Get call stack from any thread inside C

In C on Solaris 10, I would like to get a call stack from an arbitrary thread in a process.

I have many worker threads and one thread that controls them all to detect tight loops and dead ends. The function that I would like to implement is for the monitoring thread to print a call stack from the freezing thread several times before it kills it.

I know how to implement this if the monitoring thread is executing pstack (using system () or forking). But I would like to be able to implement this function in C. Is there a way to do this?

I know how to get a thread to print its OWN call stack by going through the stack, which is useful if it falls into assert, but not how to do it for another thread within the same process.

Thanks for any help. Nickb

+6
c stack multithreading solaris call
source share
2 answers

You can use walkcontext() to traverse the stack, using dladdr() / dladdr1() to convert addresses to function names. walkcontext() accepts ucontext for the stream. If you do not cooperate with this stream, you can get ucontext for it by stopping the stream (for example, PCTWSTOP ) and then reading its address from the pr_oldcontext field of the pr_oldcontext structure for this stream obtained from /proc/self/lstatus .

+4
source share

If you use gcc, you can use the __builtin_return_address built-in function. void * __builtin_return_address (unsigned int level)

The function returns the address of the function from which the function is called. that is, the calling function.

Level determines the number of levels. 0 means the current function 1 means the caller, 2 means the caller. The following example will provide use. By selecting function addresses, you can define a call stack.

 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(); } 
+3
source share

All Articles