microsoft/MIEngine

entrypoint behaviour with gdb <-> gdbserver

gareth-davies-img opened this issue · 0 comments

I am using VSCode/cpptools to debug a C program built with gcc, using a gdb <-> gdbserver connection to perform the debug.

Regarding the following code in MIEngine:
https://github.com/microsoft/MIEngine/blob/bc7dccbc0ae509b6dcd7d1e3c6b14f30bfd5064f/src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs#L1102

This works fine for me when the C program is built for and run on Windows. Here the stack frame information the above MIEngine code sees is:

1: (1001) ->1016^done,stack=[frame={level="0",addr="0x00007ffe3e6d119d",func="ntdll!LdrInitShimEngineDynamic",from="target:C:\\Windows\\SYSTEM32\\ntdll.dll",arch="i386:x86-64"},frame={level="1",addr="0x00007ffe3e6d455f",func="ntdll!LdrInitShimEngineDynamic",from="target:C:\\Windows\\SYSTEM32\\ntdll.dll",arch="i386:x86-64"},frame={level="2",addr="0x00007ffe3e6c1d75",func="ntdll!memset",from="target:C:\\Windows\\SYSTEM32\\ntdll.dll",arch="i386:x86-64"},frame={level="3",addr="0x00007ffe3e6717d3",func="ntdll!LdrInitializeThunk",from="target:C:\\Windows\\SYSTEM32\\ntdll.dll",arch="i386:x86-64"},frame={level="4",addr="0x00007ffe3e67177e",func="ntdll!LdrInitializeThunk",from="target:C:\\Windows\\SYSTEM32\\ntdll.dll",arch="i386:x86-64"},frame={level="5",addr="0x0000000000000000",func="??",arch="i386:x86-64"}]

So because there is no mention of "file", it results in this code not setting this.EntrypointHit to true, which seems to work out well later on when the breakpoint set at the beginning of main() (for stopAtEntry I guess) is hit and processed.

However building the same C program for an embedded target and running on that, the stack frame information comes back as:

1: (2722) ->1014^done,stack=[frame={level="0",addr="0x00000000",func="_start",file="../riscv-sdk-picolibc/picocrt/machine/riscv/crt0.c",fullname="/jenkins/workspace/sdk_build_gnu_tools-windows/riscv-sdk-gnu-toolchain/build-picolibc/../riscv-sdk-picolibc/picocrt/machine/riscv/crt0.c",line="69",arch="riscv:rv32"}]

So does mention "file".

I believe the difference may be that in the embedded case we do have source code to the start-up function (_start() in crt0.c), whereas on the Windows case there was no source code for the ntdll functions.

The problem the above gives in the embedded case is that the presence of "file" means this.EntrypointHit is set to true. This then causes problems when the breakpoint at the beginning of main() is hit and processed, and results in it being reported as an "Unknown breakpoint" exception at the following line of code:
https://github.com/microsoft/MIEngine/blob/bc7dccbc0ae509b6dcd7d1e3c6b14f30bfd5064f/src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs#L1179

I have made a local fix to check that file does not contain "crt0.c", but it feels very temporary :-) So just wondering what a more permanent fix might be?