Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf script: perf script tests fails with segfault

pert script tests fails with segmentation fault as below:

92: perf script tests:
--- start ---
test child forked, pid 103769
DB test
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.012 MB /tmp/perf-test-script.7rbftEpOzX/perf.data (9 samples) ]
/usr/libexec/perf-core/tests/shell/script.sh: line 35:
103780 Segmentation fault (core dumped)
perf script -i "${perfdatafile}" -s "${db_test}"
--- Cleaning up ---
---- end(-1) ----
92: perf script tests : FAILED!

Backtrace pointed to :
#0 0x0000000010247dd0 in maps.machine ()
#1 0x00000000101d178c in db_export.sample ()
#2 0x00000000103412c8 in python_process_event ()
#3 0x000000001004eb28 in process_sample_event ()
#4 0x000000001024fcd0 in machines.deliver_event ()
#5 0x000000001025005c in perf_session.deliver_event ()
#6 0x00000000102568b0 in __ordered_events__flush.part.0 ()
#7 0x0000000010251618 in perf_session.process_events ()
#8 0x0000000010053620 in cmd_script ()
#9 0x00000000100b5a28 in run_builtin ()
#10 0x00000000100b5f94 in handle_internal_command ()
#11 0x0000000010011114 in main ()

Further investigation reveals that this occurs in the `perf script tests`,
because it uses `db_test.py` script. This script sets `perf_db_export_mode = True`.

With `perf_db_export_mode` enabled, if a sample originates from a hypervisor,
perf doesn't set maps for "[H]" sample in the code. Consequently, `al->maps` remains NULL
when `maps__machine(al->maps)` is called from `db_export__sample`.

As al->maps can be NULL in case of Hypervisor samples , use thread->maps
because even for Hypervisor sample, machine should exist.
If we don't have machine for some reason, return -1 to avoid segmentation fault.

Reported-by: Disha Goel <disgoel@linux.ibm.com>
Signed-off-by: Aditya Bodkhe <aditya.b1@linux.ibm.com>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Disha Goel <disgoel@linux.ibm.com>
Link: https://lore.kernel.org/r/20250429065132.36839-1-adityab1@linux.ibm.com
Suggested-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Aditya Bodkhe and committed by
Namhyung Kim
ea04fe1b 63e37590

+9 -4
+8 -3
tools/perf/util/db-export.c
··· 181 181 if (al->map) { 182 182 struct dso *dso = map__dso(al->map); 183 183 184 - err = db_export__dso(dbe, dso, maps__machine(al->maps)); 184 + err = db_export__dso(dbe, dso, maps__machine(thread__maps(al->thread))); 185 185 if (err) 186 186 return err; 187 187 *dso_db_id = dso__db_id(dso); ··· 256 256 al.map = map__get(node->ms.map); 257 257 al.maps = maps__get(thread__maps(thread)); 258 258 al.addr = node->ip; 259 + al.thread = thread__get(thread); 259 260 260 261 if (al.map && !al.sym) 261 262 al.sym = dso__find_symbol(map__dso(al.map), al.addr); ··· 359 358 }; 360 359 struct thread *main_thread; 361 360 struct comm *comm = NULL; 362 - struct machine *machine; 361 + struct machine *machine = NULL; 363 362 int err; 363 + 364 + if (thread__maps(thread)) 365 + machine = maps__machine(thread__maps(thread)); 366 + if (!machine) 367 + return -1; 364 368 365 369 err = db_export__evsel(dbe, evsel); 366 370 if (err) 367 371 return err; 368 372 369 - machine = maps__machine(al->maps); 370 373 err = db_export__machine(dbe, machine); 371 374 if (err) 372 375 return err;
+1 -1
tools/perf/util/scripting-engines/trace-event-python.c
··· 1306 1306 1307 1307 tuple_set_d64(t, 0, es->db_id); 1308 1308 tuple_set_d64(t, 1, es->evsel->db_id); 1309 - tuple_set_d64(t, 2, maps__machine(es->al->maps)->db_id); 1309 + tuple_set_d64(t, 2, maps__machine(thread__maps(es->al->thread))->db_id); 1310 1310 tuple_set_d64(t, 3, thread__db_id(es->al->thread)); 1311 1311 tuple_set_d64(t, 4, es->comm_db_id); 1312 1312 tuple_set_d64(t, 5, es->dso_db_id);