GDB: Attempt to dereference generic pointer

assembly, c, debugging, gdb

Solution

The solution is to cast the pointers before dereferencing them.

For example, picking up where we left off above:

(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"

Note that the stack address `0xc + $ebp` is itself a pointer to the contents of that stack location, and so we need `char ***` and not `char **`.

Problem

How can I make GDB do extra dereferences in a printing function like `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. Example Consider the very useful C program, `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 `argv` is 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: ``` $ 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 $0xfffffff0,%esp 0x080483ea <+6>: sub $0x10,%esp 0x080483ed <+9>: mov 0xc(%ebp),%eax 0x080483f0 <+12>: mov (%eax),%edx 0x080483f2 <+14>: mov $0x80484e0,%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 `printf` and run the program with arguments `first` and `second`: ``` (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 ``` I attempt to print `argv[0]` in GDB, but I get the "generic pointer" error: ``` Breakpoint 1, 0x080483e5 in main () (gdb) x/s **(0xc + $ebp) Attempt to dereference a generic pointer. ``` However, by using 'x/xw' to manually dereference a few times, I'm eventually able to print `argv[0]` (and `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) ``` But this is annoying and indirect (as pointer programming is wont to be?)

Original source