Tracing function calls in Linux, printing stack frames, and linux tracing function calls
The cause is that my colleague's Code had a memory pool and there was no recycle. That is, if the Pop object is not pushed back, it is difficult to reproduce the situation. Therefore, the log is printed in Pop to track who called it, I want to track the called Stack frames in GDB debugging, so there must be methods to implement them. First, I searched the internet and there was no result! Fortunately, the amount of code is not much. We can only use the dumbest method. In each Pop call, We can pass parameters, pass the called file and row number as strings, and print them in the log! After the busy schedule, I always felt that there was a way to view the call stack frames. So I asked in the QQ group, and some people who had experience in this area gave me the answer!
The call stack frame is returned through backtrace, and the address is converted to a string through backtrace_symbols. Finally, there is a tool named addr2line in Linux that can convert the address to a file name and line number! Call addr2line through the pipeline, and print the call stack frame.
1 # include <execinfo. h> 2 # include <stdio. h> 3 # include <stdlib. h> 4 # include <string. h> 5/* 6 * print stack Frames 7*8 * Get stack frame information through backtrace and backtrace_symbols, and then establish a pipeline, use addr2line to parse 9*10 */11 12 int32_t myexec (const char * cmd) 13 {14 FILE * pp = popen (cmd, "r "); // create an MPS queue 15 if (! Pp) 16 {17 return-1; 18}
19 char tmp [1024];
While (fgets (tmp, sizeof (tmp), pp )! = NULL) 22 {23 if (tmp [strlen (tmp)-1] = '\ n') 24 {25 tmp [strlen (tmp) -1] = '\ 0'; // remove linefeed 26} 27 28 printf ("%-30 s", tmp); 29} 30 printf ("\ n "); 31 pclose (pp); // close the MPs queue 32 return 0; 33} 34 35 void parseName (char * str, char * exeName, char * addr) 36 {37 char * strTemp = str; 38 char * addrTemp; 39 while (* strTemp! = NULL) 40 {41 if (* strTemp = '(') 42 memcpy (exeName, str, strTemp-str); 43 44 if (* strTemp = '[') 45 addrTemp = strTemp; 46 47 if (* strTemp = ']') 48 memcpy (addr, str + (addrTemp-str) + 1, strTemp-addrTemp-1 ); 49 strTemp ++; 50} 51} 52 53 void print_trace (void) 54 {55 void * array [10]; 56 size_t size; 57 char ** strings; 58 59 size = backtrace (array, 10); 60 strings = backtrace_symbols (array, size); 61 62 printf ("Obtained % zd stack frames. \ n ", size); 63 char cmd [500] = {0}; 64 char exeName [100] = {0}; 65 char addr [100] = {0 }; 66 for (size_t I = 0; I <size; I ++) 67 {68 memset (cmd, 0, sizeof (cmd); 69 memset (exeName, 0, sizeof (exeName); 70 memset (addr, 0, sizeof (addr); 71 72 parseName (strings [I], exeName, addr ); 73 printf ("%-15 s", addr); 74 sprintf (cmd, "addr2line-f-e % s", exeName, addr ); 75 myexec (cmd); 76} 78} 79 80 void dummp_function (void) 81 {82 print_trace (); 83} 84 85 int main (int argc, char * argv []) 86 {87 dummp_function (); 88 return 0; 89}
Compile:
gcc -Wall -g backtrace.cpp -o bt
Run:
./bt
Effect:
1 Obtained 5 stack frames.2 0x4009e6 _Z11print_tracev /home/dyf/Project/Tool/backtrace.cpp:593 0x400b71 _Z14dummp_functionv /home/dyf/Project/Tool/backtrace.cpp:834 0x400b87 main /home/dyf/Project/Tool/backtrace.cpp:885 0x7fa51f761af5 ?? ??:0 6 0x400769 _start ??:?
The function name must be modified to meet your needs!