WebFreak001 / code-debug

Native debugging for VSCode
The Unlicense
409 stars 115 forks source link

[enhancement] Support source file browsing #397

Open ereisch opened 1 year ago

ereisch commented 1 year ago

Many debuggers offer an option to browse to a specific source file. As an executable may include source files outside the project (e.g., in shared or static libraries), parsing the output of "info sources" and displaying the results for a user to open a specific source file to set a breakpoint could be very helpful.

ereisch commented 1 year ago

Example situation for clarification:

A project exists where User A is developing libhis_thing.a, and User B is developing libher_thing.a, and User C links both libraries into their own independent executable. When debugging, they may not know which particular source path Users A and B were using when they built their libraries, so the simple "File->Open File" may be cumbersome in this situation. Since the file paths to all sources used in the executable are already stored in the DWARF info in the executable, parsing this info out from gdb (via "-file-list-exec-source-files") and making it available to a targeted file browser would be very beneficial to this workflow.

GitMensch commented 1 year ago

Just to check if I got that idea correctly:

That would be similar to entering one of -file-list-exec-source-files or info sources into the debugging console (that is possible already today), but present it in a way that you don't need to copy the interesting source path [CTRL]-[C], file-open [CTRL]+[O], insert [CTRL]+[A], [DEL], [CTRL]+[V], right? It is a pity that you can nearly click on a path "anywhere" and have vscode using it a a file link, but not in the debugging console.

If we could just output the data to a new "pseudo-terminal" then users could click on those... - but then, having file links working in the debug console seems like a reasonable FR for vscode in general as debuggers are not unlikely to output relevant file paths in there console - @ereisch could you please check if that exists/otherwise create it and link it here? If that exists there's no need for the workaround to create a pseudo-terminal.

For the FR in this repo:

Workaround for now: get the list in the debugging console, then copy+paste-to-open; a useful way to get the list for all files that have source information available for me is:

pipe info sources | grep "usr/include" | awk -F ', ' '{for(i=1; i<=NF; i++) print $i}' | grep -v "\\.h$" | sort -u:

ereisch commented 1 year ago

A console listing may be onerous, as some projects may contain thousands of files. Perhaps a dialog using window.showQuickPick() (if I'm understanding the API correctly)?

GitMensch commented 1 year ago

That could be a way: add a new command in the extension, that would then have to "connect" to the current debugging session (there is an example in the single command currently available in the extension: "examine memory"), execute -file-list-exec-source-files there, place every fullname attribute contained in the response to a (Hash?)Map (to drop duplicates) then get an String[] out of it and, then pass that to window.showQuickPick and open the chosen option in the editor. That could be a contributed command code-debug.openSourceFile.

I guess that fullname is only available if the debugger can resolve the path, so if you need to setup source name translation ( set substitute-path) / directory first that won't help - and for that another command could be created, something like code-debug.listUnavailableSourceFiles.

Do I get the idea right?

ereisch commented 1 year ago

Correct; I don't know that the debugger attempts to resolve paths on its own; I believe those paths returned are simply as they are placed in the DWARF info (for ELF files). So if you compiled a file with "gcc ./src/my_file.c", all you would get in the DWARF info would be "./src/my_file.c". Courteous programmers should be using absolute paths if working in a shared development environment on centrally-mapped drives, or relative paths if working out of a common repo, which means Code should be able to resolve them if working in the same environment or in a clone of the same repo, respectively.

Overall, the file resolution logic should be identical to whatever code-debug is presently using to resolve a path presented by gdb when you 'step' or 'break' into a routine that is in a different file than is currently open.

P.S. -- I wouldn't attempt to filter out *.h files, etc., since C++ is known for including executable lines in header files. Excluding all system-level headers is probably acceptable, but better to include extra stuff to filter through rather than make it extremely difficult (or impossible) for the programmer to get to something they need.