2011-01-07 33 views
42

Tôi có chương trình C đa luồng, thường xuyên tạo ra lỗi phân đoạn tại một điểm cụ thể trong chương trình. Khi tôi chạy nó với gdb, không có lỗi nào được hiển thị. Bạn có thể nghĩ ra bất kỳ lý do nào tại sao lỗi có thể xảy ra chỉ khi không sử dụng trình gỡ rối không? Nó khá khó chịu không thể sử dụng nó để tìm ra vấn đề!segfault chỉ khi KHÔNG sử dụng trình gỡ lỗi

+3

Loại lỗi này được gọi là ["Heisenbug"] (http://en.wikipedia.org/wiki/Heisenbug#Heisenbug) và có thể có nhiều nguyên nhân. –

+0

Lỗi có xảy ra liên quan đến quản lý cửa sổ và/hoặc User32.dll không? – Mehrdad

+1

Tôi gặp sự cố như vậy, chương trình của tôi chỉ bị lỗi với GDB. Vấn đề là một biến thành viên lớp không được nhận dạng vẫn nhận được giá trị 0 khi tôi chạy chương trình của mình, nhưng khi tôi chạy nó trong GDB nó có một số giá trị lớn bị phân đoạn khi tôi sử dụng nó làm chỉ mục mảng. – GWW

Trả lời

62

Cổ điển Heisenbug. Từ Wikipedia:

Thời gian cũng có thể là một yếu tố trong heisenbugs. Thực hiện một chương trình dưới sự kiểm soát của trình gỡ rối có thể thay đổi thời gian thực hiện của chương trình so với thực thi thông thường. Các lỗi thời gian nhạy cảm như các điều kiện chủng tộc có thể không sinh sản khi chương trình bị chậm lại bởi các dòng nguồn đơn bước trong trình gỡ lỗi. Điều này đặc biệt đúng khi hành vi liên quan đến sự tương tác với một thực thể không dưới sự kiểm soát của một trình gỡ rối, chẳng hạn như khi gỡ lỗi xử lý gói mạng giữa hai máy và chỉ một bộ điều khiển được kiểm soát.

Trình gỡ lỗi có thể thay đổi thời gian và ẩn điều kiện cuộc đua.

Trên Linux, GDB cũng vô hiệu hóa ngẫu nhiên không gian địa chỉ và sự cố của bạn có thể cụ thể để bố trí không gian địa chỉ. Hãy thử (gdb) set disable-randomization off.

Cuối cùng, ulimit -c unlimited và gỡ lỗi sau khi chết (đã được Robie đề xuất) có thể hoạt động.

+8

'thiết lập tắt ngẫu nhiên tắt' giải quyết một vấn đề tương tự cho tôi! –

+0

nếu tôi đang sử dụng LLDB thì sao? lệnh tương đương là gì? – thiagoh

+0

@thiagoh: Thật không may tôi không biết (Tôi không phải là người đã chỉnh sửa nội dung đó), bạn có thể muốn hỏi người khác ... – Mehrdad

4

Bằng cách gỡ lỗi, bạn đang thay đổi môi trường đang chạy. Có vẻ như bạn đang xử lý một số loại điều kiện chủng tộc và bằng cách gỡ lỗi, mọi thứ được lên lịch hơi khác nhau để bạn không gặp phải vấn đề. Điều đó, hoặc những thứ đang được lưu trữ một cách hơi khác nhau vì vậy nó không xảy ra. Bạn có thể đặt một số đầu ra gỡ lỗi trong mã để hỗ trợ trong việc tìm ra vấn đề không? Điều đó có thể có ít tác động hơn và cho phép bạn tìm ra vấn đề của mình.

5

Có lẽ khi sử dụng bộ nhớ gdb được ánh xạ ở vị trí mà lưu lượng quá/dưới của bạn không bị xáo trộn trên bộ nhớ gây ra sự cố. Hoặc nó có thể là một điều kiện chủng tộc không còn bị vấp ngã nữa. Mặc dù nghe có vẻ không trực quan, bạn phải là chúc mừng chương trình của bạn đủ đẹp để gây tai nạn cho bạn.

Một số gợi ý

  1. Hãy thử một máy phân tích mã tĩnh như miễn phí cppcheck
  2. Hãy thử một trình gỡ lỗi malloc() như libefence
  3. Hãy thử chạy nó thông qua valgrind
1

tôi đã hoàn toàn có vấn đề này trước đây! Đó là một tình trạng chạy đua, và khi tôi đang bước qua đoạn mã với một trình gỡ rối, luồng tôi đang ở đủ chậm để không kích hoạt tình trạng cuộc đua. Khá tệ.

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