How to debug a program at the machine instruction level
version
1.0.1
scope
Example.
This code is provided as example code for a user to base their code on.
description
How to debug a program at the machine instruction level
boards
Unless otherwise specified, this example runs on the SliceKIT Core Board, but can easily be run on any XMOS device by using a different XN file.
As well as working at the source level, XGDB can be used to debug programs at the level of the machine instructions. As an example, consider the following program:
int main() { int i, j = 0; for (i = 0; i < 5; ++i) { j += i; } return 0; }
Compile the above program ensuring that debug is enabled (-g):
From xTIMEcomposer Studio
Create a new debug configuration via Run->Debug Configurations->xCORE Applications. Set a breakpoint on main and start debugging. Execution will now break when main is reached. Open both the Disassembly and the Debug views. In the Debug view toolbar, click on the Instruction Stepping Mode button. When in this mode, a single step will now correspond to a single machine instruction and not a source line. This can be seen by stepping a few times and watching the progress in the Disassembly view.
From the command line
Start XGDB, connect to the simulator and set a breakpoint on main. Execution will therefore suspend when the main is reached. The stepi command can be used to step a single machine instruction, and the disassemble command can be used to see the disassembly of the code close to the current PC location:
> xgdb a.xe ..etc.. (gdb) connect -s 0xffffc070 in ?? () (gdb) b main Breakpoint 1 at 0x100b0: file debugging_at_the_instruction_level.xc, line 9. (gdb) r ...etc... Breakpoint 1, main () at debugging_at_the_instruction_level.xc:9 9 int i, j = 0; (gdb) disassemble Dump of assembler code for function main: 0x000100ac <main+0>: entsp (u6) 0x4 0x000100ae <main+2>: ldc (ru6) r0, 0x0 0x000100b0 <main+4>: stw (ru6) r0, sp[0x0] 0x000100b2 <main+6>: stw (ru6) r0, sp[0x1] 0x000100b4 <main+8>: bu (u6) 0x7 0x000100b6 <main+10>: ldw (ru6) r0, sp[0x1] 0x000100b8 <main+12>: ldw (ru6) r1, sp[0x0] 0x000100ba <main+14>: add (3r) r0, r1, r0 0x000100bc <main+16>: stw (ru6) r0, sp[0x0] 0x000100be <main+18>: ldw (ru6) r0, sp[0x1] 0x000100c0 <main+20>: add (2rus) r0, r0, 0x1 0x000100c2 <main+22>: stw (ru6) r0, sp[0x1] 0x000100c4 <main+24>: ldw (ru6) r0, sp[0x1] 0x000100c6 <main+26>: ldc (ru6) r1, 0x5 0x000100c8 <main+28>: lss (3r) r0, r0, r1 0x000100ca <main+30>: bt (ru6) r0, -0xb 0x000100cc <main+32>: bu (u6) 0x0 0x000100ce <main+34>: ldc (ru6) r0, 0x0 0x000100d0 <main+36>: stw (ru6) r0, sp[0x2] 0x000100d2 <main+38>: ldw (ru6) r0, sp[0x2] 0x000100d4 <main+40>: retsp (u6) 0x4 End of assembler dump. (gdb) stepi 10 for (i = 0; i < 5; ++i) { (gdb) stepi 0x000100b4 10 for (i = 0; i < 5; ++i) { (gdb) stepi 0x000100c4 10 for (i = 0; i < 5; ++i) { (gdb) stepi 0x000100c6 10 for (i = 0; i < 5; ++i) { (gdb) stepi 0x000100c8 10 for (i = 0; i < 5; ++i) { ...etc...