2010-03-29 3 views
10

Nous exécutons le linux uclibc sur ARM 9. Le problème est que uclibc ne supporte pas backtrace. Lorsqu'un vidage de mémoire se produit, je ne peux pas saisir la pile d'appels.Tout portage disponible de backtrace pour uclibc?

Quelqu'un at-il une bonne solution pour cela? Par exemple, un portage de backtrace existant pour uclibc, ou n'importe quelle bonne méthode pour récupérer la pile d'appels quand un core dump survient (uclibc + ARM + Linux)?

Répondre

5

Mise à jour:

Il semble qu'un patch a été créé pour soutenir backtrace() sur uclibc pour x86 et ARM (XScale) et il utilise le symbole __libc_stack_end.


Réponse d'origine:

je travaillais sur un projet où la version de glibc que nous utilisions n'a pas fourni une backtrace() fonctionnelle pour notre processeur ARM, nous avons donc développé notre propre en dehors de glibc en utilisant la __libc_stack_end symbole. Voici le code résultant. Peut-être que vous pouvez l'utiliser pour écrire une fonction uclibc backtrace().

extern void * __libc_stack_end; 

struct backtrace_frame_t 
{ 
    void * fp; 
    void * sp; 
    void * lr; 
    void * pc; 
}; 

int backtrace(void ** array, int size) 
{ 
    void * top_frame_p; 
    void * current_frame_p; 
    struct backtrace_frame_t * frame_p; 
    int frame_count; 

    top_frame_p = __builtin_frame_address(0); 
    current_frame_p = top_frame_p; 
    frame_p = (struct backtrace_frame_t*)((void**)(current_frame_p)-3); 
    frame_count = 0; 

    if (__builtin_return_address(0) != frame_p->lr) 
    { 
     fprintf(stderr, "backtrace error: __builtin_return_address(0) != frame_p->lr\n"); 
     return frame_count; 
    } 

    if (current_frame_p != NULL 
     && current_frame_p > (void*)&frame_count 
     && current_frame_p < __libc_stack_end) 
    { 
     while (frame_count < size 
       && current_frame_p != NULL 
       && current_frame_p > (void*)&frame_count 
       && current_frame_p < __libc_stack_end) 
     { 
      frame_p = (struct backtrace_frame_t*)((void**)(current_frame_p)-3); 
      array[frame_count] = frame_p->lr; 
      frame_count++; 
      current_frame_p = frame_p->fp; 
     } 
    } 

    return frame_count; 
} 

Note: Le symbole __libc_stack_end est pas plus exporté dans les versions les plus récentes de glibc et je ne suis pas sûr de l'existence de celui-ci ou un symbole similaire dans uclibc.

+0

du code ci-dessus je reçois erreur d'exécution « erreur Backtrace : __builtin_return_address (0)! = frame_p-> lr ". comment résoudre cette condition. – Mandar

+0

La convention d'appel ARM standard ([lien pdf] (http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf)) attribue r14 comme registre de liaison. L'instruction BL, utilisée dans un appel de sous-programme, stocke l'adresse de retour dans ce registre. Les fonctions '__builtin_frame_address (0)' et '__builtin_return_address (0)' sont utilisées pour [obtenir l'adresse de retour et l'image de la fonction d'appel] (http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html). Votre erreur indique que le registre de liens ne contient pas l'adresse de retour ou que la structure 'backtrace_frame_t' ne correspond pas à votre cadre de pile. – jschmier