레거시 C / C ++ 프로젝트에서 데드 코드 감지
C / C ++ 코드에서 데드 코드 감지는 어떻게 하시겠습니까? 작업 할 코드 기반이 꽤 크며 최소한 10-15 %는 죽은 코드입니다. 이 영역을 식별하는 Unix 기반 도구가 있습니까? 일부 코드는 여전히 많은 전처리기를 사용하는데 자동화 된 프로세스가이를 처리 할 수 있습니까?
이를 위해 코드 커버리지 분석 도구를 사용하고 코드에서 사용되지 않는 부분을 찾을 수 있습니다.
gcc 툴체인에 널리 사용되는 도구는 그래픽 프런트 엔드 lcov ( http://ltp.sourceforge.net/coverage/lcov.php ) 와 함께 gcov 입니다.
gcc를 사용하는 경우 '--coverage'플래그로 활성화되는 gcov 지원으로 컴파일 할 수 있습니다. 그런 다음이 gcov 지원 빌드로 애플리케이션을 실행하거나 테스트 스위트를 실행합니다.
기본적으로 gcc는 컴파일 중에 일부 추가 파일을 내보내고 응용 프로그램은 실행 중에 일부 커버리지 데이터도 내 보냅니다. 이 모든 파일 (.gcdo 및 .gcda 파일)을 수집해야합니다. 여기서 자세히 설명하지는 않겠지 만, 정상적인 방식으로 커버리지 데이터를 수집하려면 두 가지 환경 변수를 설정해야합니다. GCOV_PREFIX 및 GCOV_PREFIX_STRIP ...
실행 후 모든 커버리지 데이터를 모아서 lcov 도구 모음을 통해 실행할 수 있습니다. 약간 관련이 있지만 다른 테스트 실행의 모든 커버리지 파일을 병합하는 것도 가능합니다.
어쨌든, 당신은 커버리지가 없어서 사용되지 않은 코드 조각을 지적하는 커버리지 정보를 보여주는 멋진 웹 페이지 세트로 끝납니다.
물론 코드의 일부가 어떤 상황에서도 사용되지 않는지 다시 확인해야하며 테스트가 코드베이스를 얼마나 잘 실행하는지에 따라 달라집니다. 그러나 적어도 이것은 가능한 데드 코드 후보에 대한 아이디어를 줄 것입니다.
-Wunreachable-code를 사용하여 gcc에서 컴파일하십시오.
최신 버전 일수록 더 좋은 결과를 얻을 수 있다고 생각하지만, 그들이 적극적으로 작업하고있는 것 같다는 인상이 틀릴 수도 있습니다. 이것은 흐름 분석을 수행하지만 컴파일러에 의해 파싱되지 않기 때문에 전처리기를 떠날 때 이미 죽은 "코드"에 대해 알려주지 않습니다. 또한 호출되지 않는 내 보낸 함수 또는 해당 매개 변수로 함수를 호출하지 않기 때문에 불가능한 특수 케이스 처리 코드도 감지하지 않습니다. 이에 대한 코드 커버리지가 필요합니다 (그리고 기능 테스트를 실행하지 않고 단위 테스트는. 단위 테스트가되는 가정100 % 코드 커버리지를 가지므로 애플리케이션과 관련하여 '죽은'코드 경로를 실행합니다. 그럼에도 불구하고 이러한 한계를 염두에두고 코드베이스에서 가장 완벽하게 볼 릭스 된 루틴을 찾는 쉬운 방법입니다.
이 CERT 권고에는 정적 데드 코드 감지를위한 다른 도구가 나열되어 있습니다.
접근 방식은 가용성 (자동) 테스트에 따라 다릅니다. 충분한 기능을 다룰 수 있다고 신뢰하는 테스트 스위트가있는 경우 이전 답변에서 이미 제안한대로 커버리지 분석을 사용할 수 있습니다.
운이 좋지 않다면 많은 내장 분석 보고서를 사용하여 코드를 분석하는 데 도움이되는 SciTools 'Understand 와 같은 소스 코드 분석 도구를 살펴볼 수 있습니다. 이 도구에 대한 저의 경험은 2 년 전으로 거슬러 올라갑니다. 그래서 세부적으로 설명 할 수는 없지만, 버그 수정 및 질문에 대한 답변의 매우 빠른 처리 시간으로 인상적인 지원을 받았음을 기억합니다.
다른 많은 도구도 나열한 정적 소스 코드 분석 페이지를 찾았습니다 .
이것이 충분히 도움이되지 않고 전 처리기 관련 데드 코드를 찾는 데 특별히 관심이 있다면 코드에 대한 자세한 내용을 게시하는 것이 좋습니다. 예를 들어, #ifdef 설정의 다양한 조합과 주로 관련된 경우 설정 (조합)을 결정하고 실제로 빌드되지 않은 조합 등을 확인하는 스크립트를 작성할 수 있습니다.
g ++ 4.01 -Wunreachable-code는 함수 내에서 도달 할 수없는 코드에 대해 경고하지만 사용하지 않는 함수에 대해서는 경고하지 않습니다.
int foo() {
return 21; // point a
}
int bar() {
int a = 7;
return a;
a += 9; // point b
return a;
}
int main(int, char **) {
return bar();
}
g ++ 4.01은 b 지점에 대한 경고를 표시하지만이 파일에서 도달 할 수 없더라도 foo () (point a)에 대해서는 아무 말도하지 않습니다. 이 동작은 실망 스럽지만 정확합니다. 컴파일러는 foo () 함수가 다른 컴파일 단위에서 extern으로 선언되지 않고 거기에서 호출된다는 것을 알 수 없기 때문입니다. 링커 만 확신 할 수 있습니다.
C 코드의 경우에만 전체 프로젝트의 소스 코드를 사용할 수 있다고 가정하고 오픈 소스 도구 Frama-C를 사용하여 분석을 시작합니다 . GUI에서 빨간색으로 표시되는 프로그램의 모든 문장은 데드 코드입니다.
"데드 코드"문제가있는 경우 실행되지만 최종 결과에 기여하지 않는 코드 인 "예비 코드"를 제거 할 수도 있습니다. 이를 위해서는 I / O 함수의 정확한 모델링을 제공해야합니다 ( "예비"인 것처럼 보이지만의 인수로 사용되는 계산을 제거하고 싶지 않음 printf
). Frama-C에는 예비 코드를 가리키는 옵션이 있습니다.
Mozilla 와 Open Office 에는 모두 자체 개발 솔루션이 있습니다.
이와 같은 데드 코드 분석에는 전체 프로젝트에 대한 글로벌 분석이 필요합니다. 번역 단위를 개별적으로 분석하여이 정보를 얻을 수 없습니다 (글쎄요, 죽은 개체가 완전히 단일 번역 단위 내에있는 경우 감지 할 수 있지만 실제로 찾고있는 것이 아니라고 생각합니다).
우리는 DMS 소프트웨어 리엔지니어링 툴킷을 사용하여 관련된 모든 컴파일 단위를 한 번에 구문 분석하고 모든 것에 대한 기호 테이블을 구축하고 모든 참조를 추적함으로써 Java 코드에 대해이를 정확히 구현했습니다. 참조가없고 외부 API 항목이라는 주장이없는 최상위 정의는 죽었습니다. 이 도구는 또한 자동으로 데드 코드를 제거하고 마지막에 원하는 항목을 선택할 수 있습니다. 데드 엔티티 보고서 또는 해당 엔티티에서 제거 된 코드입니다.
DMS는 또한 다양한 방언 (2014 년 2 월 편집 : C ++ 14의 MS 및 GCC 버전 포함 [2017 년 11 월 편집 : 현재 C ++ 17] )의 C ++를 구문 분석 하고 필요한 모든 기호 테이블을 빌드합니다. 죽은 참조를 추적하는 것은 그 지점에서 간단합니다. DMS를 사용하여 제거 할 수도 있습니다. 참조 http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html를
Bullseye Coverage 도구가 도움이 될 것입니다. 그래도 무료가 아닙니다.
참고 URL : https://stackoverflow.com/questions/229069/dead-code-detection-in-legacy-cc-project
'Programing' 카테고리의 다른 글
Meteor를 PhoneGap과 함께 사용할 수 있습니까? (0) | 2020.11.09 |
---|---|
Valgrind : 사용하는 사소한 프로그램으로 여전히 접근 가능한 메모리 (0) | 2020.11.09 |
기록이있는 저장소 간 SVN 사본 (0) | 2020.11.09 |
그룹 별 사용과 구별 사용시 큰 성능 차이 (0) | 2020.11.09 |
Manacher의 알고리즘 (선형 시간에서 가장 긴 회문 부분 문자열을 찾는 알고리즘) (0) | 2020.11.09 |