2010-07-09 2 views
2

C'est un code unique.Comment puis-je déboguer le code de segfaults à moins d'exécuter gdb?

En particulier: module d'extension ahocorasick Python (easy_install ahocorasick).

J'isolé le problème à un exemple trivial:

import ahocorasick 
t = ahocorasick.KeywordTree() 
t.add("a") 

Quand je lance dans gdb, tout va bien, de même lorsque j'entre ces instructions en Python CLI. Cependant, lorsque j'essaie de lancer le script régulièrement, j'obtiens un segfault. Pour le rendre encore plus bizarre, la ligne qui provoque la segfault (identifiée par l'analyse de vidage du noyau) est une incrémentation int régulière (voir le bas du corps de la fonction).

Je suis complètement bloqué par ce moment, que puis-je faire?

int 
aho_corasick_addstring(aho_corasick_t *in, unsigned char *string, size_t n) 
{ 
    aho_corasick_t* g = in; 
    aho_corasick_state_t *state,*s = NULL; 
    int j = 0; 

    state = g->zerostate; 

    // As long as we have transitions follow them 
    while(j != n && 
      (s = aho_corasick_goto_get(state,*(string+j))) != FAIL) 
    { 
     state = s; 
     ++j; 
    } 

    if (j == n) { 
     /* dyoo: added so that if a keyword ends up in a prefix 
      of another, we still mark that as a match.*/ 
     aho_corasick_output(s) = j; 
     return 0; 
    } 

    while(j != n) 
    { 
     // Create new state 
     if ((s = xalloc(sizeof(aho_corasick_state_t))) == NULL) 
      return -1; 
     s->id = g->newstate++; 
     debug(printf("allocating state %d\n", s->id)); /* debug */ 
     s->depth = state->depth + 1; 

     /* FIXME: check the error return value of 
      aho_corasick_goto_initialize. */ 
     aho_corasick_goto_initialize(s); 

     // Create transition 
     aho_corasick_goto_set(state,*(string+j), s); 
     debug(printf("%u -> %c -> %u\n",state->id,*(string+j),s->id)); 
     state = s; 
     aho_corasick_output(s) = 0; 
     aho_corasick_fail(s) = NULL; 
     ++j;         // <--- HERE! 
    } 

    aho_corasick_output(s) = n; 

    return 0; 
} 
+0

Essayez de mettre en commentaire les lignes de débogage() et de l'exécuter via gdb éventuellement? J'essaierais aussi éventuellement d'utiliser des fichiers core pour étudier l'état de la machine lors d'un crash. Pourrait révéler qu'il ne plante pas vraiment sur la ligne '++ j' ... – Petriborg

+0

Où est la trace de la pile? –

+0

Je rencontre un problème similaire avec un module C++ que j'écris. Si je l'exécute à partir de la ligne de commande, il se bloque, si je l'exécute via gdb, tout fonctionne bien. – David

Répondre

2

Il existe d'autres outils permettant de détecter les erreurs qui ne provoquent pas nécessairement le blocage du programme. valgrind, electric fence, purify, coverity, et lint - des outils similaires peuvent être en mesure de vous aider.

Vous pourriez avoir besoin de construire votre propre python dans certains cas pour que ce soit utilisable. En outre, pour les choses de corruption de mémoire, il y a (ou n'a pas été construit d'exetensions dans un certain temps) une possibilité de laisser python utiliser l'allocation de mémoire directe au lieu de python propre.

0

Avez-vous essayé de traduire cette boucle en boucle for? Peut-être qu'il y a un malentendu subtil avec le ++j qui disparaîtra si vous utilisez quelque chose de plus intuitif.