Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Visual Studio Disassembly view out of sync (VSC-1557) #1399

Open
1 task done
torsts opened this issue Jan 12, 2025 · 5 comments
Open
1 task done

Visual Studio Disassembly view out of sync (VSC-1557) #1399

torsts opened this issue Jan 12, 2025 · 5 comments
Labels
bug-report Bug Report from users on Github (don't use this tag manually, its supposed to be used via the issue) ongoing Ongoing Issue or PR, this label will be used for issue or PR which is to be excluded by stale bot

Comments

@torsts
Copy link

torsts commented Jan 12, 2025

OS

Windows

Operating System version

Microsoft Windows 11 Pro

Visual Studio Code version

1.96.2

ESP-IDF version

5.4

Python version

3.11.2

Doctor command output

report.txt

Extension

esp_idf_vsc_ext.log

Description

I am debugging an esp32-s3 application for M5stack cardputer. When opening the disassembly view, the active line in the disassembly view does not match the current instruction pointer.
debugging_no_disassembler
debugging_with_disassembler
launch_json

I started debugging the problem in Visual Studio Code and ended in vscode-esp-idf-extension.
The problem is in
vscode-esp-idf-extension/src/cdtDebugAdapter/adapter/GDBDebugSession.ts
function:
protected async disassembleRequest(
response: DebugProtocol.DisassembleResponse,
args: CDTDisassembleArguments
) {
According to the debug adapter protocol:
https://microsoft.github.io/debug-adapter-protocol//specification.html
interface DisassembleArguments {
has:
/**

  • Offset (in instructions) to be applied after the byte offset (if any)
  • before disassembling. Can be negative.
    */
    instructionOffset?: number;

This argument is completely ignored by the disassembleRequest function.
In my particular debug session the value of instructionOffset = -50.
This leads to the disassembly view marking 0x420397ef in the view, whereas Registers.pc => 0x420395e1.

The mapping between these addresses happens in
private async loadDisassembledInstructions
found in the following Visual Studio Code source code file:
vscode/src/vs/workbench/contrib/debug/browser/disassemblyView.ts

Debug Message

debug_console_output.txt

Other Steps to Reproduce

Repro: I opened one of my projects, set a hardware breakpoint on esp_log_writev in log_write.c from espressif and do start debugging.
When the breakpoint is hit, I open the disassembly view ( and start single step).

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@torsts torsts added the bug-report Bug Report from users on Github (don't use this tag manually, its supposed to be used via the issue) label Jan 12, 2025
@github-actions github-actions bot changed the title Visual Studio Disassembly view out of sync Visual Studio Disassembly view out of sync (VSC-1557) Jan 12, 2025
@brianignacio5
Copy link
Collaborator

Let me summarize the relevant code and discuss about it:

const fetchSize = (args.instructionCount - instructions.length) * meanSizeOfInstruction;

const stepStartAddress = `(${args.memoryReference})+${startOffset}`;
let stepEndAddress = `(${args.memoryReference})+${startOffset}+${fetchSize}`;
if (args.endMemoryReference && instructions.length === 0) {
  // On the first call, if we have an end memory address use it instead of
  // the approx size
  stepEndAddress = args.endMemoryReference;
  oneIterationOnly = true;
}
const result = await sendDataDisassemble(
  this.gdb,
  stepStartAddress,
  stepEndAddress
);

The main issue with the alignment is that vscode disassemble request doesn't use the actual address you want when you right click and click to open disassemble view and uses some arbitrary memory reference args.memoryReference. Here the code tries to calculate a window to fetch from GDB.

In my tests I could not obtain such address from the request. If you in fact are sure that args.memoryReference is the right address and the offset too I would revisit this issue.

@torsts
Copy link
Author

torsts commented Jan 13, 2025

Hi, so VSC does an internal remapping based on the instructionOffset. From my understanding it sets the instructionOffset in order to display code prior to the one that the current focus point is. I am attaching a screenshot from the actual function from VSC that requests the disassembly data, The blue box shows where it will go into the esp-idf extension.

The box at line 497 shows on how the instruction reference (that is a string) is mapped to the actual address (based on the instructionOffset).

When it later goes into the render function it takes the reference and resolves it to the actual address. What lets the disassembly view end up in the wrong location. All this is based on the understanding, that the disassemble function knows on how to deal with the instructionOffset.

The box on the right shows you the mapping entry for reference "0x420395e4" to address 0x4203965e.

sc_debug2

To answer your 2 questions:
a) yes, you spotted the code on esp-idf side that is responsible for handling the disassemby request
b) What I really want is that the disassembly view shows me were in the code I really am. So I thought, handling the instructionOffset parameter is going to resolve this.

@torsts
Copy link
Author

torsts commented Jan 13, 2025

As a sidenote, VSC in my tests called the loadDisassembledInstructions function twice for the same address (with different instructionOffset)

focusStackFrame -> goToIntructionAndOffset -> loadDisassembledInstructions instructionCount: 50, instructionOffset; 0, instructionReference: "0x420395e4", offset: 0
focusStackFrame -> setFocus -> fire -> goToIntructionAndOffset -> loadDisassembledInstructions instructionCount: 100, instructionOffset; -50, instructionReference: "0x420395e4", offset: 0

... and a 2nd sidenote.. maybe have a look into the documentation of the disassembly view from espressif. If you look carefully, you will see that the displayed instructions are all illegal.

... and forgot about your question whether I am sure..
sc_debug3

In case it does not repro for you.. I think it might be forced when you step thru disassembly into a new callx8 or call8 instruction.

So after rereading your comment:
args.memoryReference is the base for the calculation. It is a string, that in my case represents an address.. I believe for other scenarios it can be a symbol or a label too. This is why it is a string.
offset counts forward in bytes from memoryReference. I have not observed other values than 0 so far during debugging.
instructionCount is the number of instructions counted from the location of args.memoryReference + offset.
By giving you a negative instructionCount, VSC manages to get a couple instructions in front of the instruction of interest. The value is likely connected to the window vertical window size of the disassembly window. So as args.memoryReference works like a label, VSC calculates the actual address based on the label + instructionCount (I think).

Manual debugging confirmed args.memoryReference and offset to have to correct values.

Copy link

This issue has been marked as stale since there are no activities, and this will be closed in 5 days if there are no further activities

@github-actions github-actions bot added the stale Stale PR or Issue label Jan 30, 2025
@github-actions github-actions bot closed this as completed Feb 4, 2025
@brianignacio5 brianignacio5 reopened this Feb 5, 2025
@brianignacio5 brianignacio5 reopened this Feb 11, 2025
@brianignacio5 brianignacio5 added ongoing Ongoing Issue or PR, this label will be used for issue or PR which is to be excluded by stale bot and removed stale Stale PR or Issue labels Feb 11, 2025
@osnwt
Copy link

osnwt commented Feb 19, 2025

Same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug-report Bug Report from users on Github (don't use this tag manually, its supposed to be used via the issue) ongoing Ongoing Issue or PR, this label will be used for issue or PR which is to be excluded by stale bot
Projects
None yet
Development

No branches or pull requests

3 participants