mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-21 22:28:41 -04:00
MINOR: debug: opportunistically load libthread_db.so.1 with set-dumpable=libs
When loading libs into the core dump, let's also try to load libthread_db.so.1 that gdb usually requires. It can significantly help decoding the threads for systems which require it, and the file is quite small. It can appear at a few different locations and is generally next to libpthread.so, or alternately libc, so we first look where we found them, and fall back to a few other common places. The file is really small, a few tens of kB usually.
This commit is contained in:
parent
e07c9ee575
commit
b93137ce67
1 changed files with 32 additions and 1 deletions
33
src/tools.c
33
src/tools.c
|
|
@ -6038,6 +6038,7 @@ struct dl_collect_ctx {
|
|||
size_t size;
|
||||
char *prefix;
|
||||
int pos;
|
||||
char libpthread_path[PATH_MAX];
|
||||
};
|
||||
|
||||
static int dl_collect_libs_cb(struct dl_phdr_info *info, size_t size, void *data)
|
||||
|
|
@ -6066,6 +6067,18 @@ static int dl_collect_libs_cb(struct dl_phdr_info *info, size_t size, void *data
|
|||
load_file_into_tar(&ctx->storage, &ctx->size, ctx->prefix, dbg, NULL, "haproxy-libs-dump");
|
||||
}
|
||||
|
||||
/* check if we're loading libpthread or libc, and if so, keep a copy of its path */
|
||||
if (!ctx->libpthread_path[0]) {
|
||||
const char *basename = strrchr(fname, '/');
|
||||
|
||||
if (basename &&
|
||||
(strncmp(basename, "/libpthread.so", 14) == 0 ||
|
||||
strncmp(basename, "/libc.so", 8) == 0)) {
|
||||
/* Note: this will trim the trailing slash */
|
||||
strncpy(ctx->libpthread_path, fname,
|
||||
MIN(basename - fname, sizeof(ctx->libpthread_path)));
|
||||
}
|
||||
}
|
||||
leave:
|
||||
/* increment the object's number */
|
||||
ctx->pos++;
|
||||
|
|
@ -6075,11 +6088,13 @@ static int dl_collect_libs_cb(struct dl_phdr_info *info, size_t size, void *data
|
|||
/* dumps lib names and optionally address ranges */
|
||||
void collect_libs(void)
|
||||
{
|
||||
struct dl_collect_ctx ctx = { .storage = NULL, .size = 0, .pos = 0 };
|
||||
struct dl_collect_ctx ctx = { .storage = NULL, .size = 0, .pos = 0, .libpthread_path = "" };
|
||||
const char *libthr_paths[] = { ctx.libpthread_path, "/usr/lib64", "/lib64", "/usr/lib", "/lib", NULL };
|
||||
ulong pagesize = sysconf(_SC_PAGESIZE);
|
||||
char dir_name[16];
|
||||
size_t new_size;
|
||||
void *page;
|
||||
int i;
|
||||
|
||||
/* prepend a directory named after the starting pid */
|
||||
snprintf(dir_name, sizeof(dir_name), "core-%u", getpid());
|
||||
|
|
@ -6088,6 +6103,22 @@ void collect_libs(void)
|
|||
/* callbacks will (re-)allocate ctx->storage */
|
||||
dl_iterate_phdr(dl_collect_libs_cb, &ctx);
|
||||
|
||||
/* if we've found libpthread, there's likely a libthread_db.so.1 next
|
||||
* to it, for use with gdb, and ctx.libpthread_path will point to it,
|
||||
* and with it, libthr_paths[0]. Otherwise we search in a few other
|
||||
* common paths.
|
||||
*/
|
||||
for (i = 0; libthr_paths[i]; i++) {
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (!*libthr_paths[i])
|
||||
continue;
|
||||
|
||||
snprintf(path, sizeof(path), "%s/libthread_db.so.1", DISGUISE(libthr_paths[i]));
|
||||
if (load_file_into_tar(&ctx.storage, &ctx.size, ctx.prefix, path, NULL, "haproxy-libs-dump") == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* now that the archive is complete, we need to close it by appending
|
||||
* two empty 512B blocks. We'll also place it aligned in an isolated
|
||||
* mapped area so that it uses its own segment in a core dump for
|
||||
|
|
|
|||
Loading…
Reference in a new issue