2009-09-22 1 views
4

Как просмотреть стек вызовов, возвращаемое значение и аргументы просто программы ниже, с DTraceКак просмотреть стек вызовов с DTrace

/** Trival code **/ 

#include <stdio.h> 

int 
foo (int *a, int *b) 
{ 
    *a = *b; 
    *b = 4; 
    return 0; 
} 

int 
main (void) 
{ 
    int a, b; 
    a = 1; 
    b = 2; 
    foo (&a, &b); 
    printf ("Value a: %d, Value b: %d\n", a, b); 
    return 0; 
} 

ответ

12

Во-первых, вот сценарий:

pid$target::foo:entry 
{ 
    ustack(); 

    self->arg0 = arg0; 
    self->arg1 = arg1; 

    printf("arg0 = 0x%x\n", self->arg0); 
    printf("*arg0 = %d\n", *(int *)copyin(self->arg0, 4)); 

    printf("arg1 = 0x%x\n", self->arg1); 
    printf("*arg1 = %d\n", *(int *)copyin(self->arg1, 4)); 
} 

pid$target::foo:return 
{ 
    ustack(); 
    printf("arg0 = 0x%x\n", self->arg0); 
    printf("*arg0 = %d\n", *(int *)copyin(self->arg0, 4)); 

    printf("arg1 = 0x%x\n", self->arg1); 
    printf("*arg1 = %d\n", *(int *)copyin(self->arg1, 4)); 

    printf("return = %d\n", arg1); 
} 

Как это работает. ustack() печатает стек пользовательского процесса.

В записи функции argN является аргументом Nth функции. Поскольку аргументы указатели, вам нужно использовать copyin() для копирования в фактических данных, прежде чем вы разыщите их.

Для возврата функции у вас больше нет доступа к аргументам функции. Таким образом, вы сохраняете параметры для последующего использования.

Наконец, для возврата функции вы можете получить доступ к значению, возвращаемому функцией, с помощью arg1.

+1

Фактически, чтение аргументов при входе может привести к ошибкам, поскольку адрес памяти, возможно, еще не был выгружен. https://docs.oracle.com/cd/E18752_01/html/819-5488/gcgkk.html#gcgkr – hmijail