[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