简体   繁体   中英

GDB: Attempt to dereference generic pointer

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 (ie 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?)

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 ** .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM