Programing

레거시 C / C ++ 프로젝트에서 데드 코드 감지

lottogame 2020. 11. 9. 07:41
반응형

레거시 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에는 예비 코드를 가리키는 옵션이 있습니다.


MozillaOpen 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

반응형