-/* $OpenBSD: db_trace.c,v 1.54 2021/09/04 07:13:14 jasper Exp $ */
+/* $OpenBSD: db_trace.c,v 1.55 2023/04/26 16:53:58 claudio Exp $ */
/* $NetBSD: db_trace.c,v 1.1 2003/04/26 18:39:27 fvdl Exp $ */
/*
}
}
+void
+stacktrace_save_utrace(struct stacktrace *st)
+{
+ struct callframe f, *frame, *lastframe;
+ struct pcb *pcb = curpcb;
+
+ st->st_count = 0;
+
+ if (pcb == NULL)
+ return;
+
+ frame = __builtin_frame_address(0);
+ KASSERT(INKERNEL(frame));
+ f = *frame;
+
+ while (st->st_count < STACKTRACE_MAX) {
+ if (f.f_retaddr != 0 && !INKERNEL(f.f_retaddr))
+ st->st_pc[st->st_count++] = f.f_retaddr;
+
+ lastframe = frame;
+ frame = f.f_frame;
+
+ if (frame == NULL)
+ break;
+ if (INKERNEL(f.f_retaddr)) {
+ if (frame <= lastframe)
+ break;
+ f = *frame;
+ continue;
+ }
+ if (!INKERNEL(lastframe) && frame <= lastframe)
+ break;
+ if (copyin(frame, &f, sizeof(f)) != 0)
+ break;
+ }
+}
+
vaddr_t
db_get_pc(struct trapframe *tf)
{
-/* $OpenBSD: db_trace.c,v 1.13 2021/07/09 20:59:51 jasper Exp $ */
+/* $OpenBSD: db_trace.c,v 1.14 2023/04/26 16:53:58 claudio Exp $ */
/* $NetBSD: db_trace.c,v 1.8 2003/01/17 22:28:48 thorpej Exp $ */
/*
break;
}
}
+
+void
+stacktrace_save_utrace(struct stacktrace *st)
+{
+ st->st_count = 0;
+}
-/* $OpenBSD: db_interface.c,v 1.48 2020/04/18 04:45:20 visa Exp $ */
+/* $OpenBSD: db_interface.c,v 1.49 2023/04/26 16:53:58 claudio Exp $ */
/*
* Copyright (c) 1999-2003 Michael Shalayeff
fp = (register_t *)fp[0];
}
}
+
+void
+stacktrace_save_utrace(struct stacktrace *st)
+{
+ st->st_count = 0;
+}
-/* $OpenBSD: db_trace.c,v 1.43 2023/01/30 10:49:05 jsg Exp $ */
+/* $OpenBSD: db_trace.c,v 1.44 2023/04/26 16:53:58 claudio Exp $ */
/* $NetBSD: db_trace.c,v 1.18 1996/05/03 19:42:01 christos Exp $ */
/*
}
}
+void
+stacktrace_save_utrace(struct stacktrace *st)
+{
+ struct callframe f, *frame, *lastframe;
+ struct pcb *pcb = curpcb;
+
+ st->st_count = 0;
+
+ if (pcb == NULL)
+ return;
+
+ frame = __builtin_frame_address(0);
+ KASSERT(INKERNEL(frame));
+ f = *frame;
+
+ while (st->st_count < STACKTRACE_MAX) {
+ if (f.f_retaddr != 0 && !INKERNEL(f.f_retaddr))
+ st->st_pc[st->st_count++] = f.f_retaddr;
+
+ lastframe = frame;
+ frame = f.f_frame;
+
+ if (frame == NULL)
+ break;
+ if (INKERNEL(f.f_retaddr)) {
+ if (frame <= lastframe)
+ break;
+ f = *frame;
+ continue;
+ }
+ if (!INKERNEL(lastframe) && frame <= lastframe)
+ break;
+ if (copyin(frame, &f, sizeof(f)) != 0)
+ break;
+ }
+}
+
vaddr_t
db_get_pc(struct trapframe *tf)
{
-/* $OpenBSD: trap.c,v 1.166 2023/02/11 23:07:27 deraadt Exp $ */
+/* $OpenBSD: trap.c,v 1.167 2023/04/26 16:53:59 claudio Exp $ */
/*
* Copyright (c) 1988 University of Utah.
sp += framesize;
}
}
+
+void
+stacktrace_save_utrace(struct stacktrace *st)
+{
+ st->st_count = 0;
+}
#endif
#undef VALID_ADDRESS
-/* $OpenBSD: db_trace.c,v 1.19 2022/02/07 22:28:15 gkoehler Exp $ */
+/* $OpenBSD: db_trace.c,v 1.20 2023/04/26 16:53:59 claudio Exp $ */
/* $NetBSD: db_trace.c,v 1.15 1996/02/22 23:23:41 gwr Exp $ */
/*
break;
}
}
+
+void
+stacktrace_save_utrace(struct stacktrace *st)
+{
+ st->st_count = 0;
+}
-/* $OpenBSD: db_trace.c,v 1.8 2022/01/28 18:37:40 gkoehler Exp $ */
+/* $OpenBSD: db_trace.c,v 1.9 2023/04/26 16:53:59 claudio Exp $ */
/* $NetBSD: db_trace.c,v 1.15 1996/02/22 23:23:41 gwr Exp $ */
/*
break;
}
}
+
+void
+stacktrace_save_utrace(struct stacktrace *st)
+{
+ st->st_count = 0;
+}
-/* $OpenBSD: db_trace.c,v 1.24 2022/10/25 06:00:34 guenther Exp $ */
+/* $OpenBSD: db_trace.c,v 1.25 2023/04/26 16:53:59 claudio Exp $ */
/* $NetBSD: db_trace.c,v 1.23 2001/07/10 06:06:16 eeh Exp $ */
/*
}
}
+void
+stacktrace_save_utrace(struct stacktrace *st)
+{
+ st->st_count = 0;
+}
+
void
db_dump_window(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
{
-/* $OpenBSD: dt_dev.c,v 1.25 2023/03/10 22:14:32 bluhm Exp $ */
+/* $OpenBSD: dt_dev.c,v 1.26 2023/04/26 16:53:59 claudio Exp $ */
/*
* Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
#include <sys/systm.h>
#include <sys/param.h>
#include <sys/device.h>
+#include <sys/exec_elf.h>
#include <sys/malloc.h>
#include <sys/proc.h>
+#include <sys/ptrace.h>
#include <dev/dt/dtvar.h>
void dt_ioctl_record_stop(struct dt_softc *);
int dt_ioctl_probe_enable(struct dt_softc *, struct dtioc_req *);
int dt_ioctl_probe_disable(struct dt_softc *, struct dtioc_req *);
+int dt_ioctl_get_auxbase(struct dt_softc *, struct dtioc_getaux *);
int dt_pcb_ring_copy(struct dt_pcb *, struct dt_evt *, size_t, uint64_t *);
case DTIOCRECORD:
case DTIOCPRBENABLE:
case DTIOCPRBDISABLE:
+ case DTIOCGETAUXBASE:
/* root only ioctl(2) */
break;
default:
case DTIOCPRBDISABLE:
error = dt_ioctl_probe_disable(sc, (struct dtioc_req *)addr);
break;
+ case DTIOCGETAUXBASE:
+ error = dt_ioctl_get_auxbase(sc, (struct dtioc_getaux *)addr);
+ break;
default:
KASSERT(0);
}
return 0;
}
+int
+dt_ioctl_get_auxbase(struct dt_softc *sc, struct dtioc_getaux *dtga)
+{
+ struct uio uio;
+ struct iovec iov;
+ struct process *pr;
+ struct proc *p = curproc;
+ AuxInfo auxv[ELF_AUX_ENTRIES];
+ int i, error;
+
+ dtga->dtga_auxbase = 0;
+
+ if ((pr = prfind(dtga->dtga_pid)) == NULL)
+ return ESRCH;
+
+ iov.iov_base = auxv;
+ iov.iov_len = sizeof(auxv);
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = pr->ps_auxinfo;
+ uio.uio_resid = sizeof(auxv);
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_procp = p;
+ uio.uio_rw = UIO_READ;
+
+ error = process_domem(p, pr, &uio, PT_READ_D);
+ if (error)
+ return error;
+
+ for (i = 0; i < ELF_AUX_ENTRIES; i++)
+ if (auxv[i].au_id == AUX_base)
+ dtga->dtga_auxbase = auxv[i].au_v;
+
+ return 0;
+}
+
struct dt_probe *
dt_dev_alloc_probe(const char *func, const char *name, struct dt_provider *dtpv)
{
if (ISSET(dp->dp_evtflags, DTEVT_EXECNAME))
strlcpy(dtev->dtev_comm, p->p_p->ps_comm, sizeof(dtev->dtev_comm));
- if (ISSET(dp->dp_evtflags, DTEVT_KSTACK|DTEVT_USTACK)) {
+ if (ISSET(dp->dp_evtflags, DTEVT_KSTACK)) {
if (profiling)
stacktrace_save_at(&dtev->dtev_kstack, DT_FA_PROFILE);
else
stacktrace_save_at(&dtev->dtev_kstack, DT_FA_STATIC);
}
+ if (ISSET(dp->dp_evtflags, DTEVT_USTACK))
+ stacktrace_save_utrace(&dtev->dtev_ustack);
return dtev;
}
-/* $OpenBSD: dt_prov_profile.c,v 1.4 2021/09/03 16:45:45 jasper Exp $ */
+/* $OpenBSD: dt_prov_profile.c,v 1.5 2023/04/26 16:53:59 claudio Exp $ */
/*
* Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
struct dt_probe *dtpp_interval; /* global periodic probe */
/* Flags that make sense for this provider */
-#define DTEVT_PROV_PROFILE DTEVT_KSTACK
+#define DTEVT_PROV_PROFILE DTEVT_COMMON
int dt_prov_profile_alloc(struct dt_probe *, struct dt_softc *,
struct dt_pcb_list *, struct dtioc_req *);
-/* $OpenBSD: dtvar.h,v 1.16 2023/04/10 04:21:20 jsg Exp $ */
+/* $OpenBSD: dtvar.h,v 1.17 2023/04/26 16:53:59 claudio Exp $ */
/*
* Copyright (c) 2019 Martin Pieuchot <mpi@openbsd.org>
* Recorded if the corresponding flag is set.
*/
struct stacktrace dtev_kstack; /* kernel stack frame */
+ struct stacktrace dtev_ustack; /* userland stack frame */
char dtev_comm[DTMAXCOMLEN]; /* current pr. name */
union {
register_t E_entry[DTMAXFUNCARGS];
"\002USTACK" \
"\003KSTACK" \
"\004FUNCARGS" \
- "\005RETVAL" \
/*
* Each PCB can have a filter attached to itself. A filter do not
uint64_t dtst_dropevt; /* events dropped */
};
+struct dtioc_getaux {
+ pid_t dtga_pid; /* process to inspect */
+ unsigned long dtga_auxbase; /* AUX_base value */
+};
+
#define DTIOCGPLIST _IOWR('D', 1, struct dtioc_probe)
#define DTIOCGSTATS _IOR('D', 2, struct dtioc_stat)
#define DTIOCRECORD _IOW('D', 3, int)
#define DTIOCPRBENABLE _IOW('D', 4, struct dtioc_req)
#define DTIOCPRBDISABLE _IOW('D', 5, struct dtioc_req)
#define DTIOCGARGS _IOWR('D', 6, struct dtioc_arg)
+#define DTIOCGETAUXBASE _IOWR('D', 7, struct dtioc_getaux)
#ifdef _KERNEL
-/* $OpenBSD: stacktrace.h,v 1.3 2020/04/18 04:45:20 visa Exp $ */
+/* $OpenBSD: stacktrace.h,v 1.4 2023/04/26 16:53:59 claudio Exp $ */
/*
* Copyright (c) 2017 Visa Hankala
#ifdef _KERNEL
void stacktrace_print(struct stacktrace *, int (*)(const char *, ...));
void stacktrace_save_at(struct stacktrace *, unsigned int);
+void stacktrace_save_utrace(struct stacktrace *);
static inline void
stacktrace_save(struct stacktrace *st)