2010-08-30 31 views
6

Tôi có câu hỏi sau đây và từ quan điểm hệ thống muốn biết cách đạt được điều này một cách dễ dàng và hiệu quả.C/C++ Câu hỏi về kỹ thuật lập trình theo dõi

Cho một tác vụ 'abc' đã được tạo bằng thông tin gỡ lỗi và biến toàn cục "TRACE" được đặt thành 0, tôi muốn in ra tệp 'đăng nhập' địa chỉ của mỗi hàm được gọi giữa thời gian TRACE được đặt thành 1 và ngược lại thành 0.

Tôi đã cân nhắc thực hiện thao tác này thông qua tác vụ tải trước/khởi động mà tôi muốn phát triển, xem hướng dẫn cho một kiểu nhảy chung/đẩy con trỏ khung, viết xuống địa chỉ và sau đó ánh xạ địa chỉ đến các tên hàm từ thông tin gỡ lỗi tượng trưng trong abc. Có thể có các cách mức hệ thống tốt hơn để thực hiện điều này mà không cần bộ nạp trước, và tôi không chắc điều gì là khả thi nhất.

Bất kỳ kỹ thuật được triển khai nào ngoài đó?

+3

Profilers đã có thể làm điều đó cho bạn - thậm chí hiển thị tên hàm thay vì địa chỉ. Tại sao họ không làm việc cho bạn? – Dummy00001

+0

Tại sao bạn quan tâm đến địa chỉ của hàm thay vì tên của nó? Ngoài ra nó rất hữu ích để biết những gì hệ điều hành và trình biên dịch bạn đang sử dụng. –

+0

Tôi đang sử dụng gcc/CC/xlC trên HP/Sun/IBM. Tôi cuối cùng quan tâm đến tên của các chức năng; địa chỉ được dự định chỉ là trung gian và có thể không cần thiết. Cảm ơn. – BlueCollar

Trả lời

1

Đảm bảo bạn đã xem xét __func__ hoặc __FUNCTION__ số nhận dạng được xác định trước. Chúng cung cấp một chuỗi ký tự của tên hàm/phương thức mà bạn hiện đang thực hiện.

3

Một khả năng là xử lý trước nguồn trước khi biên dịch. Việc xử lý trước này sẽ thêm mã vào đầu mỗi hàm sẽ kiểm tra TRACE toàn cầu và, nếu được đặt, ghi vào nhật ký. Như Mystagogue đã nói, trình biên dịch có các macro tiền xử lý mở rộng đến tên của hàm.

Bạn cũng có thể xem một số công cụ lược tả. Một số người trong số họ có chức năng gần với những gì bạn đang yêu cầu. Ví dụ, một số sẽ lấy mẫu toàn bộ callstack theo định kỳ, có thể cho bạn biết rất nhiều về luồng mã mà không thực sự ghi lại mọi cuộc gọi.

+0

Các nguồn tiền xử lý có thể là một trong những cách rẻ nhất để thực hiện. – Dummy00001

+0

Chúng tôi cần đăng nhập mọi cuộc gọi. Tôi có thể sử dụng dtrace để có được các ngăn xếp định kỳ tần số cao, nhưng điều này sẽ không thực hiện được.Các nguồn tiền xử lý có thể, nhưng các tệp nhị phân của chúng tôi đã đạt đến giới hạn 32 gigabit 32 bit. Cảm ơn – BlueCollar

2

Tìm kiếm phần mở đầu phổ biến/phần kết nghĩa sẽ không hoạt động với sự hiện diện của bỏ sót con trỏ khung và tối ưu hóa cuộc gọi đuôi. Ngoài ra, tối ưu hóa hiện đại như để chia chức năng thành nhiều phần và hợp nhất các phần đuôi phổ biến của các chức năng khác nhau.

Không có giải pháp chuẩn.

Đối với trình biên dịch của Microsoft, hãy xem _penter_pexit móc. Đối với GCC, hãy xem tùy chọn -finstrument-functions và bạn bè.

Ngoài ra, trên x86 Windows, bạn có thể sử dụng màn hình như WinApiOverride32. Nó chủ yếu dành cho giám sát DLL và các cuộc gọi API hệ thống, nhưng bạn có thể tạo một tệp mô tả từ tệp bản đồ của ứng dụng của bạn và theo dõi các chức năng nội bộ.

(. được sửa đổi: thêm link để lựa chọn GCC)

+0

Tôi đồng ý - cảm ơn phản hồi. Debugger 'dbx' dường như có thể làm điều này, mặc dù, vì vậy tôi không nghĩ rằng có đuôi gọi tối ưu hóa - hoặc làm thế nào có thể dbx con số nó ra? Nếu trình gỡ lỗi có thể thực hiện, chúng tôi sẽ có thể thực hiện. Vấn đề là rõ ràng là không thực tế khi được tải trong dbx trong môi trường sản xuất, vì vậy ý ​​tưởng là thực hiện công việc tối thiểu cần thiết trong một tác vụ tải trước tương tự có thể nói khi các tệp nhị phân đang gọi ra các hàm. Ngay cả ở trường hợp xấu nhất, tôi cũng có thể ghi lại tất cả các bước nhảy, cũng sẽ hiển thị (mặc dù ồn ào) trong dòng chảy chức năng. – BlueCollar

+0

Tôi hy vọng cho các chức năng -finstrument :) sẽ điều tra thêm .. cảm ơn nhiều – BlueCollar