2009-08-21 11 views
6

Trong C trên Solaris 10, tôi muốn nhận được ngăn xếp cuộc gọi từ một chuỗi tùy ý trong một quy trình.Nhận cuộc gọi ngăn xếp từ bất kỳ chủ đề nào trong C

Tôi có nhiều chuỗi công việc và một chuỗi theo dõi tất cả để phát hiện các vòng lặp và khóa chết chặt chẽ. Hàm tôi muốn thực hiện là cho chuỗi giám sát để in ngăn xếp cuộc gọi từ chuỗi "treo" nhiều lần trước khi nó giết chết nó.

Tôi biết cách thực hiện điều này bằng cách yêu cầu chuỗi giám sát thực thi pstack (với hệ thống() hoặc bằng cách tắt). Nhưng tôi muốn có thể thực hiện chức năng này trong C. Có cách nào để làm điều này không?

Tôi biết cách tạo một chuỗi in ngăn xếp cuộc gọi OWN, bằng cách đi bộ ngăn xếp, rất hữu ích nếu nó chạm vào xác nhận, nhưng không phải cách thực hiện điều này cho một chuỗi khác trong cùng một quy trình.

Cảm ơn bạn đã được trợ giúp. NickB

Trả lời

3

Nếu bạn đang sử dụng gcc, bạn có thể sử dụng hàm sẵn có __builtin_return_address. void * __builtin_return_address (cấp int không dấu)

Hàm trả về địa chỉ của hàm mà hàm được gọi. tức là người gọi hàm.

Cấp độ chỉ định số lượng cấp độ. 0 có nghĩa là chức năng hiện tại 1 có nghĩa là người gọi, 2 có nghĩa là người gọi người gọi. Ví dụ sau sẽ cung cấp cách sử dụng. Bằng cách in các địa chỉ của hàm, ngăn xếp cuộc gọi có thể được xác định.

int calla() 
{ 
    printf("Inside calla\n"); 
    printf("A1=%x\n",__builtin_return_address (0)); 
    printf("A2=%x\n",__builtin_return_address (1)); 
    printf("A3=%x\n",__builtin_return_address (2)); 
} 
int callb() 
{ 
    printf("Inside callb\n"); 
    calle(); 
    printf("B1=%x\n",__builtin_return_address (0)); 
    printf("B2=%x\n",__builtin_return_address (1)); 
    printf("B3=%x\n",__builtin_return_address (2)); 
} 
int callc() 
{ 
    printf("Inside callc\n"); 
    printf("C1=%x\n",__builtin_return_address (0)); 
    printf("C2=%x\n",__builtin_return_address (1)); 
    printf("C3=%x\n",__builtin_return_address (2)); 
} 
int calld() 
{ 
    printf("Inside calld\n"); 
    printf("D1=%x\n",__builtin_return_address (0)); 
    printf("D2=%x\n",__builtin_return_address (1)); 
    printf("D3=%x\n",__builtin_return_address (2)); 
} 
int calle() 
{ 
    printf("Inside calle\n"); 
    printf("E1=%x\n",__builtin_return_address (0)); 
    printf("E2=%x\n",__builtin_return_address (1)); 
    printf("E3=%x\n",__builtin_return_address (2)); 
} 
main() 
{ 
    printf("Address of main=%x calla=%x callb=%x callc=%x calld=%x calle=%x\n",main,calla,callb,callc,calld,calle); 
    calla(); 
    callb(); 
    calld(); 
} 
+0

Nhưng làm cách nào để cho phép một luồng nhận được ngăn xếp cuộc gọi từ một chuỗi khác? – NickB

4

Bạn có thể sử dụng walkcontext() để chuyển ngăn xếp bằng cách sử dụng dladdr()/dladdr1() để chuyển đổi địa chỉ thành tên hàm. walkcontext() mất ucontext cho chuỗi. Nếu bạn không có sự hợp tác của chuỗi đó thì bạn có thể có được một ucontext cho chuỗi đó bằng cách dừng chuỗi (ví dụ: PCTWSTOP) và sau đó đọc địa chỉ của nó từ trường pr_oldcontext của cấu trúc lwpstatus cho chuỗi đó, thu được từ /proc/self/lstatus.