Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retsnoop improvements for LBR, stitched stacks, and interim stacks #72

Merged
merged 9 commits into from
Aug 30, 2024
4 changes: 4 additions & 0 deletions src/env.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ static const struct argp_option opts[] = {
"Only emit stacks that took at least a given amount of milliseconds" },
{ "success-stacks", 'S', "VALUE", OPTION_ARG_OPTIONAL,
"Specify whether emitting non-erroring (successful) call stacks is allowed" },
{ "interim-stacks", 'I', NULL, 0, "Emit incomplete interim call stacks" },
{ "allow-errors", 'x', "ERROR", 0,
"Record stacks only with specified errors (e.g., EINVAL, EFAULT, etc.; also accepts special 'any' value)" },
{ "deny-errors", 'X', "ERROR", 0, "Ignore stacks that have specified errors" },
Expand Down Expand Up @@ -614,6 +615,9 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
}
env.emit_success_stacks = val;
break;
case 'I':
env.emit_interim_stacks = true;
break;
case 'M':
if (env.attach_mode != ATTACH_DEFAULT) {
fprintf(stderr, "Can't specify -M, -K or -F simultaneously, pick one.\n");
Expand Down
1 change: 1 addition & 0 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ struct env {
* -1 forces unsuccessful stacks only capture;
*/
int emit_success_stacks;
bool emit_interim_stacks;

int allow_error_cnt;
bool has_allow_error_filter;
Expand Down
8 changes: 4 additions & 4 deletions src/fnargs.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ static void fmt_capture_item(struct fmt_buf *b, const struct btf *btf,
btf_data_dump_printf, b, &opts);
if (err == -E2BIG) {
/* truncated data */
bnappendf(b, "\u2026");
bnappendf(b, UNICODE_HELLIP);
} else if (err < 0) {
/* unexpected error */
const char *errstr = err_to_str(err);
Expand Down Expand Up @@ -456,7 +456,7 @@ void emit_fnargs_data(FILE *f, struct stack_item *s,
if (env.args_fmt_mode == ARGS_FMT_COMPACT)
fprintf(f, "%s", i == 0 ? "" : " ");
else /* emit Unicode's slightly smaller-sized '>' as a marker of an argument */
fprintf(f, "\n%*.s\u203A ", indent_shift, "");
fprintf(f, "\n%*.s%s ", indent_shift, "", UNICODE_RANGLEQUOT);
if (fn_args->btf) {
if (is_vararg)
fprintf(f, "vararg%d%s=%s", i - vararg_start_idx, sep, sep);
Expand Down Expand Up @@ -564,7 +564,7 @@ void emit_ctxargs_data(FILE *f, struct stack_item *s, int indent_shift,
if (env.args_fmt_mode == ARGS_FMT_COMPACT)
fprintf(f, "%s", i == 0 ? "" : " ");
else /* emit Unicode's slightly smaller-sized '>' as a marker of an argument */
fprintf(f, "\n%*.s\u203A ", indent_shift, "");
fprintf(f, "\n%*.s%s ", indent_shift, "", UNICODE_RANGLEQUOT);

if (info->btf) {
fprintf(f, "%s%s=%s", spec->name, sep, sep);
Expand Down Expand Up @@ -902,7 +902,7 @@ static int prepare_tp_ctx_specs(int probe_id,
return err;
}

trace_fn_sym = ksyms__map_addr(ksyms, kmem_skel->bss->value);
trace_fn_sym = ksyms__map_addr(ksyms, kmem_skel->bss->value, KSYM_FUNC);
if (!trace_fn_sym) {
elog("Failed to resolve 0x%lx to `__bpf_trace_<class>` symbol for tracepoint '%s:%s'!\n",
kmem_skel->bss->value, inj->tp.category, inj->tp.name);
Expand Down
26 changes: 21 additions & 5 deletions src/ksyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,12 @@ static int ksym_by_addr_cmp(const void *p1, const void *p2)
{
const struct ksym *s1 = p1, *s2 = p2;

if (s1->kind != s2->kind)
return s1->kind < s2->kind ? -1 : 1;

if (s1->addr == s2->addr)
return strcmp(s1->name, s2->name);

return s1->addr < s2->addr ? -1 : 1;
}

Expand Down Expand Up @@ -210,24 +214,36 @@ void ksyms__free(struct ksyms *ksyms)
}

const struct ksym *ksyms__map_addr(const struct ksyms *ksyms,
unsigned long addr)
unsigned long addr,
enum ksym_kind kind)
{
int start = 0, end = ksyms->syms_sz - 1, mid;
const struct ksym *ksym;
unsigned long sym_addr;
enum ksym_kind sym_kind;

if (kind != KSYM_FUNC && kind != KSYM_DATA)
return NULL;

/* find largest sym_addr <= addr using binary search */
while (start < end) {
mid = start + (end - start + 1) / 2;
sym_addr = ksyms->syms_by_addr[mid].addr;
ksym = &ksyms->syms_by_addr[mid];
sym_addr = ksym->addr;
sym_kind = ksym->kind;

if (sym_addr <= addr)
if (sym_kind < kind || (sym_kind == kind && sym_addr <= addr))
start = mid;
else
end = mid - 1;
}

if (start == end && ksyms->syms_by_addr[start].addr <= addr)
return &ksyms->syms_by_addr[start];
if (start == end) {
ksym = &ksyms->syms_by_addr[start];
if (ksym->kind == kind && ksym->addr <= addr)
return ksym;
}

return NULL;
}

Expand Down
2 changes: 1 addition & 1 deletion src/ksyms.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct ksyms;
struct ksyms *ksyms__load(void);
void ksyms__free(struct ksyms *ksyms);
const struct ksym *ksyms__map_addr(const struct ksyms *ksyms,
unsigned long addr);
unsigned long addr, enum ksym_kind kind);
const struct ksym *ksyms__get_symbol(const struct ksyms *ksyms,
const char *name, const char *module,
enum ksym_kind kind);
Expand Down
Loading