The cause of this is that the previous colleague's code had a memory pool where there was no recycling. That is, pop out of the object did not push back, the situation is difficult to reproduce, so in the pop print log, tracking is who called it, I think in the GDB debugging can be traced to the stack frame of the call, there must be a way to achieve. First search the internet for a bit, and no results! Fortunately, the amount of code is not many, only with the most stupid method, in each call pop place, pass the parameter, the call file, line number as a string into, print in the log! Busy, the total feeling must be a way to see the call stack frame, so in the QQ group asked the next, sure enough experience in this area of the students gave the answer!
The main is to return the called stack frame through backtrace, and then convert the address to a string by Backtrace_symbols. Finally, under Linux there is a tool addr2line can be converted to a file name and line number! Call Addr2line through the pipeline, and finally 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 frame7 * 8 * Get stack frame information through Backtrace,backtrace_symbols, then set up a pipeline to parse through Addr2line9 * Ten */ One Aint32_t Myexec (Const Char*cmd) - { -FILE *pp = Popen (cmd,"R");//Build Pipelines the if(!pp) - { - return-1; - }
+ Chartmp[1024x768];
while(Fgets (TMP,sizeof(TMP), pp)! =NULL) A { at if(Tmp[strlen (TMP)-1] =='\ n') - { -Tmp[strlen (TMP)-1] =' /';//Remove line break - } - -printf"%-30s", TMP); in } -printf"\ n"); toPclose (PP);//Close Pipe + return 0; - } the * voidParseName (Char* STR,Char*exename,Char*addr) $ {Panax Notoginseng Char*strtemp =str; - Char*addrtemp; the while(*strtemp! =NULL) + { A if(*strtemp = ='(') thememcpy (EXEName, str, strtemp-str); + - if(*strtemp = ='[') $Addrtemp =strtemp; $ - if(*strtemp = =']') -memcpy (addr, str + (ADDRTEMP-STR) +1, Strtemp-addrtemp-1); thestrtemp++; - }Wuyi } the - voidPrint_trace (void) Wu { - void*array[Ten]; About size_t size; $ Char**strings; - -Size = BackTrace (Array,Ten); -strings =Backtrace_symbols (array,size); A +printf"obtained%ZD stack frames.\n", size); the Charcmd[ -] = {0}; - Charexename[ -] = {0}; $ Charaddr[ -] = {0}; the for(size_t i =0; I < size;i++) the { thememset (CMD,0,sizeof(cmd)); thememset (EXEName,0,sizeof(EXEName)); -memset (addr,0,sizeof(addr)); in the ParseName (strings[i],exename,addr); theprintf"%-15s", addr); Aboutsprintf (CMD,"addr2line-f-E%s%s", exename,addr); the myexec (cmd); the } + } - the voidDummp_function (void)Bayi { the print_trace (); the } - - intMainintargcChar*argv[]) the { the dummp_function (); the return 0; the}
Compile:
gcc -wall-g backtrace. CPP -O BT
Perform:
./BT
Effect:
1Obtained5stack frames.2 0x4009e6_z11print_tracev/home/dyf/project/tool/backtrace.CPP: -3 0x400b71_z14dummp_functionv/home/dyf/project/tool/backtrace.CPP: the4 0x400b87Main/home/dyf/project/tool/backtrace.CPP: the5 0x7fa51f761af5?? ??:0 6 0x400769_start??:?
Basically to meet their own needs, function name also need to decorate a bit!
Trace function call under Linux, print stack frame