summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhei Makarov <serhei@serhei.io>2024-01-18 17:00:30 -0500
committerSerhei Makarov <serhei@serhei.io>2024-01-18 17:00:30 -0500
commitc54b5349dcd9dfdeca13a7f9d4e81a175d54f363 (patch)
tree76e0b00539464cc025900641d9413415bb95af7f
parent1ce5463b16f56e40cab183effd46b116ef03d7be (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.c30
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;
}