diff options
author | Serhei Makarov <serhei@serhei.io> | 2024-01-18 17:00:30 -0500 |
---|---|---|
committer | Serhei Makarov <serhei@serhei.io> | 2024-01-18 17:00:30 -0500 |
commit | c54b5349dcd9dfdeca13a7f9d4e81a175d54f363 (patch) | |
tree | 76e0b00539464cc025900641d9413415bb95af7f | |
parent | 1ce5463b16f56e40cab183effd46b116ef03d7be (diff) |
eu-stacktrace WIP: fix sysprof_init_dwfl
Some of the data was not being reset properly on a new sample.
-rw-r--r-- | src/stacktrace.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/src/stacktrace.c b/src/stacktrace.c index 2b03236c..3c6ed650 100644 --- a/src/stacktrace.c +++ b/src/stacktrace.c @@ -78,7 +78,7 @@ #include <fcntl.h> /* #include ELFUTILS_HEADER(dwfl) */ #include "../libdwfl/libdwflP.h" -/* XXX: Private header needed for sysprof_find_procfile. */ +/* XXX: Private header needed for sysprof_find_procfile, sysprof_init_dwfl. */ #include <system.h> @@ -647,7 +647,7 @@ sysprof_find_procfile (Dwfl *dwfl, pid_t *pid, Elf **elf, int *elf_fd) { err = errno; fail: - if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR) + if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR) /* XXX requires libdwflP.h */ { errno = err; /* TODO: __libdwfl_canon_error not exported from libdwfl */ @@ -850,11 +850,16 @@ sysprof_init_dwfl (struct sysprof_unwind_info *sui, SysprofCaptureUserRegs *regs) { pid_t pid = ev->frame.pid; - (void)sui; Dwfl *dwfl = pid_find_dwfl(pid); + struct __sample_arg *sample_arg; + bool cached = false; if (dwfl != NULL) - return dwfl; + { + sample_arg = dwfl->process->callbacks_arg; /* XXX requires libdwflP.h */ + cached = true; + goto reuse; + } dwfl = dwfl_begin (&sample_callbacks); int err = dwfl_linux_proc_report (dwfl, pid); @@ -887,10 +892,7 @@ sysprof_init_dwfl (struct sysprof_unwind_info *sui, return NULL; } - if (regs->n_regs != 2) /* TODO: for now, handling only sp,pc */ - return NULL; - - struct __sample_arg *sample_arg = malloc (sizeof *sample_arg); + sample_arg = malloc (sizeof *sample_arg); if (sample_arg == NULL) { if (elf != NULL) { @@ -900,6 +902,13 @@ sysprof_init_dwfl (struct sysprof_unwind_info *sui, free (sample_arg); return NULL; } + + reuse: + if (regs->n_regs != 2) /* TODO: for now, handling only sp,pc */ + { + free (sample_arg); /* TODO move earlier */ + return NULL; + } sample_arg->tid = ev->tid; sample_arg->size = ev->size; sample_arg->data = (uint8_t *)&ev->data; @@ -911,7 +920,7 @@ sysprof_init_dwfl (struct sysprof_unwind_info *sui, fprintf(stderr, "DEBUG sysprof_init_dwfl pid %lld: initial size=%ld sp=%lx pc=%lx\n", (long long) pid, sample_arg->size, sample_arg->sp, sample_arg->pc); #endif - if (! dwfl_attach_state (dwfl, elf, pid, &sample_thread_callbacks, sample_arg)) + if (!cached && ! dwfl_attach_state (dwfl, elf, pid, &sample_thread_callbacks, sample_arg)) { #ifdef DEBUG fprintf(stderr, "DEBUG dwfl_attach_state pid %lld: %s\n", @@ -922,7 +931,8 @@ sysprof_init_dwfl (struct sysprof_unwind_info *sui, free (sample_arg); return NULL; } - pid_store_dwfl (pid, dwfl); + if (!cached) + pid_store_dwfl (pid, dwfl); return dwfl; } |