web-dev-qa-db-fra.com

Interprétation des messages de segfault

Quelle est la bonne interprétation des messages de segfault suivants?

segfault at 10 ip 00007f9bebcca90d sp 00007fffb62705f0 error 4 in libQtWebKit.so.4.5.2[7f9beb83a000+f6f000]
segfault at 10 ip 00007fa44d78890d sp 00007fff43f6b720 error 4 in libQtWebKit.so.4.5.2[7fa44d2f8000+f6f000]
segfault at 11 ip 00007f2b0022acee sp 00007fff368ea610 error 4 in libQtWebKit.so.4.5.2[7f2aff9f7000+f6f000]
segfault at 11 ip 00007f24b21adcee sp 00007fff7379ded0 error 4 in libQtWebKit.so.4.5.2[7f24b197a000+f6f000]
53
knorv

Ceci est une erreur de segmentation due au fait de suivre un pointeur null en essayant de trouver le code à exécuter (c'est-à-dire lors de l'extraction d'une instruction).

S'il s'agissait d'un programme et non d'une bibliothèque partagée

Courir addr2line -e yourSegfaultingProgram 00007f9bebcca90d (et répétez l'opération pour les autres valeurs de pointeur d'instruction données) pour voir où l'erreur se produit. Mieux, obtenez une version avec instrument de débogage et reproduisez le problème sous un débogueur tel que gdb.

Comme c'est une bibliothèque partagée

Vous êtes arrosé, malheureusement; il n'est pas possible de savoir où les bibliothèques ont été placées en mémoire par l'éditeur de liens dynamique après coup. Reproduisez le problème sous gdb.

Que signifie l'erreur

Voici la répartition des champs:

  • address (après le at) - l'emplacement en mémoire auquel le code tente d'accéder (il est probable que 10 et 11 sont des décalages par rapport à un pointeur que nous nous attendons à définir sur une valeur valide, mais qui pointe plutôt sur 0)
  • ip - pointeur d'instruction, ie. où le code qui essaie de faire cela vit
  • sp - pointeur de pile
  • error - Un code d'erreur pour les fautes de page; voir ci-dessous ce que cela signifie sur x86.

    /*
     * Page fault error code bits:
     *
     *   bit 0 ==    0: no page found       1: protection fault
     *   bit 1 ==    0: read access         1: write access
     *   bit 2 ==    0: kernel-mode access  1: user-mode access
     *   bit 3 ==                           1: use of reserved bit detected
     *   bit 4 ==                           1: fault was an instruction fetch
     */
    
85
Charles Duffy

L'erreur 4 signifie "La cause était une lecture en mode utilisateur, aucune page n'a été trouvée". Il y a un outil qui le décode ici .

Voici la définition du noyau. Gardez à l'esprit que 4 signifie que le bit 2 est défini et qu'aucun autre n'est défini. Si vous le convertissez en binaire, cela devient clair.

/*
 * Page fault error code bits
 *      bit 0 == 0 means no page found, 1 means protection fault
 *      bit 1 == 0 means read, 1 means write
 *      bit 2 == 0 means kernel, 1 means user-mode
 *      bit 3 == 1 means use of reserved bit detected
 *      bit 4 == 1 means fault was an instruction fetch
 */
#define PF_PROT         (1<<0)
#define PF_WRITE        (1<<1)
#define PF_USER         (1<<2)
#define PF_RSVD         (1<<3)
#define PF_INSTR        (1<<4)

Maintenant, "ip 00007f9bebcca90d" signifie que le pointeur d'instruction était à 0x00007f9bebcca90d lorsque le segfault s'est produit.

"libQtWebKit.so.4.5.2 [7f9beb83a000 + f6f000]" vous dit:

  • L'objet dans lequel se trouvait le crash: "libQtWebKit.so.4.5.2"
  • L'adresse de base de cet objet "7f9beb83a000"
  • Quelle est la taille de cet objet: "f6f000"

Si vous prenez l'adresse de base et la soustrayez de l'ip, vous obtenez le décalage dans cet objet:

0x00007f9bebcca90d - 0x7f9beb83a000 = 0x49090D

Ensuite, vous pouvez exécuter addr2line dessus:

addr2line -e /usr/lib64/qt45/lib/libQtWebKit.so.4.5.2 -fCi 0x49090D
??
??:0

Dans mon cas, la copie que j'ai installée n'est pas identique à la vôtre ou elle est supprimée.

46
Tim

Allons à la source - 2.6.32, par exemple . Le message est imprimé par la fonction show_signal_msg () dans Arch/x86/mm/fault.c si le sysctl de show_unhandled_signals est défini.

"erreur" n'est pas une erreur ni un numéro de signal, c'est un "code d'erreur de faute de page" - voir la définition de enum x86_pf_error_code.

"[7fa44d2f8000 + f6f000]" est l'adresse de début et la taille de la zone de mémoire virtuelle où l'objet incriminé était mappé au moment du blocage. La valeur de "ip" devrait correspondre à cette région. Avec cette information en main, il devrait être facile de trouver le code incriminé dans gdb.

10
sendmoreinfo