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

Case mismatch in setBreakpoints requests in a single session #232088

Open
nisargjhaveri opened this issue Oct 23, 2024 · 2 comments · May be fixed by #232791
Open

Case mismatch in setBreakpoints requests in a single session #232088

nisargjhaveri opened this issue Oct 23, 2024 · 2 comments · May be fixed by #232791
Assignees
Labels
info-needed Issue requires more information from poster

Comments

@nisargjhaveri
Copy link
Member

Does this issue occur when all extensions are disabled?: Yes

  • VS Code Version: 1.94.2
  • OS Version: Windows 11

Issue:
In some cases, the setBreakpoints requests sent in the same session sends the path with different cases. Especially on case-insensitive file systems. This causes broken breakpoint experience on some debugger. Currently tested with CodeLLDB and android-debug on Windows. Issue is fairly easy to repro and affects across machines and projects.

Debugging details:
After some debugging, here is what I gathered.

The issue boils down to the two different paths taken by getRawSource. For a local file, if this.sources contains an entry for that URI, it directly returns source.raw. Otherwise, it returns name and path using canonical URI.

private getRawSource(uri: URI): DebugProtocol.Source {
const source = this.getSourceForUri(uri);
if (source) {
return source.raw;
} else {
const data = Source.getEncodedDebugData(uri);
return { name: data.name, path: data.path, sourceReference: data.sourceReference };
}
}

Form what I saw this.sources is populated when resolving frames on a breakpoint hit. The debugger sends frames with raw source info. That info is stored and used as is once available.

The issue arises when the canonical path and the raw source from debugger doesn't match. e.g. canonical path is <path>/Native-Lib.cpp but the debugger reported <path>/native-lib.cpp. This means that until the this.sources was populated for this Uri, we sent <path>/Native-Lib.cpp when setting breakpoints. And later, we send <path>/native-lib.cpp. This mismatch causes lldb to treat the paths differently and duplicate breakpoints.

Potential solution:

  • Instead of using the sources.raw as is as reported by the debugger, should we always use canonical path when setting breakpoints?
  • Anything else can be done to prevent this?
@roblourens
Copy link
Member

Yeah, there is a larger issue here, also related: #210854. I'll look at your PR, but the implications are a little confusing and it might be a partial fix.

Why does the debugger return a different casing? Which is "correct"?

@roblourens roblourens added the info-needed Issue requires more information from poster label Nov 1, 2024
@nisargjhaveri
Copy link
Member Author

At the time of initialization or early in debugging, the raw Source from debugger is not present for most breakpoints. At this point, we create a new raw source using Source.getEncodedDebugData. See the below snippet.

const data = Source.getEncodedDebugData(uri);
return { name: data.name, path: data.path, sourceReference: data.sourceReference };

This generally returns the canonicalized path which the editor decides.

The debug adapter also sends Sources in different contexts as I can see, one of them being stack trace when a breakpoint hits. All the sources sent by the debug adapter are then cached in this.sources with the canonical uri as the key. Later when setting a breakpoint, this cached raw source from debug adapter is used as is.

const source = this.getSourceForUri(uri);
if (source) {
return source.raw;
} else {

The issue occurs when the initial source created using Source.getEncodedDebugData and the Sources sent by debug adapter has different casing for path. This can happen for various reasons on a case-insensitive file systems as different systems have different assumptions and different ways of handing the case-insensitivity.

This results in different setBreakpoint requests to have differently cased path for the same file on the editor side. This creates issues with some debuggers as noted in the issue.

The "correct" casing can be debated, but I'd assume it is safe to send the canonical path which matches the file system. In any case, for this particular issue, "correct" might not be that important, but "consistent" is, since the issue only occurs because of difference in path handling in editor and debug adapter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
info-needed Issue requires more information from poster
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants