Take dump_stacktrace into use

MaxScale and tests now both use the same code to dump stacktraces.
This commit is contained in:
Markus Mäkelä
2018-06-19 15:11:23 +03:00
parent c32e6a7c3f
commit 3d8f946e19
3 changed files with 12 additions and 115 deletions

View File

@ -92,7 +92,7 @@ if (HAVE_LIBDL)
target_link_libraries(maxscale-common dl)
endif()
add_dependencies(maxscale-common pcre2 connector-c libmicrohttpd jansson)
add_dependencies(maxscale-common pcre2 connector-c libmicrohttpd jansson maxutils)
set_target_properties(maxscale-common PROPERTIES VERSION "1.0.0")
install_module(maxscale-common core)

View File

@ -37,6 +37,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <maxbase/stacktrace.hh>
#include <maxscale/alloc.h>
#include <maxscale/adminusers.h>
#include <maxscale/dcb.h>
@ -383,96 +384,6 @@ volatile sig_atomic_t fatal_handling = 0;
static int signal_set(int sig, void (*handler)(int));
void get_command_output(char* output, size_t size, const char* format, ...)
{
va_list valist;
va_start(valist, format);
int cmd_len = vsnprintf(NULL, 0, format, valist);
va_end(valist);
va_start(valist, format);
char cmd[cmd_len + 1];
vsnprintf(cmd, cmd_len + 1, format, valist);
va_end(valist);
*output = '\0';
FILE* file = popen(cmd, "r");
if (file)
{
size_t nread = fread(output, 1, size, file);
nread = nread < size ? nread : size - 1;
output[nread--] = '\0';
// Trim trailing newlines
while (output + nread > output && output[nread] == '\n')
{
output[nread--] = '\0';
}
pclose(file);
}
}
void extract_file_and_line(const char* symbols, char* cmd, size_t size)
{
const char* filename_end = strchr(symbols, '(');
const char* symname_end = strchr(symbols, ')');
if (filename_end && symname_end)
{
// This appears to be a symbol in a library
char filename[PATH_MAX + 1];
char symname[512];
char offset[512];
snprintf(filename, sizeof(filename), "%.*s", (int)(filename_end - symbols), symbols);
const char* symname_start = filename_end + 1;
if (*symname_start != '+')
{
// We have a string form symbol name and an offset, we need to
// extract the symbol address
const char* addr_offset = symname_start;
while (addr_offset < symname_end && *addr_offset != '+')
{
addr_offset++;
}
snprintf(symname, sizeof(symname), "%.*s", (int)(addr_offset - symname_start), symname_start);
if (addr_offset < symname_end && *addr_offset == '+')
{
addr_offset++;
}
snprintf(offset, sizeof(offset), "%.*s", (int)(symname_end - addr_offset), addr_offset);
// Get the hexadecimal address of the symbol
get_command_output(cmd, size,
"nm %s |grep ' %s$'|sed -e 's/ .*//' -e 's/^/0x/'",
filename, symname);
long long symaddr = strtoll(cmd, NULL, 16);
long long offsetaddr = strtoll(offset, NULL, 16);
// Calculate the file and line now that we have the raw offset into
// the library
get_command_output(cmd, size,
"addr2line -e %s 0x%x",
filename, symaddr + offsetaddr);
}
else
{
// Raw offset into library
symname_start++;
snprintf(symname, sizeof(symname), "%.*s", (int)(symname_end - symname_start), symname_start);
get_command_output(cmd, size, "addr2line -e %s %s", filename, symname);
}
}
}
static void
sigfatal_handler(int i)
{
@ -487,33 +398,18 @@ sigfatal_handler(int i)
"Attempting backtrace.\n", i);
fprintf(stderr, "Commit ID: %s System name: %s Release string: %s\n\n",
maxscale_commit, cnf->sysname, cnf->release_string);
#ifdef HAVE_GLIBC
void *addrs[128];
int count = backtrace(addrs, 128);
// First print the stack trace to stderr as malloc is likely broken
backtrace_symbols_fd(addrs, count, STDERR_FILENO);
MXS_ALERT("Fatal: MaxScale " MAXSCALE_VERSION " received fatal signal %d. "
"Attempting backtrace.", i);
MXS_ALERT("Commit ID: %s System name: %s "
"Release string: %s",
MXS_ALERT("Commit ID: %s System name: %s Release string: %s",
maxscale_commit, cnf->sysname, cnf->release_string);
// Then see if we can log them
char** symbols = backtrace_symbols(addrs, count);
if (symbols)
auto cb = [](const char* symbol, const char* cmd)
{
for (int n = 0; n < count; n++)
{
char cmd[PATH_MAX + 1024] = "<not found>";
extract_file_and_line(symbols[n], cmd, sizeof(cmd));
MXS_ALERT(" %s: %s", symbols[n], cmd);
}
MXS_FREE(symbols);
}
#endif
MXS_ALERT(" %s: %s", symbol, cmd);
};
mxb::dump_stacktrace(cb);
mxs_log_flush_sync();