mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
Merge #6516 'log_callstack()'
This commit is contained in:
commit
d011facf45
@ -1,13 +1,20 @@
|
||||
Nvim core source
|
||||
================
|
||||
|
||||
Module-specific details are documented at the top of each module (e.g.
|
||||
terminal.c, screen.c).
|
||||
Module-specific details are documented at the top of each module (`terminal.c`,
|
||||
`screen.c`, ...).
|
||||
|
||||
See also `:help development`.
|
||||
See `:help development` for more guidelines.
|
||||
|
||||
UI Debugging
|
||||
------------
|
||||
Logs
|
||||
----
|
||||
|
||||
At `DEBUG_LOG_LEVEL`, all UI events are logged.
|
||||
Low-level log messages sink to `$NVIM_LOG_FILE`.
|
||||
|
||||
You can use `LOG_CALLSTACK()` anywhere in the source to log the current
|
||||
stacktrace. (Currently Linux-only.)
|
||||
|
||||
UI events are logged at level 0 (`DEBUG_LOG_LEVEL`).
|
||||
|
||||
rm -rf build/
|
||||
make CMAKE_EXTRA_FLAGS="-DMIN_LOG_LEVEL=0"
|
||||
|
@ -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, ...)
|
||||
|
@ -61,6 +61,10 @@
|
||||
__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
# define LOG_CALLSTACK() log_callstack(__func__, __LINE__)
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "log.h.generated.h"
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user