Debugging with VSCode - set next statement

Hey!

I am looking for a functionality that’s similar to the Lauterbach’s “Set program counter”. I saw that within the VSCode community this is called Set Next Statement.

Note - this is different than the run to click, which would normally set a breakpoint ahead and would stop there. What I am looking for here is to manually change the program counter by easily clicking where in the code (either source or dissassembled) I want to change the execution flow to. Is that possible with the PlatformIO debugging integration?

Thanks

There’s only “Run to cursor” when you right click on a line of code while debugging.

I think VSCode doesn’t expose a “Force execution to start here” thing because as Microsoft says,

Moving the next statement to another function or scope usually causes call-stack corruption

So only expert users will want to use this in extremely rare cases.

However, since you do have access to the GDB console through the “Debug Console” Tab…

… you can tell GDB to modify the register responsible for the program counter which is exposed as $pcin GDB. (real register is EIP / RIP on x86/x64, PC on ARM etc…) to a specific address, which itself can be found through disas <function name> commands.

E.g., given the code above and state above, and I want to move to beginning of the “sort” call, I use

=> 0x00007ff6142c1863 <+9>:	lea    0x37e6(%rip),%rcx        # 0x7ff6142c5050
   0x00007ff6142c186a <+16>:	call   0x7ff6142c2ee0 <puts>
   0x00007ff6142c186f <+21>:	movl   $0x8,0x20(%rsp)
   0x00007ff6142c1877 <+29>:	movl   $0x22,0x24(%rsp)
   0x00007ff6142c187f <+37>:	movl   $0xd,0x28(%rsp)
   0x00007ff6142c1887 <+45>:	movl   $0x11,0x2c(%rsp)
   0x00007ff6142c188f <+53>:	movl   $0x22,0x30(%rsp)
   0x00007ff6142c1897 <+61>:	movl   $0x5a,0x34(%rsp)
   0x00007ff6142c189f <+69>:	movl   $0x30,0x38(%rsp)
   0x00007ff6142c18a7 <+77>:	movl   $0x48,0x3c(%rsp)
   0x00007ff6142c18af <+85>:	movl   $0x32,0x40(%rsp)
   0x00007ff6142c18b7 <+93>:	movl   $0x56,0x44(%rsp)
   0x00007ff6142c18bf <+101>:	lea    0x20(%rsp),%rcx
   0x00007ff6142c18c4 <+106>:	mov    $0x9,%r8d
   0x00007ff6142c18ca <+112>:	mov    $0x0,%edx
   0x00007ff6142c18cf <+117>:	call   0x7ff6142c17cb <sort>
   0x00007ff6142c18d4 <+122>:	mov    $0x0,%eax
   0x00007ff6142c18d9 <+127>:	add    $0x58,%rsp
   0x00007ff6142c18dd <+131>:	ret    
End of assembler dump.

then recognize that the call to sort starts with preparing the registers used for storing the argument values at 0x00007ff6142c18bf, and thus do

   0x00007ff6142c1863 <+9>:	lea    0x37e6(%rip),%rcx        # 0x7ff6142c5050
   0x00007ff6142c186a <+16>:	call   0x7ff6142c2ee0 <puts>
   0x00007ff6142c186f <+21>:	movl   $0x8,0x20(%rsp)
   0x00007ff6142c1877 <+29>:	movl   $0x22,0x24(%rsp)
   0x00007ff6142c187f <+37>:	movl   $0xd,0x28(%rsp)
   0x00007ff6142c1887 <+45>:	movl   $0x11,0x2c(%rsp)
   0x00007ff6142c188f <+53>:	movl   $0x22,0x30(%rsp)
   0x00007ff6142c1897 <+61>:	movl   $0x5a,0x34(%rsp)
   0x00007ff6142c189f <+69>:	movl   $0x30,0x38(%rsp)
   0x00007ff6142c18a7 <+77>:	movl   $0x48,0x3c(%rsp)
   0x00007ff6142c18af <+85>:	movl   $0x32,0x40(%rsp)
   0x00007ff6142c18b7 <+93>:	movl   $0x56,0x44(%rsp)
   0x00007ff6142c18bf <+101>:	lea    0x20(%rsp),%rcx
=> 0x00007ff6142c18c4 <+106>:	mov    $0x9,%r8d
   0x00007ff6142c18ca <+112>:	mov    $0x0,%edx
   0x00007ff6142c18cf <+117>:	call   0x7ff6142c17cb <sort>
   0x00007ff6142c18d4 <+122>:	mov    $0x0,%eax
   0x00007ff6142c18d9 <+127>:	add    $0x58,%rsp
   0x00007ff6142c18dd <+131>:	ret    
End of assembler dump.

and the line was changed and one instruction was executed, which is reflected again in the GUI.

Of course in this case, the initialization of the array input_array on the stack was skipped (movl $0x8,0x20(%rsp) etc. instructions), so the function will run on completely random data from the stack. But, that’s exactly what forcing the next statement address causes in this case.

1 Like