2012-11-09 19 views
10

Nhìn vào this questionthis question Tôi có thể thấy rằng đối với backtrace_symbols() để hoạt động, người ta phải biên dịch với cờ -rdynamic.backtrace_symbols() với cả hai -static và -rdynamic

Tôi đã thử nó vào một chương trình thử nghiệm và nó hoạt động, nhưng tôi đang viết một chương trình mà cũng được biên soạn với -staticthis page nói rằng backtrace_symbols() không hoạt động khi -static được truyền cho các trình biên dịch/mối liên kết.

Có cách giải quyết nhanh nào cho vấn đề này hoặc tôi sẽ không bao giờ có chức năng backtrace có thể đọc được trong chương trình được liên kết tĩnh của tôi không?

Trả lời

8

Câu trả lời đã có trong tay: nó nằm trong số the same page I linked in the question. Cuối cùng, tôi đã sử dụng thành công libunwind.

#include <libunwind.h> 
#include <stdio.h> 

void do_backtrace() 
{ 
    unw_cursor_t cursor; 
    unw_context_t context; 

    unw_getcontext(&context); 
    unw_init_local(&cursor, &context); 

    while (unw_step(&cursor) > 0) 
    { 
     unw_word_t offset, pc; 
     char  fname[64]; 

     unw_get_reg(&cursor, UNW_REG_IP, &pc); 

     fname[0] = '\0'; 
     (void) unw_get_proc_name(&cursor, fname, sizeof(fname), &offset); 

     printf ("%p : (%s+0x%x) [%p]\n", pc, fname, offset, pc); 
    } 
} 

int main() 
{ 
do_backtrace(); 
return 0; 
} 

Tôi đã nhận được lỗi liên kết vì tôi đã (một lần nữa) tha thứ để đặt tùy chọn trình liên kết ở cuối dòng lệnh. Tôi thực sự không hiểu tại sao g++/gcc không phát hành ít nhất một cảnh báo khi bỏ qua các tùy chọn dòng lệnh. Dòng lệnh chính xác để biên dịch là (-g không cần thiết):

g++ -static unwind.cpp -o unwind -lunwind -lunwind-x86 
3

Nếu bạn hoàn toàn phải biên dịch chương trình tĩnh, bạn vẫn có thể sử dụng backtrace() để tìm địa chỉ của hàm và sau đó tìm tên hàm bằng cách phân tích cú pháp thông tin gỡ lỗi, sử dụng libdwarf.

Nhưng nó không phải là một nhiệm vụ đơn giản, vì vậy tôi khuyên bạn nên sử dụng cờ -rdynamic.

+0

Có, '-static' là bắt buộc trong chương trình của tôi. Tôi cũng đã thử với 'libunwind' nhưng các chương trình ví dụ của tôi không liên kết cả trên Ubuntu 12.04 x86 và x86_64. Tôi luôn nhận được các lỗi liên kết như: 'undefined reference to _Ux86_init_local' ' undefined reference to _Ux86_get_reg' 'undefined reference to _Ux86_get_proc_name' ' undefined reference to _Ux86_step' cả với libunwind Ubuntu nhị phân và libunwind tự biên dịch mới nhất tải xuống [ở đây] (http://download.savannah.gnu.org/releases/libunwind/). – Avio

+0

@Avio Tôi đã đề cập đến 'libdwarf', không phải là' libunwind'. Tôi không gặp vấn đề gì khi liên kết với 'libunwind' – qrdl

+0

Tôi sẽ thử' libdwarf' càng sớm càng tốt. Tôi đã đề cập đến 'libunwind' vì nó có thể là một lựa chọn thú vị khác mà không cần bất kỳ yêu cầu đặc biệt nào. Kiến trúc/phân phối nào bạn sử dụng whan bạn đã liên kết thành công với 'libunwind'? – Avio