2009-09-24 21 views
5

Giả sử tôi có chức năng được gọi là LOT từ nhiều nơi khác nhau. Vì vậy, tôi muốn tìm ra ai gọi hàm này nhiều nhất. Ví dụ: 5 người gọi hàng đầu hoặc những người từng gọi hàm này nhiều hơn N lần.Có cách nào để tìm ra những người gọi hàng đầu của một hàm C không?

Tôi đang sử dụng AS3 Linux, gcc 3.4.

Để bây giờ tôi chỉ cần đặt một breakpoint và sau đó dừng lại ở đó sau mỗi lần 300 lần, do đó brute-buộc nó ...

Có ai biết công cụ có thể giúp tôi?

Cảm ơn

+1

Gprof không thể thực hiện việc này? –

+2

Tôi không biết, có thể không :)? – vehomzzz

+1

không bao giờ được sử dụng gprof – vehomzzz

Trả lời

2

Tôi đã viết ví dụ ghi nhật ký cuộc gọi chỉ để giải trí. Macro thay đổi cuộc gọi hàm bằng một cuộc gọi hàm.

include <stdio.h>. 

int funcA(int a, int b){ return a+b; } 

// instrumentation 

void call_log(const char*file,const char*function,const int line,const char*args){ 
    printf("file:%s line: %i function: %s args: %s\n",file,line,function,args); 
} 

#define funcA(...) \ 
    (call_log(__FILE__, __FUNCTION__, __LINE__, "" #__VA_ARGS__), funcA(__VA_ARGS__)). 

// testing 

void funcB(void){ 
    funcA(7,8); 
} 


int main(void){ 
    int x = funcA(1,2)+ 

      funcA(3,4); 

    printf("x: %i (==10)\n", x); 

    funcA(5,6); 

    funcB(); 
} 

Output:

file:main.c line: 22 function: main args: 1,2 
file:main.c line: 24 function: main args: 3,4 
x: 10 (==10) 
file:main.c line: 28 function: main args: 5,6 
file:main.c line: 17 function: funcB args: 7,8 
+0

Tuyệt vời !!!! Tôi có thể thực hiện một cái gì đó như thế – vehomzzz

2

Tạo hồ sơ trợ giúp.

+0

Tôi là usbng một hồ sơ oprofile, nhưng nó không cung cấp cho tôi mức độ thông tin này – vehomzzz

+0

Có rất nhiều điều đó. Danadam đã gợi ý một câu trả lời. –

18

Biên dịch với tùy chọn -pg, chạy chương trình trong một thời gian và sau đó sử dụng gprof. Chạy chương trình được biên dịch với tùy chọn -pg sẽ tạo tệp gmon.out với cấu hình thực thi. gprof có thể đọc tệp này và hiển thị tệp ở dạng có thể đọc được.

+3

Và gprof2dot (http://code.google.com/p/jrfonseca/wiki/Gprof2Dot) có thể làm cho đầu ra đó thành một biểu đồ đẹp ;-) – ChristopheD

1

Vì bạn đã đề cập đến trang tính trong một nhận xét khác, tôi sẽ nói rằng oprofile hỗ trợ tạo biểu đồ thư trên các chương trình được định cấu hình.

Xem http://oprofile.sourceforge.net/doc/opreport.html#opreport-callgraph để biết thêm chi tiết. Cần chú ý điều này chắc chắn không rõ ràng như hồ sơ người gọi mà bạn có thể nhận được từ gprof hoặc một trình lược tả khác, như số mà nó báo cáo là số lần oprofile thu thập mẫu trong đó X là người gọi cho một hàm đã cho , không phải số lần X gọi là hàm đã cho. Nhưng điều này là đủ để tìm ra những người gọi hàng đầu của một hàm nhất định.

0

Ngoài trình hồ sơ gprof nói trên, bạn cũng có thể thử công cụ bảo vệ mã gcov. Thông tin về biên dịch và sử dụng cả hai nên được bao gồm trong hướng dẫn gcc.

1

Một phương pháp hơi rườm rà, nhưng không đòi hỏi phải có công cụ bổ sung:

#define COUNTED_CALL(fn, ...) do{ \ 
    fprintf(call_log_fp, "%s->%s\n", __FUNCTION__, #fn) ; \ 
    (fn)(__VA_ARGS__) ; \ 
}while(0) ; 

Sau đó, tất cả các cuộc gọi bằng văn bản như:

int input_available = COUNTED_CALL(scanf, "%s", &instring) ; 

sẽ được đăng nhập vào file liên quan đến call_log_fp (một FILE * toàn cầu mà bạn phải đã khởi tạo). Nhật ký cho phần trên sẽ trông giống như:

main->scanf 

Sau đó, bạn có thể xử lý tệp nhật ký đó để trích xuất dữ liệu mình cần. Bạn thậm chí có thể viết mã của riêng bạn để làm các thiết bị đo đạc mà có thể làm cho nó có lẽ ít cồng kềnh.

Có thể có một chút mơ hồ đối với các hàm thành viên lớp C++. Tôi không chắc liệu có macro __CLASS__ hay không.

0

Một lần nữa, stack sampling to the rescue! Chỉ cần một loạt các "stackshots", như nhiều như bạn muốn. Loại bỏ bất kỳ mẫu nào mà chức năng của bạn (gọi là F) không ở đâu đó trên ngăn xếp.(Nếu bạn loại bỏ hầu hết trong số họ, thì F không phải là vấn đề hiệu suất.)

Trên mỗi mẫu còn lại, tìm cuộc gọi đến F và xem chức năng nào (gọi là G). là đệ quy (nó xuất hiện nhiều hơn một lần trên mẫu) chỉ sử dụng cuộc gọi trên cùng.

Rank Gs của bạn bằng cách bao nhiêu ngăn xếp mỗi người xuất hiện trong.

Nếu bạn không muốn làm điều này bằng tay, bạn có thể làm một công cụ đơn giản hoặc kịch bản. Bạn không cần một tỷ mẫu. 20 hoặc hơn sẽ cung cấp cho bạn thông tin hợp lý.

Bằng cách này, nếu những gì bạn thực sự cố gắng làm là tìm các vấn đề về hiệu suất, bạn không thực sự cần phải thực hiện tất cả việc loại bỏ và xếp hạng. Trong thực tế - không loại bỏ các vị trí chính xác của lệnh gọi bên trong mỗi G. Những thực sự có thể cho bạn biết một chút tốt hơn chỉ là một thực tế rằng họ đã ở đâu đó bên trong G.

P.S. Điều này là tất cả dựa trên giả định rằng khi bạn nói "gọi nó là nhất" bạn có nghĩa là "dành nhiều thời gian đồng hồ treo tường nhất để gọi nó", không phải "gọi nó là số lần lớn nhất". Nếu bạn quan tâm đến hiệu suất, phần thời gian của đồng hồ treo tường sẽ hữu ích hơn số lần gọi.

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