Skip to content

Commit 61d9fc4

Browse files
Jin Yaoacmel
authored andcommitted
perf script: Support filtering by hex address
'perf script' supports '-S' or '--symbol' options to only list the records for these symbols. A symbol is typically a name or hex address. If it's hex address, it is the start address of one symbol. While it would be useful if we can filter trace records by any hex address (not only the start address of symbol). So now we support filtering trace records by more conditions, such as: - symbol name - start address of symbol - any hexadecimal address - address range The comparison order is defined as: 1. symbol name comparison 2. symbol start address comparison. 3. any hexadecimal address comparison. 4. address range comparison. The idea is if we can get a valid address from -S list, we add the address to addr_list for address comparison otherwise we still leave it to sym_list for symbol comparison. Some examples: root@kbl-ppc:~# ./perf script -S ffffffff9a477308 perf 8562 [000] 347303.578858: 1 cycles: ffffffff9a477308 native_write_msr+0x8 ([kernel.kallsyms]) perf 8562 [000] 347303.578860: 1 cycles: ffffffff9a477308 native_write_msr+0x8 ([kernel.kallsyms]) perf 8562 [000] 347303.578861: 11 cycles: ffffffff9a477308 native_write_msr+0x8 ([kernel.kallsyms]) perf 8562 [001] 347303.578903: 1 cycles: ffffffff9a477308 native_write_msr+0x8 ([kernel.kallsyms]) perf 8562 [001] 347303.578905: 1 cycles: ffffffff9a477308 native_write_msr+0x8 ([kernel.kallsyms]) perf 8562 [001] 347303.578906: 15 cycles: ffffffff9a477308 native_write_msr+0x8 ([kernel.kallsyms]) perf 8562 [002] 347303.578952: 1 cycles: ffffffff9a477308 native_write_msr+0x8 ([kernel.kallsyms]) perf 8562 [002] 347303.578953: 1 cycles: ffffffff9a477308 native_write_msr+0x8 ([kernel.kallsyms]) Filter the traced records by hex address ffffffff9a477308. root@kbl-ppc:~# ./perf script -S ffffffff9a4dd4ce,ffffffff9a4d2de9,ffffffff9a6bf9f4 perf 8562 [001] 347303.578911: 311706 cycles: ffffffff9a6bf9f4 __kmalloc_node+0x204 ([kernel.kallsyms]) perf 8562 [002] 347303.578960: 354477 cycles: ffffffff9a4d2de9 sched_setaffinity+0x49 ([kernel.kallsyms]) perf 8562 [003] 347303.579015: 450958 cycles: ffffffff9a4dd4ce dequeue_task_fair+0x1ae ([kernel.kallsyms]) Filter the traced records by hex address ffffffff9a4dd4ce, ffffffff9a4d2de9, ffffffff9a6bf9f4. root@kbl-ppc:~# ./perf script -S ffffffff9a477309 --addr-range 16 perf 8562 [000] 347303.578863: 291 cycles: ffffffff9a47730a native_write_msr+0xa ([kernel.kallsyms]) perf 8562 [001] 347303.578907: 411 cycles: ffffffff9a47730a native_write_msr+0xa ([kernel.kallsyms]) perf 8562 [002] 347303.578956: 462 cycles: ffffffff9a47730f native_write_msr+0xf ([kernel.kallsyms]) perf 8562 [003] 347303.579010: 497 cycles: ffffffff9a47730f native_write_msr+0xf ([kernel.kallsyms]) perf 8562 [004] 347303.579059: 429 cycles: ffffffff9a47730f native_write_msr+0xf ([kernel.kallsyms]) perf 8562 [005] 347303.579109: 408 cycles: ffffffff9a47730a native_write_msr+0xa ([kernel.kallsyms]) perf 8562 [006] 347303.579159: 460 cycles: ffffffff9a47730f native_write_msr+0xf ([kernel.kallsyms]) perf 8562 [007] 347303.579213: 436 cycles: ffffffff9a47730f native_write_msr+0xf ([kernel.kallsyms]) Filter the traced records from address range [ffffffff9a477309, ffffffff9a477309 + 15]. root@kbl-ppc:~# ./perf script -S "ffffffff9b163046,rcu_nmi_exit" perf 8562 [004] 347303.579060: 12013 cycles: ffffffff9b163046 exc_nmi+0x166 ([kernel.kallsyms]) perf 8562 [007] 347303.579214: 12138 cycles: ffffffff9b165944 rcu_nmi_exit+0x34 ([kernel.kallsyms]) Filter by address + symbol Signed-off-by: Jin Yao <[email protected]> Tested-by: Arnaldo Carvalho de Melo <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Jin Yao <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Kan Liang <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lore.kernel.org/lkml/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 9425339 commit 61d9fc4

File tree

5 files changed

+98
-1
lines changed

5 files changed

+98
-1
lines changed

tools/perf/Documentation/perf-script.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,9 +422,29 @@ include::itrace.txt[]
422422
Only consider the listed symbols. Symbols are typically a name
423423
but they may also be hexadecimal address.
424424

425+
The hexadecimal address may be the start address of a symbol or
426+
any other address to filter the trace records
427+
425428
For example, to select the symbol noploop or the address 0x4007a0:
426429
perf script --symbols=noploop,0x4007a0
427430

431+
Support filtering trace records by symbol name, start address of
432+
symbol, any hexadecimal address and address range.
433+
434+
The comparison order is:
435+
436+
1. symbol name comparison
437+
2. symbol start address comparison.
438+
3. any hexadecimal address comparison.
439+
4. address range comparison (see --addr-range).
440+
441+
--addr-range::
442+
Use with -S or --symbols to list traced records within address range.
443+
444+
For example, to list the traced records within the address range
445+
[0x4007a0, 0x0x4007a9]:
446+
perf script -S 0x4007a0 --addr-range 10
447+
428448
--dsos=::
429449
Only consider symbols in these DSOs.
430450

tools/perf/builtin-script.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3552,6 +3552,8 @@ int cmd_script(int argc, const char **argv)
35523552
"only consider symbols in these DSOs"),
35533553
OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
35543554
"only consider these symbols"),
3555+
OPT_INTEGER(0, "addr-range", &symbol_conf.addr_range,
3556+
"Use with -S to list traced records within address range"),
35553557
OPT_CALLBACK_OPTARG(0, "insn-trace", &itrace_synth_opts, NULL, NULL,
35563558
"Decode instructions from itrace", parse_insn_trace),
35573559
OPT_CALLBACK_OPTARG(0, "xed", NULL, NULL, NULL,

tools/perf/util/event.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,19 @@ struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
645645
return al->sym;
646646
}
647647

648+
static bool check_address_range(struct intlist *addr_list, int addr_range,
649+
unsigned long addr)
650+
{
651+
struct int_node *pos;
652+
653+
intlist__for_each_entry(pos, addr_list) {
654+
if (addr >= pos->i && addr < pos->i + addr_range)
655+
return true;
656+
}
657+
658+
return false;
659+
}
660+
648661
/*
649662
* Callers need to drop the reference to al->thread, obtained in
650663
* machine__findnew_thread()
@@ -711,6 +724,17 @@ int machine__resolve(struct machine *machine, struct addr_location *al,
711724
ret = strlist__has_entry(symbol_conf.sym_list,
712725
al_addr_str);
713726
}
727+
if (!ret && symbol_conf.addr_list && al->map) {
728+
unsigned long addr = al->map->unmap_ip(al->map, al->addr);
729+
730+
ret = intlist__has_entry(symbol_conf.addr_list, addr);
731+
if (!ret && symbol_conf.addr_range) {
732+
ret = check_address_range(symbol_conf.addr_list,
733+
symbol_conf.addr_range,
734+
addr);
735+
}
736+
}
737+
714738
if (!ret)
715739
al->filtered |= (1 << HIST_FILTER__SYMBOL);
716740
}

tools/perf/util/symbol.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2406,6 +2406,49 @@ int setup_intlist(struct intlist **list, const char *list_str,
24062406
return 0;
24072407
}
24082408

2409+
static int setup_addrlist(struct intlist **addr_list, struct strlist *sym_list)
2410+
{
2411+
struct str_node *pos, *tmp;
2412+
unsigned long val;
2413+
char *sep;
2414+
const char *end;
2415+
int i = 0, err;
2416+
2417+
*addr_list = intlist__new(NULL);
2418+
if (!*addr_list)
2419+
return -1;
2420+
2421+
strlist__for_each_entry_safe(pos, tmp, sym_list) {
2422+
errno = 0;
2423+
val = strtoul(pos->s, &sep, 16);
2424+
if (errno || (sep == pos->s))
2425+
continue;
2426+
2427+
if (*sep != '\0') {
2428+
end = pos->s + strlen(pos->s) - 1;
2429+
while (end >= sep && isspace(*end))
2430+
end--;
2431+
2432+
if (end >= sep)
2433+
continue;
2434+
}
2435+
2436+
err = intlist__add(*addr_list, val);
2437+
if (err)
2438+
break;
2439+
2440+
strlist__remove(sym_list, pos);
2441+
i++;
2442+
}
2443+
2444+
if (i == 0) {
2445+
intlist__delete(*addr_list);
2446+
*addr_list = NULL;
2447+
}
2448+
2449+
return 0;
2450+
}
2451+
24092452
static bool symbol__read_kptr_restrict(void)
24102453
{
24112454
bool value = false;
@@ -2489,6 +2532,10 @@ int symbol__init(struct perf_env *env)
24892532
symbol_conf.sym_list_str, "symbol") < 0)
24902533
goto out_free_tid_list;
24912534

2535+
if (symbol_conf.sym_list &&
2536+
setup_addrlist(&symbol_conf.addr_list, symbol_conf.sym_list) < 0)
2537+
goto out_free_sym_list;
2538+
24922539
if (setup_list(&symbol_conf.bt_stop_list,
24932540
symbol_conf.bt_stop_list_str, "symbol") < 0)
24942541
goto out_free_sym_list;
@@ -2512,6 +2559,7 @@ int symbol__init(struct perf_env *env)
25122559

25132560
out_free_sym_list:
25142561
strlist__delete(symbol_conf.sym_list);
2562+
intlist__delete(symbol_conf.addr_list);
25152563
out_free_tid_list:
25162564
intlist__delete(symbol_conf.tid_list);
25172565
out_free_pid_list:
@@ -2533,6 +2581,7 @@ void symbol__exit(void)
25332581
strlist__delete(symbol_conf.comm_list);
25342582
intlist__delete(symbol_conf.tid_list);
25352583
intlist__delete(symbol_conf.pid_list);
2584+
intlist__delete(symbol_conf.addr_list);
25362585
vmlinux_path__exit();
25372586
symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
25382587
symbol_conf.bt_stop_list = NULL;

tools/perf/util/symbol_conf.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,13 @@ struct symbol_conf {
7070
*sym_to_list,
7171
*bt_stop_list;
7272
struct intlist *pid_list,
73-
*tid_list;
73+
*tid_list,
74+
*addr_list;
7475
const char *symfs;
7576
int res_sample;
7677
int pad_output_len_dso;
7778
int group_sort_idx;
79+
int addr_range;
7880
};
7981

8082
extern struct symbol_conf symbol_conf;

0 commit comments

Comments
 (0)