log: log_callstack()

This commit is contained in:
Justin M. Keyes
2017-07-23 17:00:30 +02:00
parent 5fc775e2ef
commit eb2473e9ea
3 changed files with 61 additions and 27 deletions

View File

@@ -173,6 +173,53 @@ FILE *open_log_file(void)
return stderr;
}
#if defined(__linux__)
# include <execinfo.h>
void log_callstack(const char *const func_name, const int line_num)
{
void *trace[100];
int trace_size = backtrace(trace, ARRAY_SIZE(trace));
char exepath[MAXPATHL] = { 0 };
size_t exepathlen = MAXPATHL;
if (os_exepath(exepath, &exepathlen) != 0) {
abort();
}
assert(24 + exepathlen < IOSIZE); // Must fit in `cmdbuf` below.
do_log(DEBUG_LOG_LEVEL, func_name, line_num, true, "trace:");
char cmdbuf[IOSIZE + (20 * ARRAY_SIZE(trace))];
snprintf(cmdbuf, sizeof(cmdbuf), "addr2line -e %s -f -p", exepath);
for (int i = 1; i < trace_size; i++) {
char buf[20]; // 64-bit pointer 0xNNNNNNNNNNNNNNNN with leading space.
snprintf(buf, sizeof(buf), " %p", trace[i]);
xstrlcat(cmdbuf, buf, sizeof(cmdbuf));
}
// Now we have a command string like:
// addr2line -e /path/to/exe -f -p 0x123 0x456 ...
log_lock();
FILE *log_file = open_log_file();
if (log_file == NULL) {
goto end;
}
FILE *fp = popen(cmdbuf, "r");
char linebuf[IOSIZE];
while (fgets(linebuf, sizeof(linebuf) - 1, fp) != NULL) {
fprintf(log_file, " %s", linebuf);
}
pclose(fp);
if (log_file != stderr && log_file != stdout) {
fclose(log_file);
}
end:
log_unlock();
}
#endif
static bool do_log_to_file(FILE *log_file, int log_level,
const char *func_name, int line_num, bool eol,
const char* fmt, ...)