GDB strace montre qu’il essaye de faire de la trace à une adresse invalide

J’ai rencontré une telle erreur lors de l’exécution de la commande ni lors du débogage de gdb:

Attention:
Impossible d’insérer le point d’arrêt 0.
Erreur lors de l’access à l’adresse de mémoire 0x3ac706a: erreur d’entrée / sortie.

0xf6fa4771 dans siglongjmp () de /lib/libc.so.6

Pour étudier quel problème rencontre gdb avec strace gdb et obtenir une telle sortie:

rt_sigprocmask (SIG_BLOCK, NULL, [RT_1], 8) = 0
ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fdf60, [0x1cc4fe470]) = 0
ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0
rt_sigprocmask (SIG_BLOCK, NULL, [RT_1], 8) = 0


rt_sigprocmask (SIG_BLOCK, NULL, [RT_1], 8) = 0
rt_sigprocmask (SIG_BLOCK, NULL, [RT_1], 8) = 0
ptrace (PTRACE_GETREGS, 27781, 0, 0x7fff8990e8b0) = 0
ptrace (PTRACE_PEEKTEXT, 27781, 0x3ac7068, [0x28b]) = -1 EIO (erreur d’entrée / sortie)
ptrace (PTRACE_PEEKTEXT, 27781, 0x3ac7068, [0x28b]) = -1 EIO (erreur d’entrée / sortie)

Cela implique que gdb ptrace d’abord à l’adresse de mémoire 0xcc4fe480 et obtient la valeur 0x3ac706a4506fa1d (en fait une valeur de 8 octets 0x03ac706a4506fa1d ). Plus tard, il obtient une adresse alignée 0x3ac7068 à partir des 4 premiers octets de cette valeur, qui est une adresse non valide et provoque l’échec de gdb.

Contenu de / proc / [pid] / maps:

cbce2000-cc353000 r-xp 00000000 08:03 295479 xxx.so
cc353000-cc3f0000 r – p 00670000 08:03 295479 xxx.so
cc3f0000-cc3f6000 rw-p 0070d000 08:03 295479 xxx.so
cc3f6000-cc3fe000 rw-p cc3f6000 00:00 0
cc3fe000-cc3ff000 — p cc3fe000 00:00 0
cc3ff000-cc4ff000 rwxp cc3ff000 00:00 0
cc4ff000-cc500000 — p cc4ff000 00:00 0

cc500000-cc600000 rwxp cc500000 00:00 0
cc62d000-cc673000 r-xp 00000000 08:03 295545 yyy.so
cc673000-cc674000 — p 00046000 08:03 295545 yyy.so
cc674000-cc675000 r – p 00046000 08:03 295545 yyy.so
cc675000-cc676000 rw-p 00047000 08:03 295545 yyy.so

Il montre que l’adresse 0xcc4fe480 provient de la section avec une police en gras ci-dessus. Cette section n’est liée à aucun fichier .so ou bin.

Cette question est en fait liée à une autre question http://stackoverflow.com/questions/9564417/gdb-cant-insert-internal-breakpoint , qui n’a pas encore été résolue. J’ai trouvé ces problèmes lors de l’enquête sur le numéro précédent.

J’ai 3 questions ici:
1. Regardez la sortie de strace pour ptrace ici:
ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0
Pourquoi le dernier paramètre est-il annoté par des crochets? Est-ce que cela signifie qu’il représente la valeur de retour? La page de manuel indique que ptrace devrait renvoyer le mot lu pour PTRACE_PEEKTEXT, mais il semble que la sortie de strace ne suive pas cela, donc je soupçonne qu’elle affiche la valeur de retour dans le dernier paramètre.
2. Il y a une section (avec une police en gras) entre deux .so mais non associée à aucun inode. Que représente une telle section?
3. Gdb lit un mot de cette section et utilise ce mot comme adresse, mais en réalité, il s’agit d’une adresse non valide. Quelles sont les causes possibles d’une telle erreur?

Merci!

  1. Jetez un coup d’oeil à la sortie de strace pour ptrace ici: ptrace (PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0 Pourquoi le dernier paramètre est-il annoté par des crochets? Est-ce que cela signifie qu’il représente la valeur de retour?

Correct.

  1. Il y a une section (avec une police en gras) entre deux .so mais non associée à aucun inode. Que représente une telle section?

C’est une région de la mémoire qui a été mmap ed avec l’indicateur MAP_ANONYMOUNS (c.-à-d. MAP_ANONYMOUNS ne correspond à aucun fichier sur le disque).

Étant donné que la taille de cette région est exactement de 1 Mo et qu’elle est entourée de régions privées mappées avec PROT_NONE , il est fort à parier que cette région représente une stack de threads, entourée de zones de garde de stack.

  1. Gdb lit un mot de cette section et utilise ce mot comme adresse, mais en réalité, il s’agit d’une adresse non valide. Quelles sont les causes possibles d’une telle erreur?

Pour une raison quelconque, GDB estime qu’il devrait y avoir du code à l’adresse 0x3ac7068 et souhaite y placer un point d’arrêt interne . GDB utilise des points d’arrêt internes pour assurer le suivi des bibliothèques partagées chargées (entre autres).

La sortie des maintenance info break de maintenance info break devrait révéler le code qui, selon GDB, réside à la “mauvaise” adresse.

Je suppose que votre code déborde et écrit sur une adresse valide et que gdb accède à cette zone de mémoire en attendant une adresse mais des données indésirables. Quelle est la section de code que vous essayez de déboguer? Cela pourrait nous aider.