4

This is a follow up to this question with additional details since no one helped answer it. I cloned the latest QEMU repo and followed this tutorial to create a Hello World program for arm-softmmu. I traced the TCG, rather the registers in the Basic Block using Helper Functions but I came across the tracing functionality and I wanted to try it out. Following the documentation, this is my /tmp/events file after uncommenting the trace-events file.

exec_tb
exec_tb_exit

The part of the trace-events file in which the disable keyword was removed to enable trace is :

# TCG related tracing (mostly disabled by default)
# cpu-exec.c
exec_tb(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
exec_tb_nocache(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
exec_tb_exit(void *last_tb, unsigned int flags) "tb:%p flags=%x"

This is how I configure and run the qemu executable:

./configure --target-list=arm-softmmu --enable-trace-backends=simple

make

./qemu-system-arm -trace events=/tmp/events -M versatilepb -m 256M -nographic -kernel ~/FileName.bin

From the arm-softmmu directory, I run the simple trace python script this way:

./scripts/simpletrace.py trace-events arm-softmmu/trace-*pid* | head

Am I doing anything wrong here? Since I receive absolutely no information. Even the binary after tracing is just a short line(of gibberish, of course). I expected a large enough trace actually.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Arjun
  • 1,259
  • 1
  • 13
  • 25

1 Answers1

0

I can't spot what you are doing wrong, but I can provide a minimal self contained working example that just works in one command: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/467923860b78bb5d0c787f1433682dfc9c83223a#count-instructions

Once you clone do:

./run -n -- -trace exec_tb,file=trace
./qemu/scripts/simpletrace.py qemu/trace-events trace >trace.txt
wc -l trace

and you will see the traces.

For ARM:

./run -a arm -- -trace exec_tb,file=trace

Maybe this will allow you to diff out what is wrong.

The exact QEMU config line Buildroot did was:

./configure --target-list="arm-softmmu" --prefix="/home/ciro/bak/git/linux-kernel-module-cheat/buildroot/output.arm~/hos
t/usr" --interp-prefix=/home/ciro/bak/git/linux-kernel-module-cheat/buildroot/output.arm~/host/usr/arm-buildroot-linux-uclibcgnueabi/sysroot --cc="/usr/bin/gcc" --host-cc="/usr
/bin/gcc" --python=/home/ciro/bak/git/linux-kernel-module-cheat/buildroot/output.arm~/host/usr/bin/python2 --extra-cflags="-O2 -I/home/ciro/bak/git/linux-kernel-module-cheat/bu
ildroot/output.arm~/host/usr/include" --extra-ldflags="-L/home/ciro/bak/git/linux-kernel-module-cheat/buildroot/output.arm~/host/lib -L/home/ciro/bak/git/linux-kernel-module-ch
eat/buildroot/output.arm~/host/usr/lib -Wl,-rpath,/home/ciro/bak/git/linux-kernel-module-cheat/buildroot/output.arm~/host/usr/lib" --enable-debug --enable-sdl --extra-cflags='-
DDEBUG_PL061=1' --with-sdlabi=2.0

on QEMU v2.7.0, and the full QEMU command was:

./buildroot/output.x86_64~/host/usr/bin/qemu-system-x86_64 -m 128M -monitor telnet::45454,server,nowait -netdev user,hostfwd=tcp::45455-:45455,id=net0 -smp 1  -M pc -append 'root=/dev/vda nopat nokaslr norandmaps printk.devkmsg=on printk.time=y console=ttyS0 init=/poweroff.out' -device edu -device lkmc_pci_min -device virtio-net-pci,netdev=net0 -kernel ./buildroot/output.x86_64~/images/bzImage  -nographic -trace exec_tb,file=trace -drive file='./buildroot/output.x86_64~/images/rootfs.ext2.qcow2,if=virtio,format=qcow2'

I also recommend that you start without --enable-trace-backends, which leads to the even simpler backend that just spits things to stdout, with a large performance penalty. Also try to GDB QEMU up, it should be easy to figure out what is missing.

Update 2.11

-d in_asm option

Edit: -d in_asm alone shows only translation chunks, so if a chunk gets executed multiple times, it won't show multiple times. There are some extra flags that make it more accurate, see: What instructions does qemu trace?

Since I found about this option, I have been using it to get instruction listings rather than the more complicated trace backend: Tracing/profiling instructions

I would expect performance to not be as good, but if it is good enough for you, as when I do baremetal / user mode simulation, go for it.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • 1
    Similar to OP, I could not capture anything. I did not check your answer, but `+1` for the handy `-d in_asm` option. It solved my problem. – TheAhmad Oct 11 '20 at 21:04
  • 1
    Finally, I managed to enable tracing. I selected traces (at runtime), mistakenly, by including the *arguments* and *formats* in the *events file*. For example, instead of adding `exec_tb`, I added `exec_tb(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR`. The other thing to note is that `-d in_asm` does not show all **executed** `Basic Blocks`. – TheAhmad Oct 20 '20 at 17:26
  • @TheAhmad thanks for sharing!! So `exec_tb` omits repeated basic blocks is that it? I never used it outside of hello worlds so I hadn't noticed. – Ciro Santilli OurBigBook.com Oct 20 '20 at 17:30
  • The OS is `xv6-rev11 32-bit` and the emulator is `Qemu 5.1.0`. I traced the system until the shell became ready. For each trace configuration the `total unique guestPC/total guest PC` are as follows: – TheAhmad Oct 20 '20 at 20:51
  • [`exec_tb`: `3935/100393`] --- [`exec_tb_nocache`: `0/0`] --- [`translate_block`: `3935/4017`] --- [`-d in_asm`: `14350/15327`] --- [`-d in_asm -singlestep`: `16926/17211`] – TheAhmad Oct 20 '20 at 20:56
  • 1
    `exec_tb` seems to be the only one that reports all instructions including the repeated ones. Some instructions are repeated **many times** (such as the *timer interrupt handler*) but they are reported **once** or **at most several times** in the other configurations (i.e., the **non-`exec_tb`** methods). Perhaps, the reason is that the other methods only reported only the first time that each `BBL` is translated. – TheAhmad Oct 20 '20 at 21:02
  • The **small difference** between the *unique* and *non-unique* instructions may be caused by the fact that translation is done at the `Dynamic BBL` level rather than the static `BBL` level. I do not know why `translate_block` does not match with `-d in_asm`. They will need a **closer** inspection. – TheAhmad Oct 20 '20 at 21:06
  • Could this be what you're looking for? "nochain do not chain compiled TBs so that "exec" and "cpu" show complete traces" – Simon Willcocks Mar 05 '21 at 11:12