diff --git a/README.adoc b/README.adoc index dae1ab8..b6dde00 100644 --- a/README.adoc +++ b/README.adoc @@ -8203,18 +8203,29 @@ The most interesting are events which show instructions that QEMU ran, for which Under the hood, this uses QEMU's `-trace` option. -You can then inspect the instructions with: +You can then inspect the address of each instruction run: .... less "$(./getvar --arch x86_64 run_dir)/trace.txt" .... +Sample output excerpt: + +.... +exec_tb 0.000 pid=10692 tb=0x7fb4f8000040 pc=0xfffffff0 +exec_tb 35.391 pid=10692 tb=0x7fb4f8000180 pc=0xfe05b +exec_tb 21.047 pid=10692 tb=0x7fb4f8000340 pc=0xfe066 +exec_tb 12.197 pid=10692 tb=0x7fb4f8000480 pc=0xfe06a +.... + Get the list of available trace events: .... ./run --trace help .... +TODO: any way to show the actualy disassembled instruction executed directly from there? Possible with <>. + Enable other specific trace events: .... @@ -8276,7 +8287,25 @@ IN: TODO: after `IN:`, symbol names are meant to show, which is awesome, but I don't get any. I do see them however when running a bare metal example from: https://github.com/cirosantilli/newlib-examples/tree/900a9725947b1f375323c7da54f69e8049158881 -TODO: what is the point of having two mechanisms, `-trace` and `-d`? `-d` tracing is cool because it does not require a messy recompile, and it can also show symbols. +TODO: what is the point of having two mechanisms, `-trace` and `-d`? `-d` tracing is cool because it does not require a messy recompile, and it can also show symbols. + +==== QEMU trace register values + +TODO: is it possible to show the register values for each instruction? + +This would include the memory values read into the registers. + +Asked at: https://superuser.com/questions/1377764/how-to-trace-the-register-values-of-executed-instructions-in-qemu + +Seems impossible due to optimizations that QEMU does: + +* https://lists.gnu.org/archive/html/qemu-devel/2015-06/msg07479.html +* https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg02856.html +* https://lists.gnu.org/archive/html/qemu-devel/2012-08/msg03057.html + +PANDA can list memory addresses, so I bet it can also decode the instructions: https://github.com/panda-re/panda/blob/883c85fa35f35e84a323ed3d464ff40030f06bd6/panda/docs/LINE_Censorship.md I wonder why they don't just upstream those things to QEMU's tracing: https://github.com/panda-re/panda/issues/290 + +gem5 can do it: <>. ==== Trace source lines @@ -8422,18 +8451,6 @@ TODO: is there any way to distinguish which instruction runs on each core? Doing just appears to output both cores intertwined without any clear differentiation. -==== QEMU trace decode instructions - -TODO: is is possible to show which instructions ran at each point in time, in addition to the address of the instruction with `exec_tb` shows? Hopefully dissembled, not just the instruction memory. - -PANDA can list memory addresses, so I bet it can also decode the instructions: https://github.com/panda-re/panda/blob/883c85fa35f35e84a323ed3d464ff40030f06bd6/panda/docs/LINE_Censorship.md I wonder why they don't just upstream those things to QEMU's tracing: https://github.com/panda-re/panda/issues/290 - -Memory access on vanilla seem impossible due to optimizations that QEMU does: - -* https://lists.gnu.org/archive/html/qemu-devel/2015-06/msg07479.html -* https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg02856.html -* https://lists.gnu.org/archive/html/qemu-devel/2012-08/msg03057.html - ==== gem5 tracing gem5 unlike QEMU is deterministic by default without needing to replay traces @@ -10555,6 +10572,8 @@ Don't believe me? Then try: and watch it hang forever. +When GDB step debugging, switch between cores with the usual `thread` commands, see also: <>. + Bibliography: * https://stackoverflow.com/questions/20055754/arm-start-wakeup-bringup-the-other-cpu-cores-aps-and-pass-execution-start-addre diff --git a/common.py b/common.py index 5cf552a..f84e90b 100644 --- a/common.py +++ b/common.py @@ -794,7 +794,7 @@ def setup(parser): common.gem5_run_dir = os.path.join(common.run_dir_base, 'gem5', args.arch, str(args.run_id)) common.m5out_dir = os.path.join(common.gem5_run_dir, 'm5out') common.stats_file = os.path.join(common.m5out_dir, 'stats.txt') - common.trace_txt_file = os.path.join(common.m5out_dir, 'trace.txt') + common.gem5_trace_txt_file = os.path.join(common.m5out_dir, 'trace.txt') common.gem5_guest_terminal_file = os.path.join(common.m5out_dir, 'system.terminal') common.gem5_readfile = os.path.join(common.gem5_run_dir, 'readfile') common.gem5_termout_file = os.path.join(common.gem5_run_dir, 'termout.txt') @@ -841,11 +841,13 @@ def setup(parser): common.run_dir = common.gem5_run_dir common.termout_file = common.gem5_termout_file common.guest_terminal_file = gem5_guest_terminal_file + common.trace_txt_file = gem5_trace_txt_file else: common.executable = common.qemu_executable common.run_dir = common.qemu_run_dir common.termout_file = common.qemu_termout_file common.guest_terminal_file = qemu_guest_terminal_file + common.trace_txt_file = qemu_trace_txt_file common.gem5_config_dir = os.path.join(common.gem5_src_dir, 'configs') common.gem5_se_file = os.path.join(common.gem5_config_dir, 'example', 'se.py') common.gem5_fs_file = os.path.join(common.gem5_config_dir, 'example', 'fs.py') diff --git a/trace-boot b/trace-boot index a4af53c..2daac4b 100755 --- a/trace-boot +++ b/trace-boot @@ -31,7 +31,7 @@ if common.emulator == 'gem5': run.main(args, extra_args) else: extra_args.update({ - 'kernel_cli_extra': 'init=/poweroff.out', + 'kernel_cli': 'init=/poweroff.out', 'trace': 'exec_tb', }) run.main(args, extra_args)