2011-11-24 47 views
7

Chúng tôi có phiên bản nhúng của nhân Linux chạy trên lõi MIP. Chương trình chúng tôi đã viết chạy một bộ thử nghiệm cụ thể. Trong một trong các bài kiểm tra căng thẳng (chạy trong khoảng 12 giờ), chúng tôi nhận được một lỗi seg. Điều này lần lượt tạo ra một bãi chứa lõi.Bắt gỡ lỗi tốt hơn khi Linux gặp sự cố trong một chương trình C

Rất tiếc, kết xuất lõi không phải là rất hữu ích. Sự cố là trong một số thư viện hệ thống được liên kết động (có thể là pthread hoặc glibc). Các vết lùi trong các bãi chứa lõi là không hữu ích vì nó chỉ cho thấy điểm vụ tai nạn và không có người gọi khác (ứng dụng không gian sử dụng của chúng tôi được xây dựng với -O0 -g, nhưng vẫn không có lại thông tin dấu vết):

Cannot access memory at address 0x2aab1004 
(gdb) bt 
#0 0x2ab05d18 in ??() 
warning: GDB can't find the start of the function at 0x2ab05d18. 

    GDB is unable to find the start of the function at 0x2ab05d18 
and thus can't determine the size of that function's stack frame. 
This means that GDB may be unable to access that stack frame, or 
the frames below it. 
    This problem is most likely caused by an invalid program counter or 
stack pointer. 
    However, if you think GDB should simply search farther back 
from 0x2ab05d18 for code which looks like the beginning of a 
function, you can increase the range of the search using the `set 
heuristic-fence-post' command. 

bất hạnh khác -ness là chúng ta không thể chạy gdb/gdbserver. gdb/gdbserver tiếp tục vi phạm trên __nptl_create_event. Thấy rằng các thử nghiệm tạo ra các chủ đề, giờ và phá hủy sau đó mỗi 5s nó gần như không thể ngồi trong một thời gian dài đánh tiếp tục trên chúng.

EDIT: Một lưu ý khác, backtrace và backtrace_symbols không được hỗ trợ trên chuỗi công cụ của chúng tôi.

Do đó:

  1. Có một cách để bẫy lỗi seg và tạo dữ liệu vết lùi hơn, chồng con trỏ, gọi chồng, vv?

  2. Có cách nào để nhận thêm dữ liệu từ một phân đoạn lõi bị lỗi trong tệp .so không?

Cảm ơn.

+0

Bạn có thể thử xử lý 'SIGSEGV' nếu có thể? Nó không bao giờ được đề nghị, nhưng tôi cảm thấy rằng có thể giúp bạn trong tình huống này. – Stark07

Trả lời

1

Nếu mọi thứ khác không chạy lệnh bằng trình gỡ lỗi!

Chỉ cần đặt "gdb" dưới dạng lệnh bắt đầu bình thường của bạn và nhập "c" ontinue để chạy quy trình. Khi nhiệm vụ segfaults nó sẽ trở về dấu nhắc gdb tương tác chứ không phải là kết xuất lõi. Sau đó, bạn sẽ có thể nhận được các dấu vết ngăn xếp có ý nghĩa hơn, v.v.

Một tùy chọn khác là sử dụng "giàn" nếu có. Điều này sẽ cho bạn biết các cuộc gọi hệ thống nào đang được sử dụng tại thời điểm diễn ra sự kiện.

+0

Tôi đoán điều này là không thể. Chương trình đang chạy trên một hệ thống nhúng và người hỏi đã thử dùng gdb với gdbserver. – daxelrod

+0

Umm, nhiều như tôi thích đẩy 'c' làm như vậy sẽ dẫn đến khoảng 8640 lần tôi sẽ cần phải đẩy 'c' trước khi nó bị treo :) Điều duy nhất tôi có thể tìm thấy về giàn là cho Solaris và Linux sẽ sử dụng strace. strace sẽ không thực sự giúp đỡ ở đây như xa như tôi biết. Cảm ơn. – user626201

+0

@ user626201 - c = tiếp tục cho đến điểm ngắt tiếp theo. Không có điểm ngắt không có lời nhắc cho đến khi một ngoại lệ cần xử lý. –

1

GDB không thể tìm thấy sự khởi đầu của hàm tại 0x2ab05d18

gì là tại địa chỉ đó vào thời điểm vụ tai nạn?

Làm info shared và tìm hiểu xem thư viện có chứa địa chỉ đó không.

Nguyên nhân có thể gây ra rắc rối của bạn: bạn có chạy strip libpthread.so.0 trước khi tải lên mục tiêu của mình không? Không làm điều đó: GDB yêu cầu libpthread.so.0 đến không bị tước. Nếu chuỗi công cụ của bạn chứa libpthread.so.0 với các biểu tượng gỡ lỗi (và do đó quá lớn cho mục tiêu), hãy chạy strip -g trên đó, không phải là strip đầy đủ.

Cập nhật:

info shared sản xuất không thể truy cập vào bộ nhớ tại địa chỉ 0x2ab05d18

Điều này có nghĩa rằng GDB không thể truy cập danh sách thư viện chia sẻ (mà sau đó sẽ giải thích sự thiếu stack trace). Nguyên nhân thông thường nhất: nhị phân thực sự tạo ra core không khớp với nhị phân mà bạn đã cung cấp cho GDB. Nguyên nhân ít phổ biến hơn: kết xuất cốt lõi của bạn đã bị cắt bớt (có lẽ do ulimit -c được đặt quá thấp).

+0

Xin chào, thông tin được chia sẻ được sản xuất 'Không thể truy cập bộ nhớ tại địa chỉ 0x2ab05d18'. Chúng tôi chưa chạm vào tệp .so. – user626201

+0

Không chắc chắn nếu điều này được tính nhưng một lần chạy khác cho biết địa chỉ nằm trong libc: 'thông tin được chia sẻ Từ To Syms Đọc Thư viện đối tượng được chia sẻ 0x2aaf7e70 0x2ab461f0 Có /opt/nfsroot_bcm97335_stblinux-2.6.18-7.7_be/lib/libc.so. 0' – user626201

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