C语言 GDB:尝试取消引用通用指针
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20414699/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
GDB: Attempt to dereference generic pointer
提问by ntc2
How can I make GDB do extra dereferences in a printing function like
x/s?
我怎样才能让 GDB 在打印功能中做额外的取消引用
x/s?
When I try explicit dereferences in x/I get the error "Attempt to
dereference a generic pointer". Using x/multiple times works, since
each use includes an implicit dereference, but this is annoying since
I have to copy and paste each intermediate result.
当我在中尝试显式取消引用时,x/出现错误“尝试取消引用通用指针”。x/多次使用是有效的,因为每次使用都包含一个隐式取消引用,但这很烦人,因为我必须复制和粘贴每个中间结果。
Example
例子
Consider the very useful C program, example.c:
考虑非常有用的 C 程序example.c:
#include <stdio.h>
int main(int argc, char **argv) {
printf("argv[0] = %s\n", argv[0]);
}
If I build it and load it into GDB, I see that argvis stored at
0xc(%ebp), since a double dererence of that is passed as the second
argument to printf(i.e. in 0x4(%esp)) on line 26:
如果我构建它并将其加载到 GDB 中,我会看到它argv存储在
0xc(%ebp),因为它的双重错误作为第二个参数传递给printf(即 in 0x4(%esp))在第 26 行:
$ gcc -o example example.c
$ gdb example
(gdb) disass main
Dump of assembler code for function main:
0x080483e4 <+0>: push %ebp
0x080483e5 <+1>: mov %esp,%ebp
0x080483e7 <+3>: and (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
xfffffff0,%esp
0x080483ea <+6>: sub Breakpoint 1, 0x080483e5 in main ()
(gdb) x/s **(0xc + $ebp)
Attempt to dereference a generic pointer.
x10,%esp
0x080483ed <+9>: mov 0xc(%ebp),%eax
0x080483f0 <+12>: mov (%eax),%edx
0x080483f2 <+14>: mov (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)
x80484e0,%eax
0x080483f7 <+19>: mov %edx,0x4(%esp)
0x080483fb <+23>: mov %eax,(%esp)
0x080483fe <+26>: call 0x8048300 <printf@plt>
0x08048403 <+31>: leave
0x08048404 <+32>: ret
End of assembler dump.
I break at printfand run the program with arguments firstand
second:
我中断printf并使用参数first和
运行程序second:
(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"
I attempt to print argv[0]in GDB, but I get the "generic pointer"
error:
我尝试argv[0]在 GDB 中打印,但出现“通用指针”错误:
However, by using 'x/xw' to manually dereference a few times, I'm
eventually able to print argv[0](and argv[1]):
但是,通过使用 'x/xw' 手动取消引用几次,我最终能够打印argv[0](和argv[1]):
But this is annoying and indirect (as pointer programming is wont to be?)
但这很烦人而且是间接的(因为指针编程不会是?)
回答by ntc2
The solution is to cast the pointers before dereferencing them.
解决方案是在取消引用它们之前强制转换指针。
For example, picking up where we left off above:
例如,从上面我们离开的地方开始:
##代码##Note that the stack address 0xc + $ebpis itself a pointer to the
contents of that stack location, and so we need char ***and not
char **.
请注意,堆栈地址0xc + $ebp本身就是指向该堆栈位置内容的指针,因此我们需要char ***而不是
char **。

