2009-06-26 31 views
13

Tôi có một ứng dụng C mà chúng tôi đã triển khai cho trang web của khách hàng. Nó được biên dịch và chạy trên HP-UX. Người dùng đã báo cáo sự cố và chúng tôi đã có được kết xuất chính. Cho đến nay, tôi đã không thể lặp lại vụ tai nạn trong nhà.Tệp lõi gỡ lỗi không có ký hiệu

Như bạn nghi ngờ, tệp lõi/triển khai được triển khai hoàn toàn không có bất kỳ loại biểu tượng nào. Khi tôi tải nó lên trong gdb và làm một bt, tốt nhất tôi nhận được là:

(gdb) bt 
#0 0xc0199470 in ??() 

tôi có thể làm một 'dây lõi' trên tập tin, nhưng sự hiểu biết của tôi là tất cả những gì đạt được điều đó là tất cả các các chuỗi trong tệp thực thi, vì vậy dường như không thể theo dõi bất kỳ thứ gì ở đó.

Tôi có một phiên bản gỡ lỗi (được biên dịch với -g) của tệp thực thi, rất tiếc là một vài tháng mới hơn phiên bản đã phát hành. Nếu tôi cố gắng để bắt đầu gdb với trung tâm đó, tôi thấy điều này:

warning: exec file is newer than core file. 
Core was generated by `program_name'. 
Program terminated with signal 11, Segmentation fault. 
__dld_list is not valid according to __dld_flags. 

#0 0xc0199470 in ??() 
(gdb) bt 
#0 0xc0199470 in ??() 

Trong khi nó sẽ là khả thi để biên dịch một phiên bản sửa lỗi và triển khai nó tại địa điểm của khách hàng và sau đó chờ cho vụ tai nạn khác, nó sẽ là tương đối khó khăn và không mong muốn vì một số lý do.

Tôi khá quen thuộc với mã và có ý tưởng tương đối tốt về vị trí mã đang bị lỗi dựa trên báo cáo lỗi của khách hàng.

Có cách nào để tôi có thể thu thập thêm bất kỳ thông tin nào từ kết xuất cốt lõi này không? Qua chuỗi hoặc trình gỡ lỗi khác hoặc bất kỳ thứ gì? Cảm ơn.

Trả lời

7

Đây là loại phản ứng từ gdb:

(gdb) bt 
#0 0xc0199470 in ??() 

cũng có thể xảy ra trong trường hợp đó, đống bị đập tan bởi một bộ đệm tràn ngập, nơi địa chỉ trả lại được ghi đè trong bộ nhớ, do đó chương trình truy cập được thiết lập để một khu vực dường như ngẫu nhiên.

Đây là một trong những cách mà ngay cả khi xây dựng với một cơ sở dữ liệu biểu tượng tương ứng cũng có thể gây ra lỗi tra cứu biểu tượng (hoặc dấu trang tìm kiếm lạ). Nếu bạn vẫn nhận được thông báo này sau khi bạn có bảng biểu tượng, vấn đề của bạn có thể là dữ liệu của khách hàng đang gây ra một số vấn đề với mã của bạn.

+0

Câu trả lời này có vẻ khó hiểu với tôi. Tôi chắc chắn sẽ xem xét mã cho các khu vực có khả năng bị tràn ngập. – Morinar

+0

Nếu gỡ lỗi với một bản sao "trùng lặp" không hiển thị bất cứ điều gì, đó là thời gian để bắt đầu nhìn vào đăng ký và ngăn xếp bãi để cố gắng suy ra cách bạn đã đi vào giữa hư không. Nó cũng có thể là con trỏ hàm (hoặc uninitialized) bị thổi, quá tải phân bổ, hoặc có thể là kích cỡ bộ đệm không chính xác hoặc đầu vào "xấu" thổi bộ đệm (sử dụng sprintf()/sscanf với đầu vào không kiểm soát, v.v.). – jesup

+0

Tôi chưa bao giờ tìm ra bất cứ điều gì ở đây, nhưng tôi chấp nhận điều này vì nó vẫn có vẻ giống như khả năng xảy ra nhất. – Morinar

1

Bạn có nguồn chính xác mà bạn đã sử dụng để biên dịch phiên bản cũ (ví dụ: thông qua thẻ trong cây nguồn hoặc thứ gì đó tương tự) không? Có lẽ bạn có thể xây dựng lại bằng cách sử dụng đó, và có thể có được một cái nhìn sâu sắc vào nơi vụ tai nạn xảy ra?

+0

Tôi có nguồn chính xác, nhưng đoạn mã cụ thể này đã không thay đổi nhiều (nếu có) từ điểm đó đến những gì tôi có bây giờ. – Morinar

0

Không có nhiều thông tin ở đây. Các nhị phân là stripped.But nhìn vào lỗi phân khúc ... bạn nên tìm những nơi mà có một khả năng mà bạn đang ghi đè lên một mảnh bộ nhớ.

Đây chỉ là một gợi ý. Có thể có nhiều vấn đề.

BTW, nếu bạn không thể sao chép trong máy cục bộ của bạn thì khối lượng dữ liệu trên khách hàng có thể là một vấn đề.

5

Đối với tương lai:

  1. Hãy chắc chắn rằng bạn luôn xây dựng với một cơ sở dữ liệu biểu tượng bên ngoài (điều này không phải là một debug xây dựng - đó là một phát hành xây dựng, nhưng bạn lưu trữ các bảng biểu tượng riêng)
  2. giữ nó xung quanh cho các phiên bản bạn triển khai

đối với tình huống này:

bạn biết khu vực chung, vì vậy để xem nếu bạn là đúng, đi đến tra ngăn xếp ce và tìm mã lắp ráp - nhãn cầu nó và xem nếu bạn nghĩ rằng nó phù hợp với nguồn của bạn (điều này là dễ dàng hơn nếu bạn có một số ý tưởng những gì nguồn tạo ra lắp ráp này). Nếu nó có vẻ đúng, sau đó bạn có một số xác minh về giả thuyết của bạn. Bạn có thể tìm ra các giá trị của các biến cục bộ bằng cách nhìn vào ngăn xếp (vì bạn biết những gì bạn truyền vào và khai báo).

+0

Làm cách nào để tìm mã lắp ráp và/hoặc truy cập vào ngăn xếp ngăn xếp? Tất cả các dấu vết ngăn xếp tôi đã nhìn thấy cho đến nay tôi dán lên trên ... – Morinar

+0

Lệnh này là 'tháo rời' - xem http://www.unknownroad.com/rtfm/gdbtut/gdbadvanced.html –

+0

Tôi đã làm này và có: (gdb) tháo rời Không có chức năng nào chứa bộ đếm chương trình cho khung đã chọn. Mà dường như tôi thích nó ủng hộ chồng đập vỡ theo đề nghị của Sufian dưới đây. – Morinar

2
  1. Luôn kiểm soát nguồn sử dụng (CVS/GIT/Subversion/etc), ngay cả đối với các phiên bản thử nghiệm
  2. Tag tất cả phiên
  3. Hãy xem xét (trong tương lai) thực hiện một xây dựng với gỡ lỗi (- g) và loại bỏ tệp thực thi trước khi giao hàng. LƯU Ý: Không tạo hai bản dựng có và không có -g; chúng có thể không khớp với nhau, vì thỉnh thoảng có thể gây ra các mã khác nhau được tạo ngay cả ở cùng mức tối ưu hóa. Trong mã siêu hiệu suất quan trọng, bạn có thể từ bỏ -g cho các tệp quan trọng - hầu hết nó sẽ không tạo sự khác biệt.
  4. Nếu bạn đang thực sự bị mắc kẹt, hãy đổ ngăn xếp và đổ các phần liên quan của heap xuống hex và xem nó bằng tay; có lẽ lấy một bản sao có dụng cụ và tìm kiếm các chữ ký tương tự trong mã được tạo ra và trên ngăn xếp. Đây là thực "cũ-trường" gỡ lỗi ... :-)
+0

Lời khuyên chắc chắn chắc chắn. Chúng tôi thực hiện rất nhiều bước 1-3 ở đây, nhưng bất kể, chúng được xử lý bởi một nhóm người hoàn toàn khác (chúng tôi có một đội phụ trách những thứ ở đây) hơn là bản thân mình. – Morinar

3

Dưới gdb, "Thông tin đăng ký" sẽ cho bạn đủ tình trạng thực hiện tại thời điểm vụ tai nạn để sử dụng với một tháo dỡ các thư viện được chia sẻ và có thể thực thi. Tôi thường sử dụng objdump để tháo rời, chuyển hướng đầu ra vào một tập tin, sau đó đưa lên các tập tin trong trình soạn thảo yêu thích của tôi - điều này rất hữu ích cho việc lưu giữ các ghi chú như mọi thứ được tìm ra. Ngoài ra gdb của "thông tin mục tiêu" và "info sharedlib" có thể hữu ích cho việc tìm ra nơi thư viện chia sẻ được nạp. Với trạng thái đăng ký, nội dung ngăn xếp, và tháo gỡ trong tay cùng với một chút may mắn, nó sẽ đơn giản (nếu tẻ nhạt) để tái tạo lại callstack (trừ khi, tất nhiên, ngăn xếp đã được trashed bởi một bộ đệm overrun hoặc tương tự thảm họa ... có thể cần một bảng Ouija hoặc quả cầu pha lê trong trường hợp đó.)

Bạn cũng có thể tương quan aa tháo gỡ phiên bản mới hơn được xây dựng với -g chống lại việc tháo gỡ phiên bản bị tước.

1

Thử chạy "pmap" đối với tệp lõi (nếu hp/ux có công cụ này). Điều này sẽ báo cáo địa chỉ bắt đầu của tất cả các mô-đun trong tệp lõi. Với thông tin này, bạn sẽ có thể lấy địa chỉ của vị trí lỗi và tìm ra thư viện nào bị lỗi. So sánh địa chỉ hơn giữa địa chỉ sự cố và địa chỉ của các hàm đã biết trong thư viện ("nm" so với thư viện sẽ nhận được điều đó) có thể giúp bạn xác định hàm nào bị lỗi.

Thậm chí nếu bạn quản lý để xác định chức năng ở đầu ngăn xếp, nó không phải là rất có khả năng chức năng này là nguồn gốc của vấn đề ... hy vọng nó đã thực sự bị rơi trong mã của bạn và không, nói , thư viện chuỗi C chuẩn. Việc xây dựng lại dấu vết ngăn xếp là điều tốt nhất tiếp theo tại thời điểm đó.

0

Tôi không nghĩ rằng tệp lõi được cho là có chứa biểu tượng. Bạn cần có thể tạo phiên bản chương trình của mình là chính xác cùng một số là những gì bạn đã giao cho khách hàng của mình, nhưng với -g.Nếu bạn loại bỏ tệp thực thi gỡ lỗi của mình, nó phải giống hệt với phiên bản đã xuất. Chỉ sau đó có thể gdb cung cấp cho bạn bất cứ điều gì hữu ích.

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