2017-03-28 7 views
2

dtrace를 사용하여 함수의 로컬 변수에 어떻게 액세스합니까?Dtrace의 로컬 변수

예를 들어 다음 스 니펫에서 dtrace를 사용하여 변수 x의 값을 알고 싶습니다.

void foo(int a){ 
    int x=some_fun(a); 
} 

답변

3

임의의 커널 명령어를 계측 할 메커니즘이 없기 때문에 지역 변수 추적은 커널 코드에서 불가능합니다. 사용자 영역에서도 추적 로컬 변수는 다소 복잡하기 때문에 구체적인 예제에서는 some_fun()의 반환 값을 추적하는 것이 훨씬 더 중요합니다.

임의의 지역 변수를 추적해야하는 경우 특정 위치에서 위치 (일반적으로 레지스터 또는 메모리의 위치)를 결정해야합니다. 간단한 경우 함수를 분해하고 출력을 검사하여이 작업을 수행 할 수 있습니다. 보다 복잡한 경우에는 DWARF를 사용하여 객체를 작성한 다음 로컬 변수의 DIE의 DW_AT_location 속성을 찾는 것이 도움이 될 수 있습니다.

변수 위치를 찾으면 D로 표현해야합니다. 레지스터는 uregs[] 배열을 통해 공개됩니다. 또한 dtrace(1)에는 행 번호를 알 수 없으므로 함수 내에서 오프셋을 사용하여 프로브를 설명해야합니다. 자세한 내용은 Oracle Solaris Dynamic Tracing Guide의 "User Process Tracing"섹션을 참조하십시오. 예를 들어

, 나는 foo()를 찾기 전에 ... DWARF와 더불어, AMD64 실행으로,

cc -m64 -g -o demo demo.c 

int 
foo(int i) 
{ 
    int x; 
    ... 
    for (x = 0; x < 10; x++) 
     i += 2; 

를 포함하는 사소한 프로그램을 작성하고 내장 출력에서 x의 해당 정의는 의 dwarfdump demo :

< 1><0x000000e4> DW_TAG_subprogram 
        DW_AT_name     "foo" 
        ... 
        DW_AT_frame_base   DW_OP_reg6 



< 2><0x00000121>  DW_TAG_variable 
         DW_AT_name     "x" 
         ... 
         DW_AT_location    DW_OP_fbreg -24 
012 3,516,

x 상위 함수의 DW_AT_frame_base 특성의 결과로 치환 , 즉 DW_OP_reg6 있어야하지만 DW_OP_fbreg -24DW_OP_fbreg 자체를 설명한다. DWARF는 고유 한 아키텍처에 의존하지 않고 레지스터에 번호 매기기를 사용하고 개별 레지스터에 매핑하는 것은 적절한 표준 몸체 인 까지입니다. 이 경우 AMD64 ABI은 DWARF 레지스터 6이 %rbp에 해당한다고 에게 알립니다. 따라서 x%rbp - 0x18에 저장됩니다. (DWARF에 대한 자세한 내용 자체가 마이클 열망의 Introduction to the DWARF Debugging Format를 권장합니다.)

따라서, 당신은 (아마도 DWARF 라인 테이블을 검사하여) 당신이 관심이 이있어하는 소스의 라인에서 설정 0x32 오프셋 것을 발견 한 경우 다음과 같은 프로브 작성할 수 있습니다

pid$target:a.out:foo:32 
{ 
    self->up = (uintptr_t)(uregs[R_RBP] - 0x18); 
    self->kp = (int *)copyin(self->up, sizeof (int)); 
    printf("x = %d\n", *self->kp); 
    self->up = 0; 
    self->kp = 0; 
} 

를이 내가 데모 프로그램을 실행할 때 내가 볼 것입니다 :

# dtrace -q -s test.d -c /tmp/demo 
x = 1 
x = 2 
x = 3 
x = 4 
x = 5 
x = 6 
x = 7 
x = 8 
x = 9 
x = 10 

# 
+0

내가 벤처 줄을이 소스 코드에 DTrace 프로브를 추가하는 많은 쉽게, pos 인 경우 시 블. http://www.ibm.com/developerworks/aix/library/au-dtraceprobes.html 및 https://blogs.oracle을 참조하십시오.com/d/entry/adding_dtrace_probes_to_user –