2015-09-15 2 views
1

Un fichier core a été produit par une version Release du code (g ++) dont les symboles ont été supprimés.Est-il possible de déboguer un fichier core produit à l'origine par un exécutable dont les symboles ont été supprimés?

En prenant cette même version (SVN) du code, j'ai modifié les options de construction pour inclure des symboles.

Dois-je être en mesure de déboguer ce fichier core en utilisant l'exécutable que j'ai construit qui comprend des symboles? Cela ne semble pas possible, mais je veux juste m'assurer que ce n'est pas quelque chose d'autre que je fais de mal.

bash-3.2$ gdb ./MyTest.53519 -c ~/public_html/core.20375.MyTest 
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-42.el5) 
Copyright (C) 2009 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-redhat-linux-gnu". 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>... 
Reading symbols from /home/me/tmp/MyTest.53519...done. 

warning: core file may not match specified executable file. 
[New Thread 20388] 
[New Thread 20389] 
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done. 
Loaded symbols for /lib64/ld-linux-x86-64.so.2 
Core was generated by `./MyTest -np1 -p1'. 
Program terminated with signal 11, Segmentation fault. 
#0 0x00007f99c19b39e0 in ??() 
(gdb) bt 
#0 0x00007f99c19b39e0 in ??() 
#1 0x00007f99bc438650 in ??() 
#2 0x00007f99c19b58cf in ??() 
#3 0x00007f9994008880 in ??() 
#4 0x00007f99b8013080 in ??() 
#5 0x00007f99bc4386f0 in ??() 
#6 0x00007f99bc438b00 in ??() 
#7 0x00007f99bc438810 in ??() 
#8 0x00007f99c19aa489 in ??() 
+0

À mon humble avis, je crois que c'est * possible *. Peut-être très difficile, mais possible. Par exemple, le débogage peut être plus rapide en créant un exécutable avec des symboles de débogage et en utilisant cet exécutable plutôt qu'en déboguant un exécutable sans symboles. J'espère que vous êtes vraiment bon pour lire le code d'assemblage (forme lisible par l'homme) ou le code machine (les numéros d'instructions). –

+0

Avez-vous un fichier * map * qui affiche les symboles et les adresses? Vous pouvez rechercher l'adresse dans le fichier carte pour trouver le symbole ou la déclaration la plus proche. –

+2

Tout au-delà des normes C++! Soyez spécifique à votre environnement actuel! –

Répondre

2

En théorie, il convient de reproduire les symboles en reconstituant le programme. Mais il nécessite que vous ayez exactement la même version du compilateur, avec exactement les mêmes paramètres, la même version de système d'exploitation et la même version de bibliothèques, en-têtes système, etc., et le système d'exploitation n'effectue pas la randomisation [ou le débogueur comprend l'adresse brassage].

Cependant, il semble que SOMETHING manque dans cette chaîne de "If ... and ..." que j'ai énumérée ci-dessus - ce qui signifie que votre pile et son contenu ne sont pas particulièrement significatifs.

Vous voudrez peut-être faire x/1000zg $rsp et voir si le contenu de la pile semble plus sain que le backtrace. Vous pouvez toujours charger votre exécutable de symbole de débogage dans une instance gdb distincte, et utiliser disass 0x124213,+123 pour désassembler ce qui est à 0x123213 (et 123 octets) dans ce processus.

En outre, en supposant que vous ne soyez pas certain à 100% des threads, essayez info thread pour voir de quoi parlent les threads.

Je ne vous envie pas ...

+2

Je pense que la chose à faire, si vous voulez distribuer des exécutables dépouillés afin que les pirates ne puissent pas tirer parti des informations de débogage (ou simplement réduire la taille du téléchargement), est de construire une fois avec les informations de débogage maximum. vous-même **, dépouiller et distribuer. Tant que vous déboguez avec le binaire complet qui correspond à celui qui est dépouillé, les choses devraient aller mieux. –

2

J'ai eu à le faire et laissez-moi vous dire que ce n'est pas facile.

La méthode que j'ai fini par utiliser ressemblait beaucoup à la vôtre. J'ai construit une copie de la bibliothèque avec toutes les mêmes options, plus des symboles de débogage.

Ensuite, j'ai regardé dans la décharge de base pour trouver l'emplacement de l'accident. J'ai utilisé la vue de démontage de gdb pour trouver les instructions de la machine et sauvegardé jusqu'à ce que j'ai trouvé la fonction démarrer.

Ensuite, je suis allé dans objdump -dC sur la bibliothèque d'origine sans symboles pour trouver l'emplacement correspondant en cherchant des séries d'instructions machine correspondantes. Cela m'a donné les compensations dans la bibliothèque.

Ensuite, j'ai été en mesure d'aller dans la bibliothèque construite avec des symboles de débogage et de trouver la même fonction. Il était généralement dans la même zone générale, bien que de petits décalages puissent se produire en raison des nombres aléatoires utilisés par le compilateur. (Note: J'ai plus tard commencé à utiliser l'option -frandom-seed de GCC pour forcer l'utilisation des nombres aléatoires SAME sur chaque exécution de compilation Lisez les docs Doit être une graine différente pour chaque fichier source.)

De là, c'était une question de lecture le démontage pour déterminer ce qui s'était mal passé. Si le core dump indique qu'il s'est écrasé à la lecture d'un pointeur NULL dans le registre $ r12, j'ai dû me souvenir de la version du symbole de débogage où $ r12 a sa valeur. Après cela, j'ai changé le système de construction plusieurs fois pour utiliser les mêmes graines aléatoires pour chaque génération et pour construire une version de symbole de débogage depuis le début, qui est dépouillée pour produire les binaires finaux. Toutes les versions sont bourrées dans un serveur SVN pour être retirées au besoin plus tard. Bien que chaque build ait des noms de répertoires uniques, un simple répertoire NFS fonctionnerait aussi bien.