GDB: tentative de déréférence du pointeur générique

Comment faire en sorte que GDB fasse des déréférences supplémentaires dans une fonction d’impression comme x/s ?

Lorsque j’essaie des déréférences explicites dans x/ j’obtiens l’erreur “Tentative de déréférencer un pointeur générique”. L’utilisation de x/ multiple times fonctionne, car chaque utilisation inclut un déréférencement implicite, mais c’est ennuyeux car je dois copier et coller chaque résultat intermédiaire.

Exemple

Considérez le programme C très utile, example.c :

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

Si je le construis et le charge dans GDB, je vois que argv est stocké à 0xc(%ebp) , car une double erreur est passée comme second argument de printf (c’est-à-dire dans 0x4(%esp) ) à la ligne 26:

 $ 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 à printf et lance le programme avec les arguments first et 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 

J’essaie d’imprimer argv[0] dans GDB, mais l’erreur “Pointeur générique” est générée:

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

Cependant, en utilisant ‘x / xw’ pour déréférencer manuellement plusieurs fois, je suis finalement capable d’imprimer argv[0] (et 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) 

Mais ceci est ennuyeux et indirect

    La solution consiste à lancer les pointeurs avant de les déréférencer.

    Par exemple, reprenons là où nous en étions restés:

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

    Notez que l’adresse de la stack 0xc + $ebp est en elle-même un pointeur sur le contenu de cet emplacement de la stack. Nous avons donc besoin de char *** et non de char ** .