Comment mapper une adresse de pointeur d'instruction segfault à partir de / var / log / messages sur une adresse / fonction de mon fichier .map?

StackOverflow https://stackoverflow.com/questions/1408788

  •  05-07-2019
  •  | 
  •  

Question

(Mon environnement est Ubuntu 64 bits, mon application est compilée C ++ et liée à g ++.)

Lorsqu'une application effectue quelque chose comme diviser par zéro ou exécuter un asm (" int $ 3 ") dans le code, l'un des éléments suivants est consigné par / var via syslog. /log/kern.log et / var / log / messages :

Sep 10 18:06:47 VM kernel: [117194.123452] a.out[20288] trap divide error ip:45c59d sp:7fff65a91810 error:0 in a.out[400000+144000]
Sep 10 18:07:10 VM kernel: [117217.020833] a.out[20294] trap int3 ip:45c493 sp:7fff5cc559f0 error:0

Dans ces deux cas, l'adresse du pointeur d'instruction pointe sur quelque chose que je peux facilement rechercher dans le fichier .map généré au moment du lien (à l'aide de l'option " -Wl, -Map , output.map ").

Mais si je provoque une erreur de segmentation, dans ce cas, par un appel à memcpy () avec la source définie sur NULL, le pointeur d'instruction est tellement hors de portée que je ne sais pas comment est censé être mappé:

Sep 10 18:06:13 VM kernel: [117160.228587] a.out[20282]: segfault at 0 ip 00007f7e79209092 sp 00007fff831faf08 error 4 in libc-2.9.so[7f7e79185000+168000]

Dans cet exemple, j'aurais pensé que l'adresse IP se situerait dans la plage de 0x445e70-0x445e7f, qui correspond à l'emplacement de memcpy () d'après mon fichier .map.

Ma question: quelle est l'astuce pour interpréter l'adresse IP dans ce cas?

Était-ce utile?

La solution

Selon le message, il semble qu'il se soit écrasé dans memcpy () , à partir de libc-2.9.so , qui est mappé dans votre processus à partir de 0x7f7e79185000. Cela est attendu puisque memcpy est la fonction qui tente de déréférencer le pointeur. Le pointeur d'instruction semble valide puisqu'il se situe dans la plage de libc. Si vous vouliez remplacer memcpy et appeler votre propre version, vous devrez peut-être compiler avec -fno-builtin-memcpy .

Modifier: Vous pouvez relier libc statiquement, mais selon le message, la bibliothèque partagée libc est également mappée dans la mémoire de votre processus. Vous devriez le voir répertorié dans / proc / pid / maps pendant l'exécution de votre programme. Il se peut que vous vous connectiez à une autre bibliothèque partagée, telle que libstdc ++, et que cela dépende de la bibliothèque partagée libc. Par conséquent, vous avez deux versions de memcpy et, dans ce cas, il appelle la version de la bibliothèque partagée libc qui est mappée à l'adresse haute. Si vous ne souhaitez pas utiliser la bibliothèque partagée libc, assurez-vous de relier toutes toutes les bibliothèques de manière statique; utilisez l'option -static au début de votre ligne de lien.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top