2012-04-18 31 views
18

Tôi muốn sử dụng gprof để cấu hình một daemon. Daemon của tôi sử dụng thư viện của bên thứ 3, mà nó đăng ký một số cuộc gọi lại, sau đó gọi hàm main, không bao giờ trả về. Tôi cần gọi kill (hoặc SIGTERM hoặc SIGKILL) để chấm dứt daemon. Rất tiếc, trang hướng dẫn của gprof cho biết như sau:Lưu gmon.out trước khi giết một quá trình

Chương trình được định cấu hình phải gọi là "thoát" (2) hoặc trở lại bình thường để lưu vào thông tin hồ sơ gmon.out .

Có cách nào để lưu thông tin hồ sơ cho các quy trình bị giết bằng SIGTERM hoặc SIGKILL không?

Trả lời

24

Trước tiên, tôi muốn cảm ơn @wallyk đã cho tôi những gợi ý ban đầu tốt. Tôi đã giải quyết vấn đề của mình như sau. Rõ ràng, trình xử lý thoát gprof của libc được gọi là _mcleanup. Vì vậy, tôi đã đăng ký trình xử lý tín hiệu cho SIGUSR1 (không được thư viện của bên thứ ba sử dụng) và được gọi là _mcleanup_exit. Hoạt động hoàn hảo! Mã trông giống như sau:

#include <dlfcn.h> 
#include <stdio.h> 
#include <unistd.h> 

void sigUsr1Handler(int sig) 
{ 
    fprintf(stderr, "Exiting on SIGUSR1\n"); 
    void (*_mcleanup)(void); 
    _mcleanup = (void (*)(void))dlsym(RTLD_DEFAULT, "_mcleanup"); 
    if (_mcleanup == NULL) 
     fprintf(stderr, "Unable to find gprof exit hook\n"); 
    else _mcleanup(); 
    _exit(0); 
} 

int main(int argc, char* argv[]) 
{ 
    signal(SIGUSR1, sigUsr1Handler); 
    neverReturningLibraryFunction(); 
} 
+1

Bạn cũng cần thêm một số cờ vào trình biên dịch và trình liên kết. Đối với g ++, bạn nên sử dụng: -Wl, - no-as-needed -ldl -pg. Nguồn: http://stackoverflow.com/questions/20369672/undefined-reference-to-dlsym – rkioji

6

Bạn có thể thêm trình xử lý tín hiệu cho tín hiệu mà thư viện của bên thứ ba không bắt hoặc bỏ qua. Có lẽ SIGUSR1 là đủ tốt, nhưng sẽ phải thử nghiệm hoặc đọc tài liệu của thư viện — nếu nó đủ kỹ lưỡng.

Trình xử lý tín hiệu của bạn có thể chỉ cần gọi exit().

+0

Câu trả lời hay, nhưng nó thực sự không giải quyết được vấn đề của tôi. Thư viện của bên thứ ba sử dụng omnithread và giữ một mutex trong khi thực hiện. omnithread dường như đăng ký một cái gì đó bằng cách sử dụng atexit, bởi vì tôi nhận được 'chấm dứt được gọi là sau khi ném một thể hiện của 'omni_thread_fatal''. Khối lõi của quá trình, không có gmon.out. Tôi không thể gọi trực tiếp từ gex's atexit()? – user1202136

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