Make backtrace resemble gdb bt
This commit is contained in:
parent
0242a3c188
commit
a12e59dbee
|
@ -205,11 +205,13 @@ static const Signaltype listofsignals[] = {
|
||||||
* \return size of array
|
* \return size of array
|
||||||
* */
|
* */
|
||||||
template<typename T, int size>
|
template<typename T, int size>
|
||||||
int GetArrayLength(T(&)[size])
|
int GetArrayLength(const T(&)[size])
|
||||||
{
|
{
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 32 vs. 64bit
|
||||||
|
#define ADDRESSDISPLAYLENGTH ((sizeof(long)==8)?12:8)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to print the callstack.
|
* Try to print the callstack.
|
||||||
|
@ -218,34 +220,53 @@ int GetArrayLength(T(&)[size])
|
||||||
static void print_stacktrace(FILE* f, bool demangling)
|
static void print_stacktrace(FILE* f, bool demangling)
|
||||||
{
|
{
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
void *array[50]= {0};
|
void *array[32]= {0}; // the less resources the better...
|
||||||
const int depth = backtrace(array, (int)GetArrayLength(array));
|
const int depth = backtrace(array, (int)GetArrayLength(array));
|
||||||
char **symbolstrings = backtrace_symbols(array, depth);
|
char **symbolstrings = backtrace_symbols(array, depth);
|
||||||
if (symbolstrings) {
|
if (symbolstrings) {
|
||||||
fprintf(f, "Callstack:\n");
|
fputs("Callstack:\n", f);
|
||||||
const int offset=3; // the first two entries are simply within our own exception handling code, third is within libc
|
const int offset=3; // the first two entries are simply within our own exception handling code, third is within libc
|
||||||
for (int i = offset; i < depth; ++i) {
|
for (int i = offset; i < depth; ++i) {
|
||||||
const char * const symbol = symbolstrings[i];
|
const char * const symbol = symbolstrings[i];
|
||||||
|
//fprintf(f, "\"%s\"\n", symbol);
|
||||||
char * realname = nullptr;
|
char * realname = nullptr;
|
||||||
const char * const firstBracket = strchr(symbol, '(');
|
const char * const firstBracketName = strchr(symbol, '(');
|
||||||
if (demangling && firstBracket) {
|
const char * const firstBracketAddress = strchr(symbol, '[');
|
||||||
const char * const plus = strchr(firstBracket, '+');
|
const char * const secondBracketAddress = strchr(firstBracketAddress, ']');
|
||||||
if (plus) {
|
const char * const beginAddress = firstBracketAddress+3;
|
||||||
|
const int addressLen = int(secondBracketAddress-beginAddress);
|
||||||
|
const int padLen = int(ADDRESSDISPLAYLENGTH-addressLen);
|
||||||
|
//fprintf(f, "AddressDisplayLength=%d addressLen=%d padLen=%d\n", ADDRESSDISPLAYLENGTH, addressLen, padLen);
|
||||||
|
if (demangling && firstBracketName) {
|
||||||
|
const char * const plus = strchr(firstBracketName, '+');
|
||||||
|
if (plus && (plus>(firstBracketName+1))) {
|
||||||
char input_buffer[512]= {0};
|
char input_buffer[512]= {0};
|
||||||
strncpy(input_buffer, firstBracket+1, plus-firstBracket-1);
|
strncpy(input_buffer, firstBracketName+1, plus-firstBracketName-1);
|
||||||
char output_buffer[1024]= {0};
|
char output_buffer[1024]= {0};
|
||||||
size_t length = GetArrayLength(output_buffer);
|
size_t length = GetArrayLength(output_buffer);
|
||||||
int status=0;
|
int status=0;
|
||||||
realname = abi::__cxa_demangle(input_buffer, output_buffer, &length, &status); // non-NULL on success
|
realname = abi::__cxa_demangle(input_buffer, output_buffer, &length, &status); // non-NULL on success
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fprintf(f, "#%d 0x",
|
||||||
fprintf(f, "%d. %s\n",
|
i-offset);
|
||||||
i-offset, (realname) ? realname : symbolstrings[i]);
|
if (padLen>0)
|
||||||
|
fprintf(f, "%0*d",
|
||||||
|
padLen, 0);
|
||||||
|
if (realname) {
|
||||||
|
fprintf(f, "%.*s in %s\n",
|
||||||
|
(int)(secondBracketAddress-firstBracketAddress-3), firstBracketAddress+3,
|
||||||
|
realname);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(f, "%.*s in %.*s\n",
|
||||||
|
(int)(secondBracketAddress-firstBracketAddress-3), firstBracketAddress+3,
|
||||||
|
(int)(firstBracketAddress-symbol), symbol);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(symbolstrings);
|
free(symbolstrings);
|
||||||
} else {
|
} else {
|
||||||
fprintf(f, "Callstack could not be obtained\n");
|
fputs("Callstack could not be obtained\n", f);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -269,26 +290,27 @@ static void CppcheckSignalHandler(int signo, siginfo_t * info, void * /*context*
|
||||||
{
|
{
|
||||||
const char * const signame=signal_name(signo);
|
const char * const signame=signal_name(signo);
|
||||||
bool bPrintCallstack=true;
|
bool bPrintCallstack=true;
|
||||||
|
FILE* f=stderr;
|
||||||
switch (signo) {
|
switch (signo) {
|
||||||
case SIGILL:
|
case SIGILL:
|
||||||
fprintf(stderr, "Internal error (caught signal %d=%s at 0x%p)\n",
|
fprintf(f, "Internal error (caught signal %d=%s at 0x%p)\n",
|
||||||
signo, signame, info->si_addr);
|
signo, signame, info->si_addr);
|
||||||
break;
|
break;
|
||||||
case SIGFPE:
|
case SIGFPE:
|
||||||
fprintf(stderr, "Internal error (caught signal %d=%s at 0x%p)\n",
|
fprintf(f, "Internal error (caught signal %d=%s at 0x%p)\n",
|
||||||
signo, signame, info->si_addr);
|
signo, signame, info->si_addr);
|
||||||
break;
|
break;
|
||||||
case SIGSEGV:
|
case SIGSEGV:
|
||||||
fprintf(stderr, "Internal error (caught signal %d=%s at 0x%p)\n",
|
fprintf(f, "Internal error (caught signal %d=%s at 0x%p)\n",
|
||||||
signo, signame, info->si_addr);
|
signo, signame, info->si_addr);
|
||||||
break;
|
break;
|
||||||
/*
|
/*
|
||||||
case SIGBUS:
|
case SIGBUS:
|
||||||
fprintf(stderr, "Internal error (caught signal %d=%s at 0x%p)\n",
|
fprintf(f, "Internal error (caught signal %d=%s at 0x%p)\n",
|
||||||
signo, signame, info->si_addr);
|
signo, signame, info->si_addr);
|
||||||
break;
|
break;
|
||||||
case SIGTRAP:
|
case SIGTRAP:
|
||||||
fprintf(stderr, "Internal error (caught signal %d=%s at 0x%p)\n",
|
fprintf(f, "Internal error (caught signal %d=%s at 0x%p)\n",
|
||||||
signo, signame, info->si_addr);
|
signo, signame, info->si_addr);
|
||||||
break;
|
break;
|
||||||
*/
|
*/
|
||||||
|
@ -296,13 +318,13 @@ static void CppcheckSignalHandler(int signo, siginfo_t * info, void * /*context*
|
||||||
bPrintCallstack=false;
|
bPrintCallstack=false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Internal error (caught signal %d)\n",
|
fprintf(f, "Internal error (caught signal %d)\n",
|
||||||
signo);
|
signo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bPrintCallstack) {
|
if (bPrintCallstack) {
|
||||||
print_stacktrace(stderr, false);
|
print_stacktrace(f, true);
|
||||||
fprintf(stderr, "Please report this to the cppcheck developers!\n");
|
fputs("\nPlease report this to the cppcheck developers!\n", f);
|
||||||
}
|
}
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue