Single-stepping with QEMU and GDB
It's possible to put the ARM emulator
qemu-arm into a mode where it accepts commands from an instance of the Gnu debugger
gdb running on the host machine. This makes it possible to run an ARM program written in assembly languageA symbolic representation of the machine code for a program. – such as the output of the Lab 4 compiler – and trace its action one instruction at a time. I tried this experiment on a machine running Debian Stretch, but other Linux variants ought to work much the same.
- Install the needed packages with
sudo apt-get install qemu-user gdb-multiarch gcc-arm-linux-gnueabihf. (Probably you've got some of those installed already.)
- In the
lab4directory, edit the
compilescript so that the last line reads (note the
./ppc $* >b.s && $ARMGCC -g b.s pas0.o -static -o b.out
- Run a command such as
./compile -O test/mult.pto compile a test program.
- Now start two terminal windows. In one of them, start
qemu-armwith the command
$ qemu-arm -g 1234 ./b.out
- In the other terminal window, start
gdbwith the command
$ gdb-multiarch ./b.out
- Connect to the QEMU session with the command
(gdb) target remote localhost:1234
- Use this command to activate GDB's display of source and registers
(gdb) tui reg general
- Skip to the start of your code with
(gdb) advance pmain
- At this point, you can use the command
stepto execute your program one instruction at a time, and watch the register contents as you do so. It helps to enlarge the terminal window so that all the registers are visible. Once you have given the step command once, just pressing
<Return>will step repeatedly.
- When boredom overcomes you, use
- Single stepping will skip over library routines such as
print_numthat are written in C, unless you also recompile
- All the power of GDB is available to set breakpoints, examine and even modify memory, redirect the flow of control, etc. Don't get carried away!