2010-03-29 22 views
10

Chúng tôi đang chạy Linux uclibc trên ARM 9. Vấn đề là uclibc không hỗ trợ backtrace. Khi một kết xuất lõi xảy ra, tôi không thể lấy chồng cuộc gọi.Bất kỳ cổng nào có sẵn của backtrace cho uclibc?

Có ai có giải pháp tốt cho điều đó không?

Ví dụ: một cổng quay ngược hiện tại cho uclibc hoặc bất kỳ phương pháp tốt nào để lấy ngăn xếp cuộc gọi khi xảy ra lỗi lõi (uclibc + ARM + Linux)?

Trả lời

5

Cập nhật:

Dường như một patch được tạo ra để hỗ trợ backtrace() trên uclibc cho x86 và ARM (XScale) và nó làm cho việc sử dụng biểu tượng __libc_stack_end.


gốc trả lời:

tôi đã làm việc trên một dự án mà phiên bản của glibc chúng tôi đang sử dụng không cung cấp một chức năng backtrace() cho bộ vi xử lý ARM của chúng tôi, vì vậy chúng tôi phát triển bên ngoài của chúng ta của glibc sử dụng Biểu tượng __libc_stack_end. Dưới đây là mã kết quả. Có lẽ bạn có thể sử dụng nó để viết một hàm 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; 
} 

Lưu ý: Biểu tượng __libc_stack_end không còn được xuất khẩu trong nhiều phiên bản gần đây của glibc và tôi không chắc chắn về sự tồn tại của nó hoặc một biểu tượng tương tự trong uclibc.

+0

từ đoạn mã trên tôi đang nhận được lỗi runtime "lỗi vết lùi : __builtin_return_address (0)! = frame_p-> lr ". cách giải quyết tình trạng này. – Mandar

+0

Quy ước gọi điện chuẩn của ARM ([liên kết pdf] (http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf)) phân bổ r14 làm thanh ghi liên kết. Lệnh BL, được sử dụng trong một cuộc gọi chương trình con, lưu trữ địa chỉ trả về trong thanh ghi này. Các hàm '__builtin_frame_address (0)' và '__builtin_return_address (0)' được sử dụng cho [nhận được trả về và địa chỉ khung của hàm gọi] (http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html). Lỗi của bạn nói rằng thanh ghi liên kết không chứa địa chỉ trả về hoặc cấu trúc 'backtrace_frame_t' không khớp với khung ngăn xếp của bạn. – jschmier

1

Hãy nhìn vào cùng một câu hỏi hỏi ở đây:

http://lists.uclibc.org/pipermail/uclibc/2010-June/044115.html

đó đề cập đến một bản vá từ đây:

http://git.stlinux.com/?p=stm/uclibc.git;a=commit;h=d6a3d9ece5922a337800a8e2ed4db7e226f9ccb3

+0

Bạn nên đặt thông tin từ bài đăng đó vào câu trả lời của bạn ở đây, nếu không thì khi liên kết 404, câu trả lời của bạn sẽ trở thành vô ích. –

+0

ok. tạo một liên kết đến git commit. – lumpidu