gpt4 book ai didi

c++ - 如何在没有 gdb 的情况下获取崩溃函数或死锁的回溯(调用堆栈)?

转载 作者:太空宇宙 更新时间:2023-11-04 05:02:16 24 4
gpt4 key购买 nike

我试图找到一个随机错误(我没有特定的情况),它会导致我的 C++ Linux 程序崩溃。我知道如果我使用 gdb 并且应用程序崩溃,我可以使用“bt”命令并获取崩溃的调用堆栈。我无法使用 gdb(逻辑问题)并且崩溃是随机的。

  1. Linux 中有没有一种方法可以在不使用 gdb 的情况下获取崩溃的 C++ 应用程序的调用堆栈?
  2. 有没有办法知道是否存在死锁(使用和不使用 gdb)?

谢谢

最佳答案

您可以使用 __cxa_demangle() 来获取堆栈消息,如下所示:

string OException::strGetSourceCode(const string& p_strFileName,const string& p_strAddressInfo) throw()
{
char l_acBuf[CBUFFLEN] = {0};
char l_acAddress[CBUFFLEN] = {0};
memcpy(l_acBuf, p_strAddressInfo.c_str(), p_strAddressInfo.length());
if(sscanf(l_acBuf,"%*[^[][0x%[^]]", l_acAddress)==1)
{
FILE *l_pFp;
stringstream l_ss;
if(p_strFileName.find(".so")!=string::npos)
{
unsigned int l_lOffset=strtol(l_acAddress,NULL,16)-strtol(strGetBaseAddress(p_strFileName).c_str(),NULL,16);
snprintf(l_acAddress,sizeof(l_acAddress),"%x",l_lOffset);
}

l_ss << "addr2line 0x" << l_acAddress<< " -i -e " << p_strFileName;
if((l_pFp = popen(l_ss.str().c_str(), "r"))) {
if(fgets(l_acAddress, CBUFFLEN, l_pFp) != NULL) {
l_acAddress[strlen(l_acAddress) - 1] = '\0';
}
}
return l_acAddress;
}
return l_acBuf;
}
string OException::strGetBaseAddress(const string& p_soFileName) throw()
{
int l_iPid=getpid();
char l_acFileName[CBUFFLEN]={0};
char l_acCmd[CBUFFLEN]={0};
#ifdef __linux__
snprintf(l_acFileName,sizeof(l_acFileName),"/proc/%d/maps",l_iPid);
snprintf(l_acCmd,sizeof(l_acCmd),"grep %s %s | head -1 | awk -F- \'{print $1}\'",p_soFileName.c_str(),l_acFileName);
#endif
FILE* l_pFile=popen(l_acCmd,"r");
char l_acBaseAddress[CBUFFLEN]={0};
if(fgets(l_acBaseAddress,CBUFFLEN,l_pFile)!=NULL)
return l_acBaseAddress;
return "";
}
void OException::vSaveStackTrace() throw()
{
void* l_acBuffer[CBUFFLEN];
int l_iStackCount = ::backtrace(l_acBuffer, CBUFFLEN); //get the trace list //cout<<"l_iStackCount="<<l_iStackCount<<endl;
//translate trace message
char** l_pacStackResult = ::backtrace_symbols(l_acBuffer, l_iStackCount);
if (l_pacStackResult)
{
string l_strFormat="";
string l_binFile="";
m_sStack="==============BackTrace===========\n";
for (int i = 0;i<l_iStackCount-1; i++)//
{

l_binFile=l_pacStackResult[i];//get the exe filename
l_binFile=l_binFile.substr(0,l_binFile.find('(',0));
m_sStack.append(l_strFormat+"["+l_binFile+"]:"+strDemangle(l_pacStackResult[i])+"-->");
m_sStack.append(strGetSourceCode(l_binFile,l_pacStackResult[i]));
m_sStack.push_back('\n');
l_strFormat+=" ";
}
free(l_pacStackResult);
}

}
string OException::strDemangle(const char* p_acSymbol) throw()
{
size_t size;
int status;
char l_acTmp[CBUFFLEN]={0};
char* l_pDemangled;
//first, try to demangle a c++ name
if (1 == sscanf(p_acSymbol, "%*[^(](%256[^)+]", l_acTmp)) {
if (NULL != (l_pDemangled = abi::__cxa_demangle(l_acTmp, NULL, &size, &status))) {
string l_strResult(l_pDemangled);
free(l_pDemangled);
return l_strResult;
}
}
//if that didn't work, try to get a regular c p_acSymbol
if (1 == sscanf(p_acSymbol, "%256s", l_acTmp)) {
return l_acTmp;
}
return p_acSymbol;
}

关于c++ - 如何在没有 gdb 的情况下获取崩溃函数或死锁的回溯(调用堆栈)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29398133/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com