Actualización:
parece que un patch fue creado para apoyar backtrace()
en uClibc para x86 y ARM (XScale) y hace uso del símbolo __libc_stack_end
.
respuesta original:
trabajé en un proyecto en la versión de glibc que estábamos usando no proporcionó un funcional backtrace()
para nuestro procesador ARM, por lo que hemos desarrollado nuestro propio fuera de glibc utilizando el __libc_stack_end
símbolo. A continuación está el código resultante. Quizás pueda usarlo para escribir una función 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;
}
Nota: El símbolo __libc_stack_end
ya no se exporta en las versiones más recientes de glibc y no estoy seguro de la existencia de la misma o un símbolo similar en uClibc.
en el código anterior que estoy recibiendo error de ejecución "error de traza : __builtin_return_address (0)! = frame_p-> lr ". cómo resolver esta condición – Mandar
La convención de llamada ARM estándar ([pdf link] (http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf)) asigna r14 como el registro de enlace. La instrucción BL, utilizada en una llamada de subrutina, almacena la dirección de retorno en este registro. Las funciones '__builtin_frame_address (0)' y '__builtin_return_address (0)' se utilizan para [obtener el retorno y la dirección del cuadro de la función de llamada] (http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html) Su error dice que el registro de enlace no contiene la dirección de retorno o que la estructura 'backtrace_frame_t' no coincide con su marco de pila. – jschmier