2010-03-29 12 views
10

Estamos ejecutando el uclibc linux en ARM 9. El problema es que uclibc no admite backtrace. Cuando ocurre un volcado del núcleo, no puedo tomar la pila de llamadas.¿Alguna portabilidad disponible de backtrace para uclibc?

¿Alguien tiene una buena solución para eso?

Por ejemplo, un puerto existente de backtrace para uclibc, o cualquier otro método para tomar la pila de llamadas cuando ocurre un volcado de núcleo (uclibc + ARM + Linux)?

Respuesta

5

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.

+0

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

+0

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

Cuestiones relacionadas