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.

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

8 Comments

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.
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 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.
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:
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.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.