[DTrace-devel] [PATCH] cg: allow non-fatal dt_cg_ctf_offsetof() failures
Kris Van Hees
kris.van.hees at oracle.com
Wed Nov 22 20:57:08 UTC 2023
Lookup failures for a struct member should not always be fatal. There
is a need to be able to try again (e.g. to support the case where a
struct member was renamed between two kernel versions).
Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
---
libdtrace/dt_cg.c | 24 +++++++++++++++---------
libdtrace/dt_cg.h | 2 +-
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index f86e2bd1..843ac165 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -1637,7 +1637,8 @@ dt_cg_clsflags(dt_pcb_t *pcb, dtrace_actkind_t kind, const dt_node_t *dnp)
* Optionally, also get member size.
*/
int
-dt_cg_ctf_offsetof(const char *structname, const char *membername, size_t *sizep)
+dt_cg_ctf_offsetof(const char *structname, const char *membername,
+ size_t *sizep, int relaxed)
{
dtrace_typeinfo_t sym;
ctf_file_t *ctfp;
@@ -1650,8 +1651,13 @@ dt_cg_ctf_offsetof(const char *structname, const char *membername, size_t *sizep
ctfp = sym.dtt_ctfp;
if (!ctfp) /* Should never happen. */
longjmp(yypcb->pcb_jmpbuf, EDT_NOCTF);
- if (ctf_member_info(ctfp, sym.dtt_type, membername, &ctm) == CTF_ERR)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOCTF);
+ if (ctf_member_info(ctfp, sym.dtt_type, membername, &ctm) == CTF_ERR) {
+ if (relaxed)
+ return -1;
+ else
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOCTF);
+ }
+
if (sizep)
*sizep = ctf_type_size(ctfp, ctm.ctm_type);
@@ -1949,7 +1955,7 @@ dt_cg_act_pcap(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
*/
dt_cg_node(addr, dlp, drp);
- off = dt_cg_ctf_offsetof("struct sk_buff", "len", NULL);
+ off = dt_cg_ctf_offsetof("struct sk_buff", "len", NULL, 0);
if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
@@ -1969,7 +1975,7 @@ dt_cg_act_pcap(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
emit(dlp, BPF_LOAD(BPF_DW, lenreg, BPF_REG_FP, DT_STK_SP));
emit(dlp, BPF_LOAD(BPF_W, lenreg, lenreg, 0));
- off = dt_cg_ctf_offsetof("struct sk_buff", "data_len", NULL);
+ off = dt_cg_ctf_offsetof("struct sk_buff", "data_len", NULL, 0);
if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
@@ -1992,7 +1998,7 @@ dt_cg_act_pcap(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
BPF_STORE(BPF_W, BPF_REG_9, size_off, lenreg));
/* Copy the packet data to the output buffer. */
- off = dt_cg_ctf_offsetof("struct sk_buff", "data", NULL);
+ off = dt_cg_ctf_offsetof("struct sk_buff", "data", NULL, 0);
if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
@@ -4434,11 +4440,11 @@ dt_cg_uregs(unsigned int idx, dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp
char *memnames[] = { "ds", "es", "fsbase", "gsbase", "trap_nr" };
/* Look up task->thread offset. */
- offset = dt_cg_ctf_offsetof("struct task_struct", "thread", NULL);
+ offset = dt_cg_ctf_offsetof("struct task_struct", "thread", NULL, 0);
/* Add the thread->member offset. */
offset += dt_cg_ctf_offsetof("struct thread_struct",
- memnames[idx - 21], &size);
+ memnames[idx - 21], &size, 0);
/* Get task. */
if (dt_regset_xalloc_args(drp) == -1)
@@ -4508,7 +4514,7 @@ dt_cg_uregs(unsigned int idx, dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp
/* Copy contents at task->stack to %fp+DT_STK_SP (scratch space). */
emit(dlp, BPF_MOV_REG(BPF_REG_3, BPF_REG_0));
emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_3,
- dt_cg_ctf_offsetof("struct task_struct", "stack", NULL)));
+ dt_cg_ctf_offsetof("struct task_struct", "stack", NULL, 0)));
emit(dlp, BPF_MOV_IMM(BPF_REG_2, sizeof(uint64_t)));
emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_FP, DT_STK_SP));
emit(dlp, BPF_CALL_HELPER(dtp->dt_bpfhelper[BPF_FUNC_probe_read_kernel]));
diff --git a/libdtrace/dt_cg.h b/libdtrace/dt_cg.h
index 6fdc1183..700a83ed 100644
--- a/libdtrace/dt_cg.h
+++ b/libdtrace/dt_cg.h
@@ -36,7 +36,7 @@ extern void dt_cg_tramp_epilogue(dt_pcb_t *pcb);
extern void dt_cg_tramp_epilogue_advance(dt_pcb_t *pcb, dt_activity_t act);
extern void dt_cg_tramp_error(dt_pcb_t *pcb);
extern int dt_cg_ctf_offsetof(const char *structname, const char *membername,
- size_t *sizep);
+ size_t *sizep, int relaxed);
extern uint_t dt_cg_ldsize(dt_node_t *dnp, ctf_file_t *ctfp, ctf_id_t type,
ssize_t *ret_size);
--
2.39.3
More information about the DTrace-devel
mailing list