2012-02-01 1 views
43

코드베이스에서 컴파일되지 않은 함수를 찾고 싶습니다. 컴파일 단위를 포함하여. 내 컴파일러로 gcc를 사용하고있다.사용하지 않는 기능에 대해 경고를받을 수있는 방법이 있습니까?

foo.c (적절한 foo.h 가정) :

void foo() { 
    .... 
} 

void bar() { 
    .... 
} 

main.c : 여기

이 예제이 예제에서는

#include <stdio.h> 
#include "foo.h" 

int main(void) { 
    bar(); 
    return 0; 
} 

, 나는 약 foo()이 없다는 경고를 좀하고 싶습니다 익숙한.

-Wunused-function GCC 옵션이 있습니다 : 정적 함수를 선언하지만 정의 또는 인라인이 아닌 정적 기능이 사용되지 때마다

-Wunused-function

이 경고. 이 경고는 -Wall에 의해 활성화 된 입니다.

정적 기능에만 해당되며 위의 예에서는 경고가 표시되지 않습니다.

가능한 경우 gcc을 계속 사용하고 싶지만 도구/스크립트/다른 컴파일러 제안을 수락합니다.

+6

기본적으로 사용되지 않는 비 정적 기능에 대해서는 경고하지 않는 것이 좋습니다. 비 정적 함수는 공용 인터페이스의 일부입니다. gcc에서 생성 한 .o 파일을 링커를 통해 쉽게 제공하여 .a 또는 .so 라이브러리를 생성 할 수 있기 때문에 모든 비 정적 함수가 링크 도서관과. 그렇다고해도 여전히 유용한 질문입니다. 유용한 답변을 원합니다. –

+3

물론 기본적으로 켜져 있으면 안됩니다. 아직도, 나는 특징이 존재하는 경우에 마지막 연결 시간에 그것을 가능하게하고 싶으면 :) –

+1

관련 http : //gcc.gnu.org/ml/gcc-help/2003-08/msg00072.html? –

답변

41

Caolan Mc Namara, LibreOffice 개발자는 LibreOffice 소스 코드에서 이러한 유형의 것을 탐지하는 작은 도구를 만들었다. 그들은 LibreOffice에서 수천 가지 함수 & 메서드를 사용하지 않았습니다. 그의 도구는 그들을 제거하기위한 핵심 요소입니다.

callcatcher이라고합니다. 그것은

함수/메소드를 정의/호출 그것은 어셈블러 출력을 직접 작동 그래서, 그것은 단지 x86 및 x86_64의 아키텍처 작동

를 참조 빼기 수집 할 수 있습니다. this과 같은 출력을 생성 할 수 있습니다. gcc에 대한 기존의 컴파일 링 및 호출과 통합 할 수 있습니다.

Caolan은 gcc 플러그인이되어야한다는 데 동의합니다.

+0

이것은 내가 원하는 것 그대로이다. 고맙습니다! –

+4

그것은 훌륭합니다. 엔터테인먼트 가치를 위해, 내가 일하고있는 프로젝트에는 ** 1257 개의 사용하지 않는 기능 **이 있습니다. 나는이 코드베이스에 몇 가지 이상이있을 것이라는 인상을 받았다. –

3

먼저, 이러한 경고를 프로그램 전체에 적용하려면 -flto 플래그가 필요합니다. 각 개별 단위를 컴파일 할 때가 아니라 링크 할 때 해결해야하므로 확실하게 플래그가 필요합니다. 그러나 나는 GCC가 이런 식으로 경고를한다고 생각하지 않는다.

그런 다음 일반적인 경우에는 제공하는 것이 현명하지 않을 것입니다 (예 : 연결된 libc에는 응용 프로그램에 필요하지 않은 많은 기능이 포함되어있을 수 있음). 또한, 분명히 지껄 기능에 도달 dlsym 트릭을 사용할 수있는 응용 프로그램 ... 그러나

, 그것은 어딘가에 각 통화의 발생을 등록 할 것 GCC 플러그인 또는 MELT 확장에 대한 잠재적 인 사용 사례의 좋은 예로,이다 이후의 유틸리티는 호출되지 않은 모든 함수를 찾습니다. (그러나 GCC 용 플러그인 또는 MELT 확장 코드는 최소한 GCC 내부를 이해해야하기 때문에 며칠이 걸릴 것입니다.)

프로파일 링 기법을 사용하여 동적으로 사용되지 않는 (호출되지 않은) 함수를 얻을 수도 있습니다.

전자 메일로 더 많은 질문을 주시기 바랍니다.

+1

+1 감사합니다. GCC 플러그인 경로를 끝내면 거의 확실하게 이메일을 보냅니다 :) –

+0

나는 MELT 확장 기능을 C의 GCC 플러그인보다 더 잘 사용할 수 있습니다. –

+0

@BasileStarynkevitch : 아마도 당신입니다. Caolan Mc Namara가 이것에 대해 무엇을했는지 보길 바랍니다. 자세한 내용은 내 대답을 참조하십시오. – Coren

3

경고를 요청했으며 gcc 옵션을 사용하지 않는 것을 선호하지만 실제로는 쉽습니다.

응용 프로그램에서 데드 코드를 제거하기 위해 링커 최적화 (--gc-sections)를 사용할 수 있습니다. GCC의 man 페이지에서

:

--gc 섹션은 --no-GC-섹션 사용하지 않는 입력 섹션의 가비지 컬렉션을 사용합니다.이 옵션을 지원하지 않는 대상에서는 무시됩니다. 이 가비지 콜렉션을 수행하지 않는 기본 동작은 명령 행에 --no-gc-sections을 지정하여 복원 할 수 있습니다.

--gc- 섹션은 기호 및 재배치를 검사하여 어떤 입력 섹션이 사용되는지 결정합니다. 입력 심볼을 포함하는 섹션과 명령 행에서 정의되지 않은 심볼을 포함하는 모든 섹션은 동적 객체가 참조하는 심볼을 포함하는 섹션과 마찬가지로 유지됩니다. 공유 라이브러리를 만들 때 링커는 보이는 심볼이 참조 된 것으로 간주해야합니다. 이 섹션의 초기 집합이 결정되면 링커는 해당 재배치에서 참조하는 섹션을 사용하여 재귀 적으로 표시합니다. -entry 및 --undefined를 참조하십시오.

이 옵션은 부분 링크를 수행 할 때 설정할 수 있습니다 (옵션 -r을 사용하여 사용 가능). 이 경우 보관 된 기호의 루트는 --entry 또는 --undefined 옵션이나 링커 스크립트의 "ENTRY"명령에 의해 명시 적으로 지정되어야합니다.

+3

슬프게도 바이너리에서 코드를 제거하지 않을 것입니다. 소스의 어느 부분을 정리할 수 있는지 알고 싶습니다. –

+5

올바르게 기억하면 자세한 정보가있는 자세한 옵션이 있습니다. gc-sections에 의해 수행되었습니다. 나는 그것이 "--print-gc-sections"라고 생각한다. – eyalm

1

Eclipse CDT에는 사용되지 않는 정적 함수 및 사용되지 않는 함수 선언 (다른 유용한 것들 중 하나)을 표시하도록 설정할 수있는 코드 분석 기능이 있습니다. 이미 말했듯이 링커 만 특정 바이너리에서 특정 (비 정적) 함수가 사용되지 않았다는 것을 알 수 있습니다 ...

1

gprof은 내가 생각하기에 가장 간단한 해결책입니다. -pg 옵션을 사용하여 a.out (나중에 gprof를 사용할 수 있음)을 실행할 때 gmon.out을 얻은 다음 gprof -z a.out gmon.out | tee output.txt을 마침내 실행 한 샘플 프로그램을 컴파일했습니다. 사용하지 않은 목록에 귀하의 기능을 찾을 수 있습니다 foo! 즉 0 번이라고합니다. -z은 사용하지 않는 루틴을 추적하려면 gprof과 함께 사용해야하는 옵션입니다.

적절한 포인터에 대한 this 스레드 덕분에!

PS : gprof은 사용되지 않는 함수 foo과 함께 사용되지 않은 다른 라이브러리 함수를 던져 버렸습니다. 나는 심각하게 필터하는 방법을 모른다 :