2011-10-04 63 views
5

Tôi đã gặp phải lỗi phân đoạn có dây. Tôi đang phát triển một phần mềm trong C bằng Eclipse CDT. Khi chạy chương trình của tôi trên thiết bị đầu cuối (Ubuntu 10, 64 bit), nó chỉ đơn giản là báo cáo "Phân đoạn lỗi". Tuy nhiên, khi tôi gỡ lỗi bằng cách sử dụng gdb trong Eclipse, nó đi đến cuối và kết quả là chính xác.Lỗi phân đoạn khi chạy, nhưng thành công khi gỡ lỗi

Tôi hiểu rằng có thể có nhiều lý do cho lỗi phân đoạn. Và tôi xin lỗi vì tôi không thể hiển thị mã của mình vì tôi không biết vấn đề có thể ở đâu ...

Nhưng bất cứ ai có thể vui lòng giúp tôi, có tình huống nào có thể xảy ra như trường hợp của tôi hay không: lỗi phân đoạn trên thiết bị đầu cuối, trong khi tốt trong gỡ lỗi? Cám ơn rất nhiều.


Xin cảm ơn, tất cả. Tôi đã dành chút thời gian để học valgrind. Tôi chỉ sửa lỗi bằng cách thay thế một malloc() bởi realloc(). Cuộc gọi được theo sau bởi hai memcpy. Đó có phải là lý do? Đây là đoạn mã:

bwa_seq_t *merge_seq (bwa_seq_t *s1, bwa_seq_t *s2) { 
    ubyte_t *seq1, *seq2, *tmp; 
    if (!s1 || !s2) 
    return 0; 
    seq1 = s1->seq; 
    seq2 = s2->seq; 
    tmp = (ubyte_t*) calloc (sizeof(ubyte_t), (s2->len + s1->len + 1)); 
    memcpy(tmp, seq1, sizeof(ubyte_t) * s1->len); 
    memcpy(&tmp[s1->len], seq2, sizeof(ubyte_t) * s2->len); 
    s1->len += s2->len; 
    tmp[s1->len] = '\0'; 
    s1->seq = tmp; 
    return s1; 
} 

Ai đó có thể giúp giải thích tại sao?

+0

Có thể xảy ra sự cố tham nhũng và/hoặc đống. Hãy chắc chắn rằng bạn cho phép cảnh báo đầy đủ trên trình biên dịch của bạn và đối phó với tất cả chúng. Các đối số không khớp với 'printf' và những thứ như thế là những thứ cần tìm kiếm. – Mat

+2

Chạy chương trình của bạn dưới [valgrind] (http://valgrind.org/), vấn đề này có thể sẽ trở nên rõ ràng. – Hasturkun

Trả lời

9

Hãy thử các bước sau:

  • loại ulimit -c unlimited trong một xterm (điều này cho phép tạo các lõi/file postmorterm)

  • ra mắt chương trình của bạn (và để cho nó sụp đổ): một tập tin lõi bây giờ sẽ có mặt trong thư mục.

  • ra mắt trình gỡ lỗi với gdb <yourprogram> <corefile>

  • loại bt tại dấu nhắc gdb để xem vào những gì dòng nó đã sụp đổ.

  • (tùy chọn) sửa lỗi.

+0

Điều này về cơ bản là câu trả lời của lsalamon. 1 phút sau ^^ –

+2

Er, vâng. Nhưng câu trả lời này có vẻ toàn diện hơn đối với tôi. – Joy

0

Đây có lẽ là kết quả của biến chưa được khởi tạo. (Trong dòng 14 của chương trình của bạn)

+0

Tại sao lại là dòng 14? – Hasturkun

+2

Tôi phải đoán; OP không hiển thị bất kỳ nguồn có liên quan nào. – wildplasser

5

Nếu bạn biết làm thế nào để sụp đổ nó từ thiết bị đầu cuối, bạn có thể làm cho nó tạo ra một corefile và kiểm tra điểm mà nó bị rơi như thế này:

$ ulimit -c unlimited # to create a corefile 
$ yourprogram 
... 
crash     # this will create file "core" in the current directory 
$ gdb yourprogram core # shows the state at the moment of the crash 

Câu hỏi trên đó chủ đề:

0

Biên dịch thông tin gỡ lỗi và sử dụng gdb để xác định nơi xảy ra lỗi khi sử dụng kết xuất.

0

Rất có thể bạn đang gặp phải một số hành vi không xác định. Như những người khác đã nói, sử dụng Valgrind để gỡ lỗi vấn đề này. Trước hết hãy tìm các lỗi READALID READ, INVALID WRITE trong đầu ra Valgrind. Nó cũng sẽ tạo ra các ngăn xếp cuộc gọi bổ sung khi những điều xấu xảy ra trong mã của bạn. Điều này sẽ giúp hiểu được lý do lỗi.

0

Tôi cũng phải đối mặt với vấn đề này trước đây. Không phải trong Linux với trình biên dịch GCC nhưng trong Visual studio 2005. Nó giống như, mã của tôi đã chạy thành công trong chế độ gỡ lỗi trong khi ở chế độ phát hành (Direct running), nó đã bị hỏng. Thực tế là khi bạn đang gỡ lỗi mã của bạn, trình gỡ rối sẽ xử lý các ngoại lệ như vi phạm Truy cập, mảng bị ràng buộc, v.v. và không cho phép mã bị lỗi. Trong chế độ chạy trực tiếp không có ai để chăm sóc ngoại lệ và do đó mã bị lỗi.

Tôi khuyên bạn nên sử dụng printf để hiển thị kết quả hoạt động trung gian vì đây là cách tốt nhất để khắc phục sự cố mã của bạn.

Hy vọng điều này sẽ giúp bạn .. :-)

0

BTW: bạn đang bị rò rỉ bộ nhớ ở đây. s1-> seq về cơ bản đang được thực, nhưng bạn quên giải phóng bộ nhớ cũ. Thay đổi:

s1->len += s2->len; 
tmp[s1->len] = '\0'; 
s1->seq = tmp; 
return s1; 

thành:

void *del; // <<-- 
s1->len += s2->len; 
tmp[s1->len] = '\0'; 
del = s1->seq; // <<-- 
s1->seq = tmp; 
free (del); // <-- 
return s1; 

, Và ít nhất bạn sẽ ngăn chặn rò rỉ.

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