usage:
PrintStackTrace();
impl:
#define PrintStackTrace() \
{ \
static const int MAX_STACK_TRACE_CONTENT_SIZE = 65535; \
\
char __internal_szstacktrace_buffer[MAX_STACK_TRACE_CONTENT_SIZE]; \
CaptureStackTrace(__internal_szstacktrace_buffer, \
MAX_STACK_TRACE_CONTENT_SIZE); \
\
if (*__internal_szstacktrace_buffer != '\x0') \
{ \
printf(__internal_szstacktrace_buffer); \
LOG_ERROR("\n%s\n\n", __internal_szstacktrace_buffer); \
} \
}
#include <stdlib.h>
#include <unistd.h>
#include <cxxabi.h>
#include <execinfo.h>
int CaptureStackTrace(char* szStackTrace, int nStackTraceSize)
{
if (NULL == szStackTrace)
{
return ~0;
}
*szStackTrace = '\x0';
if (nStackTraceSize <= 0)
{
return 0;
}
static const int MAX_STACK_TRACE_SIZE = 100;
static const int MAX_STACK_TRACE_STRING = 260;
void* pStackFrame[MAX_STACK_TRACE_SIZE];
int nptrs = backtrace(pStackFrame, MAX_STACK_TRACE_SIZE);
char** pszStackBuffer = backtrace_symbols(pStackFrame, nptrs);
if (NULL == pszStackBuffer)
{
return 0;
}
for (int iStackFrameIndex = 1; iStackFrameIndex < nptrs; iStackFrameIndex++)
{
char szStackString[MAX_STACK_TRACE_STRING];
memcpy(szStackString, pszStackBuffer[iStackFrameIndex], MAX_STACK_TRACE_STRING);
int iStackStringLength = (int)::strlen(szStackString);
if (iStackStringLength <= 0)
{
continue;
}
char* pProcNameKey = (char*)::strchr(szStackString, '(');
*pProcNameKey++ = '\x0';
char* pProcEipAddr = (char*)::strchr(pProcNameKey, ')');
*pProcEipAddr++ = '\x0';
char szStackTempText[MAX_STACK_TRACE_STRING];
if (*pProcNameKey == '\x0')
{
sprintf(szStackTempText, "%s%s", szStackString, pProcEipAddr);
}
else
{
char* pSymbolName = (char*)abi::__cxa_demangle(pProcNameKey, NULL, NULL, NULL);
if (NULL == pSymbolName)
{
char szSymbolNameTemp[MAX_STACK_TRACE_STRING];
szSymbolNameTemp[0] = '\x0';
strcpy(szStackTempText, pProcNameKey);
char* pProcName = szStackTempText;
char* pProcAddr = (char*)strchr(pProcName, '+');
*pProcAddr++ = '\x0';
pSymbolName = (char*)abi::__cxa_demangle(pProcName, NULL, NULL, NULL);
if (NULL == pSymbolName)
{
pSymbolName = pProcName;
}
strcat(szSymbolNameTemp, pSymbolName);
if (NULL != pProcAddr && *pProcAddr != '\x0')
{
strcat(szSymbolNameTemp, "+");
strcat(szSymbolNameTemp, pProcAddr);
}
pSymbolName = szSymbolNameTemp;
}
sprintf(szStackTempText, "%s(%s)%s\r\n", szStackString, pSymbolName, pProcEipAddr);
}
strncat(szStackTrace, szStackTempText, (size_t)nStackTraceSize);
}
return nptrs;
}