2011-12-17 31 views
23

Tôi có một stack trace được tạo ra bởi một ứng dụng lột mà trông như thế này:Sử dụng gdb để chuyển đổi địa chỉ cho dòng

*** Check failure stack trace: *** 
    @  0x7f0e442d392d (unknown) 
    @  0x7f0e442d7b1f (unknown) 
    @  0x7f0e442d7067 (unknown) 
    @  0x7f0e442d801d (unknown) 
    @  0x7f0e457c55e6 (unknown) 
    @  0x7f0e457c5696 (unknown) 
    @   0x4e8765 (unknown) 
    @   0x4a8b43 (unknown) 
    @  0x7f0e43197ced (unknown) 
    @   0x4a6889 (unknown) 

Và tôi có một phiên bản không lột của thực thi và tất cả các thư viện của nó (biên soạn với thông tin gỡ lỗi). Nhưng làm thế nào tôi có thể dịch địa chỉ vào các tập tin và số dòng ??

Dưới đây là những gì tôi đã cố gắng:

gdb 
set solib-absolute-prefix /path/to/non-stripped/edition/of/root/filesystem/sysroot/ 
file /path/to/non-stripped/edition/of/root/filesystem/sysroot/usr/bin/my-buggy-app 
info line *0x7f0e457c5696 

Khi tôi gõ vào lệnh tập tin nó chỉ tải biểu tượng từ các tập tin, không phải tất cả các thư viện được sử dụng. Có cách nào có thể thực hiện được không?

Các "đường dây thông tin" lệnh nói:

Không có thông tin số dòng có sẵn cho địa chỉ 0x7f0e442d801d

Mà tôi giả định là bởi vì địa chỉ là một trong các thư viện chia sẻ, nhưng làm thế nào có thể Tôi biết trong đó một trong số họ?

+3

['addr2line'] (http://linuxcommand.org/man_pages/addr2line1.html)? –

+0

@ another.anon.coward Năm, tôi đã thử điều đó nhưng tôi không biết cách xem tệp nào, vì địa chỉ trỏ đến thư viện được chia sẻ. – Allan

+0

@Allan: bạn có thể sử dụng lệnh 'info sharedlibrary' để biết thư viện chia sẻ địa chỉ' 0x7f0e442d801d' thuộc về. – ks1322

Trả lời

25

Nhưng làm cách nào để dịch địa chỉ thành tệp và số dòng?

Đối với thực thi chính (địa chỉ như 0x4e8765) làm điều này:

addr2line -e /path/to/non-stripped/.../my-buggy-app \ 
    0x4a6889 0x4a8b43 0x4e8765 

Trên thực tế, bạn có thể muốn trừ 5 (chiều dài thông thường của hướng dẫn CALL) từ tất cả các địa chỉ trên.

Đối với các địa chỉ trong thư viện được chia sẻ, bạn phải biết địa chỉ tải của thư viện.

Nếu ứng dụng của bạn tạo tệp core thì (gdb) info shared sẽ cho bạn biết thư viện đã được tải ở đâu.

Nếu bạn không nhận được một tập tin cốt lõi, và các ứng dụng không in các bản đồ cần thiết, sau đó

  • bạn nên sửa chữa các ứng dụng để nó in thông tin đó (stack trace chủ yếu là vô ích mà không có nó) và
  • bạn vẫn có thể đoán: xem mã trong tệp thực thi tại 0x4e8760 - nó phải là hướng dẫn CALL đối với một số chức năng. Bây giờ, hãy tìm hiểu xem thư viện nào có chức năng và tìm địa chỉ của thư viện trong thư viện (qua số nm). Nếu bạn may mắn, địa chỉ đó gần 0xNc56NN. Bây giờ bạn có thể đoán địa chỉ tải của bất kỳ thư viện nào là 0x7f0e457NNNNNN. Lặp lại cho 0x7f0e457c55e1 và bạn có thể tìm địa chỉ tải của thư viện tại 0x7f0e442dNNNN.
17

mỗi OP, lệnh trong GDB để tìm dòng nguồn mã từ một địa chỉ là:

info line *0x10045740 

Sửa: Thay thế "Thông tin biểu tượng 0x10045740" mà sẽ không làm việc dưới nhất định điều kiện (cảm ơn @ Thomasa88).

+3

Điều này chỉ hiển thị biểu tượng + bù đắp ('LftPlugin :: import_clicked() const + 1522 trong phần .text/home/thomas/.kde4/lib64/kde4/kmm_lft.so'), trong khi' thông tin dòng * 0xabc' hiển thị số dòng ('Dòng 97 của" plugin/lft_plugin.cpp "bắt đầu tại địa chỉ 0x7fffe49eb39c và kết thúc tại 0x7fffe49eb3ad .'). Trong trường hợp của tôi, thư viện được chia sẻ của tôi không bị tước đi, nhưng 'địa chỉ tên tập tin add-symbol-file' có thể có ích khi các biểu tượng bị tước đi. http://www.delorie.com/gnu/docs/gdb/gdbiffon.html – thomasa88

+3

Cảm ơn thomasa88! 'dòng thông tin * 0x10045740' bên trong gdb (nhớ dấu hoa thị) thực hiện công việc. –

Các vấn đề liên quan