Disassembly Debugging - Marus/cortex-debug GitHub Wiki

This is a feature that involves both Cortex-Debug and VSCode. Note that all the presentation and user interface are handled by VSCode, while we provide the data to present.

While in a debug session and in a paused state, you can invoke the disassembler and view the disassembly for that source code. This Disassembly view is provided by Microsoft/VSCode and I would still consider it a work in progress but it has been functional thus far. Cortex-Debug provides the backend and VSCode provides the window/menus that you interact with. Here are the features thus far

  • Trigger Disassembly either from the editor or in the CALL STACK window by right-clicking on any frame of any thread. This will make the Disassembly window appear.
    • It can disassemble an entire executable but it will only do it based on how far you scroll. It is more like on-demand disassembly.
    • You can toggle 'Source code' embedding from the Command Palette. images/toggle-source.png Hint: Create a keyboard shortcut
  • You can single step in either of the windows. If the focus is in the disassembly window, it will do a step/next at an instruction level
  • Tip: You can arrange your windows to be in a side-by-side configuration and then invoke Lock Group using the ... menu on the top right. This way when you double click on an assembly instruction, the source will open in the adjacent group.
  • You can set breakpoints at any instruction just like you do for source files (in the gutter area). The UI to set conditions and hit counts are not yet enabled although our backend supports conditions

images/disassemble.gif

Caveats

It is difficult to tell if the disassembly is actually accurate.

  • Known issue: Sometimes you may not see source code when the current instruction is near a bunch of other functions that do not have source. This happens for example if you are stopped in main, and your main is small, and it is surrounded by startup code that does not have source. Not sure why gdb is doing this

  • Since arbitrary addresses are used to fetch instructions, we may not be getting the correct ones. Especially if the start address is in the middle of an instruction. We try multiple times to make sure that some known instructions are in the right location -- meaning all others will be as well. Please report if you are suspecting inaccurate disassembly. This is more of an issue with CPUs like Xtensa with variable instruction widths. ARM/RISC-V are either 16 or 32 bit which is far more reliable.

  • The address range may be beyond the limits of memory regions. We try to detect this and display a '??' just before the instruction to indicate that it might be suspicious. In the event that a request to gdb to disassemble fails, we try to reduce the memory to be within the known memory regions and try again. But we still have to satisfy the request from VSCode. You may see something like the following when that occurs (partly in a valid region and partly outside) bad disassembly example You can get the regions defined for your device/target using the gdb command info mem. If this is empty or wrong then you may see issues with the disassembly not working fully, especially at the boundaries of memory regions.

  • We are not sure how VSCode deals with multiple memory regions that are disjoint. You can have code in ROM, FLASH, external FLASH, SRAM, and all combinations of those memories. They are generally in disjoint address spaces. We know Cortex-Debug and GDB can handle it but not sure if VSCode can. It should be okay because VSCode also has to deal with native programs where DLLs are typically located in very different address spaces than the main executable. Let us know if you are seeing a problem.. It seems to handle it fine, but please report any issues.