2011-08-14 3 views
7

gcov 도구의 출력을 이해하려고합니다. 선택 사항없이 실행하면 의미가 있지만 지점 적용 범위 옵션을 시도하고 이해하려고합니다. 불행히도 지점이하는 일과 이유를 이해하지 못합니다. 아래는 최신 LLVM/Clang 빌드를 사용하여 컴파일하는 메소드의 출력입니다.gcov 파일의 분기 이해

function -[TestCoverageAppDelegate loopThroughArray:] called 5 returned 100% blocks executed 88% 
     5: 30:- (NSInteger)loopThroughArray:(NSArray *)array { 
     5: 31: NSInteger i = 0; 
     22: 32: for (NSString *string in array) { 
branch 0 taken 0 
branch 1 taken 7 
     -: 33:   
     22: 34: } 
branch 0 taken 4 
branch 1 taken 3 
branch 2 taken 0 
branch 3 taken 3 
     5: 35: return i; 
     -: 36:} 

내가 전무 전달이를 통해 5 테스트를 실행 한, 하늘의 배열, 1 개 객체 배열 및 배열이 객체와 4 객체와 배열. 첫 번째 경우에 지점 1은 "루프에 들어감"을 의미하지만 분기 0이 무엇인지 실마리가 없습니다. 두 번째 경우 지점 0 다시 통해 루프 것 같다, 1 분기 루프를 끝내고 3 분기 계속됩니다/루프를 종료하지만 난 어떤 분기 2인지 또는 왜/언제 실행될 것이라고 생각하지 않습니다.

누군가가 지점 정보를 해독하는 방법을 알고 있거나 모든 내용에 대한 자세한 설명서를 알고 있다면 도움을 주시면 감사하겠습니다.

+0

함수의 어셈블리를 가져 와서'j **'명령어의 수를 확인하십시오. – osgx

+0

내 어셈블리가별로 좋지는 않지만 4가있는 것처럼 보입니다. 첫 번째는 열거 할 개체가 없으면 루프를 건너 뛸 것으로 생각되는 je입니다. 그런 다음 열거 형 돌연변이 예외를 건너 뛴 또 다른 je, jb에 대해서는 전혀 알지 못하지만 루프의 맨 위로 이동 한 다음 열거 할 객체가있는 경우 루프의 맨 위로 이동한다고 생각하는 jne입니다. 흥미롭게도, 돌연변이는 첫 번째 브랜치 0이 취하게하여 하나의 신비를 해결하지만 브랜치 2는 여전히 나를 피합니다 –

+0

흠 .. 다른 가능한 경우는 -pg (gcov 실행 용)로 컴파일 된 오브젝트 파일을 디스 어셈블하는 것입니다. 당신은 "__llvm_gcov_ctr"increment 또는 "__llvm_gcda_edge"호출과 같은 분해와 같은 분해에서 일부 gcov 계측 함수에 대한 호출을보아야합니다. 또한'-fno-inline'으로'O0'에서 컴파일 했습니까? – osgx

답변

3

Gcov는 모든 기본 명령 블록 (어셈블러에 대해 생각할 수 있음)을 계측 (컴파일하는 동안)하여 작동합니다. Basic block은 내부에 가지가없고 그 안에 lables가없는 코드의 선형 섹션을 의미합니다. 따라서 기본 블록을 실행하기 시작한 경우에만 기본 블록의 끝까지 도달하게됩니다. 기본 블록은 CFG (제어 흐름 그래프, 방향 그래프로 생각)에서 구성되며 기본 블록 간의 관계 (V1에서 V2 로의 가장자리는 V1 호출은 V2, V2는 V1에 의해 호출 됨)를 보여줍니다. 따라서 profile-arcs 컴파일러와 gcov 모드는 모든 라인에 대해 실행 횟수를 얻고 싶고 기본 블록 실행 횟수를 계산하여 수행합니다. 그래프의 기본 블록 사이에 대수 관계가 있기 때문에 CFG의 가장자리 중 일부는 계측되고 일부는 계측되지 않습니다.

ObjC 구성 (for..in)이 낮춰지고 (초기 컴파일에서 변환 된) 몇 가지 기본 블록으로 변환됩니다. 그래서 gcov는 4 개의 브랜치를 봅니다. 이 낮추기에 대해서는 아무것도 알지 못하지만 모든 어셈블러 명령어 (이것은 디버그 정보 임)에 해당하는 라인을 알고 있습니다. 따라서 분기는 CFG의 가장자리입니다.

기본 블록을 보려면 컴파일 된 프로그램의 어셈블러 덤프를 수행하거나 컴파일러에서 CFG를 덤프하거나 바이너리를 분해해야합니다. profile-arcs 모드와 profile-arcs 모드를 모두 비교하여 비교할 수 있습니다.

profile-arcs 모드에는 "__llvm_gcov_ctr"또는 "__llvm_gcda_edge"와 같이 많은 호출과 증분이 있습니다.이 블록은 기본 블록의 실제 계기입니다.