2011-11-23 10 views
10

I como el uso del comando bt para ver el stacktrace. La salida esgdb | vea la lista de argumentos de variable

(gdb) bt 
#0 0x001ae4cd in Debugger (message=0x1 "???\a") at /SourceCache/xnu/xnu-1228.7.58/osfmk/i386/AT386/model_dep.c:705 
#1 0x3bf97000 in ??() 
#2 0x0012b0fa in panic (str=0x5ef "") at /SourceCache/xnu/xnu-1228.7.58/osfmk/kern/debug.c:274 
#3 0x001a8cd4 in kernel_trap (state=0x51a67c80) at /SourceCache/xnu/xnu-1228.7.58/osfmk/i386/trap.c:680 
#4 0x0019ede5 in return_from_trap() at pmap.h:176 
#5 0x00132bea in __doprnt (fmt=<value temporarily unavailable, due to optimizations>, argp=0x51a67e6c, putc=0x38ad24 <kvprintf+33>, arg=0x51a67e48, radix=10) at /SourceCache/xnu/xnu-1228.7.58/osfmk/kern/printf.c:439 
#6 0x0038ad11 in kvprintf (fmt=0x1 "???\a", func=0x1, arg=0x1, radix=1, ap=0x51a67e84 "\\?\034I\"") at /SourceCache/xnu/xnu-1228.7.58/bsd/kern/subr_prf.c:525 
#7 0x491b5dac in com_my_drv_Log (format=0x491cbff8 "%s::%s:%n\n") at Logger.cpp:37 
#8 0x491b3d36 in MyDrv::init (this=0x5c1f200, properties=0x58a8040) at MyDrv.cpp:34 
#9 0x00412887 in IOService::probeCandidates (this=0x599a980, matches=0x58ade80) at /SourceCache/xnu/xnu-1228.7.58/iokit/Kernel/IOService.cpp:2512 
#10 0x004124ab in IOService::doServiceMatch (this=0x534180, options=8) at /SourceCache/xnu/xnu-1228.7.58/iokit/Kernel/IOService.cpp:2921 
#11 0x00411127 in _IOConfigThread::main (self=0x58c6790) at /SourceCache/xnu/xnu-1228.7.58/iokit/Kernel/IOService.cpp:3125 
(gdb) 

En el marco

#7 0x491b5dac in com_my_drv_Log 

Cómo pude ver los parámetros pasados ​​a mi com_my_drv_Log con la firma

void com_my_drv_Log (const char* format, ...); 
/* with the variable argument list */ 

?

+0

posiblemente relevante: http://www.cocoabuilder.com/archive/cocoa/220209-gdb-of-va-alist.html – sehe

Respuesta

5

Parece que esto es posible hacerlo por un programa sencillo como esto:

#include <stdarg.h> 
#include <stdio.h> 

void myfunc(const char *fmt, ...) 
{ 
     va_list args; 
     va_start(args, fmt); 
     vprintf(fmt, args); 
     va_end(args); 
     return; 
} 

int main(int argc, char *argv[]) 
{ 
     myfunc("test 1: %s %s\n", "one", "two"); 
     myfunc("test 2: %s %d %c\n", "apple", 222, 'y'); 
     return 0; 
} 

Aquí es ejemplo de sesión GDB:

$ gdb testprog 
GNU gdb (GDB) 7.1-debian 
[snip] 
Reading symbols from /home/user/testprog...done. 
(gdb) break myfunc 
Breakpoint 1 at 0x400552: file testprog.c, line 7. 
(gdb) run 
Starting program: /home/user/testprog 

Breakpoint 1, myfunc (fmt=0x4006f4 "test 1: %s %s\n") at testprog.c:7 
7    va_start(args, fmt); 
(gdb) # initialize args to hold correct values: 
(gdb) step 
8    vprintf(fmt, args); 
(gdb) # print first argument in "..." list which we know is a char*: 
(gdb) p *(char **)(((char *)args[0].reg_save_area)+args[0].gp_offset) 
$1 = 0x4006f0 "one" 

No he probado todo esto, mira esto link para una solución completa. This blog será útil también.

+0

Gracias, me ayudó, también fue útil ver el encabezado ''. –

3
 
(gdb) frame 8 

lo pondrán en el marco de la persona que llama. Examine los argumentos que se están pasando.

+0

Creo que la pregunta se centra en las listas de argumentos variables (el infame '...') y el OP ya sabe cómo ver los argumentos en el caso general. –

+1

La manera más fácil de ver los argumentos pasados ​​a una función variadic es subir un nivel en la pila de llamadas. Es una solución simple; ¿Por qué molestarse tratando de hacerlo desde dentro de la función variadica? –

+0

bien, demasiado obvio, supongo, ni siquiera lo pensé. –

Cuestiones relacionadas