Skip to content

Commit

Permalink
cg: allow non-fatal dt_cg_ctf_offsetof() failures
Browse files Browse the repository at this point in the history
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@oracle.com>
Reviewed-by: Eugene Loh <eugene.loh@oracle.com>
  • Loading branch information
kvanhees committed Jan 3, 2024
1 parent d630881 commit 46b9a63
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
22 changes: 14 additions & 8 deletions libdtrace/dt_cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1640,7 +1640,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;
Expand All @@ -1653,8 +1654,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)
if (ctf_member_info(ctfp, sym.dtt_type, membername, &ctm) == CTF_ERR) {
if (relaxed)
return -1;

longjmp(yypcb->pcb_jmpbuf, EDT_NOCTF);
}

if (sizep)
*sizep = ctf_type_size(ctfp, ctm.ctm_type);

Expand Down Expand Up @@ -1952,7 +1958,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);
Expand All @@ -1972,7 +1978,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);
Expand All @@ -1995,7 +2001,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);
Expand Down Expand Up @@ -4485,11 +4491,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)
Expand Down Expand Up @@ -4559,7 +4565,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]));
Expand Down
2 changes: 1 addition & 1 deletion libdtrace/dt_cg.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 46b9a63

Please sign in to comment.