GDB:尝试取消引用通用指针

如何使GDB在x/s等打印function中进行额外的解引用?

当我在x/ I中尝试显式解引用时,会出现错误“尝试取消引用通用指针”。 使用x/多次工作,因为每次使用都包含隐式解引用,但这很烦人,因为我必须复制并粘贴每个中间结果。

考虑非常有用的C程序, example.c

 #include  int main(int argc, char **argv) { printf("argv[0] = %s\n", argv[0]); } 

如果我构建它并将其加载到GDB中,我看到argv存储在0xc(%ebp) ,因为它的双重因素作为第二个参数传递给第24行的printf (即0x4(%esp) ):

 $ gcc -o example example.c $ gdb example (gdb) disass main Dump of assembler code for function main: 0x080483e4 : push %ebp 0x080483e5 : mov %esp,%ebp 0x080483e7 : and $0xfffffff0,%esp 0x080483ea : sub $0x10,%esp 0x080483ed : mov 0xc(%ebp),%eax 0x080483f0 : mov (%eax),%edx 0x080483f2 : mov $0x80484e0,%eax 0x080483f7 : mov %edx,0x4(%esp) 0x080483fb : mov %eax,(%esp) 0x080483fe : call 0x8048300  0x08048403 : leave 0x08048404 : ret End of assembler dump. 

我打破printf并使用参数firstsecond运行程序:

 (gdb) break *main + 26 Breakpoint 1 at 0x80483fe (gdb) run first second Starting program: /var/tmp/SO-attempt-to-dereference-generic-pointer/example first second 

我尝试在GDB中打印argv[0] ,但是我得到了“通用指针”错误:

 Breakpoint 1, 0x080483e5 in main () (gdb) x/s **(0xc + $ebp) Attempt to dereference a generic pointer. 

但是,通过使用’x / xw’手动取消引用几次,我最终能够打印argv[0] (和argv[1] ):

 (gdb) x/xw 0xc + $ebp 0xbfffeba4: 0xbfffec34 (gdb) x/xw 0xbfffec34 0xbfffec34: 0xbfffedc8 (gdb) x/s 0xbfffedc8 0xbfffedc8: "/var/tmp/SO-attempt-to-dereference-generic-pointer/example" (gdb) x/xw 0xbfffec34 + 4 0xbfffec38: 0xbfffee03 (gdb) x/s 0xbfffee03 0xbfffee03: "first" (gdb) 

但这是烦人的和间接的(因为指针编程不会是?)

解决方案是在解除引用之前强制转换指针。

例如,从我们上面的位置开始:

 (gdb) x/s **((char ***) (0xc + $ebp)) 0xbfffedc8: "/var/tmp/SO-attempt-to-dereference-generic-pointer/example" (gdb) x/s *(*((char ***) (0xc + $ebp)) + 1) 0xbfffee03: "first" (gdb) x/s *(*((char ***) (0xc + $ebp)) + 2) 0xbfffee09: "second" 

请注意,堆栈地址0xc + $ebp本身是指向该堆栈位置内容的指针,因此我们需要char ***而不是char **