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.
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
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