Skip to content

[VS Code] Add memory view, assembly view and debugging for C/C++ #816

Closed

Description

Referencing this issue in the cpptools repo, I would be willing to try and implement the feature if I could get a few examples or pointers of how the engine code interacts with gdb and vs code.

Activity

  1. gregg-miskelly commented on Dec 14, 2018

    @gregg-miskelly
    Member

    This is a fairly large amount of work to take on. So if you have the cycles, that would be very cool, but you might find this a bit scary.

    You wouldn't actually need to interact with GDB at all -- all that work is already done because this project supports disassembly and memory in full Visual Studio.

    Here is the work that is needed:

    1. The C++ extension (or VS Code itself) needs to provide a disassembly window. Assuming this is done in the extension, I believe this would need to work by having the C++ extension provide HTML/CSS back to VS Code for VS Code to render using the VS Code Webview API. This is probably the single biggest work item. There would also need to be code to kick off the web view. I recently have been looking at adding a 'set next statement' command for C# which is slightly similar (it adds a command to the context menu, which we would probably want as one of the gestures for bringing up the disassembly window -- https://github.com/OmniSharp/omnisharp-vscode/blob/master/src/coreclr-debug/setNextStatement.ts) that might get you slightly started.
    2. A protocol needs to be worked out between the debug adapter and the UI. This doesn't necessarily need to be an official part of the protocol. But it probably does make sense to at least propose something to avoid breaking changes if VS Code later creates something of their own. The protocol is at https://github.com/Microsoft/debug-adapter-protocol/blob/gh-pages/debugAdapterProtocol.json.
    3. The OpenDebugAD7 layer needs to implement the new request to obtain disassembly. To actually fetch diassembly, use IDebugProgram2.GetDisassemblyStream which the MIEngine already implements here.
  2. changed the title [-]Add memory view and assembly view and debugging for C/C++[/-] [+]Add memory view, assembly view and debugging for C/C++[/+] on Dec 16, 2018
  3. Izikiel commented on Dec 16, 2018

    @Izikiel
    Author

    Ok, I will check how to create a webview and populate it

  4. changed the title [-]Add memory view, assembly view and debugging for C/C++[/-] [+][VS Code] Add memory view, assembly view and debugging for C/C++[/+] on Jan 16, 2019
  5. haneefdm commented on Mar 10, 2019

    @haneefdm
    Contributor

    Hi Ezequiel Darío Gambaccini (@Izikiel) did you make any progress? I am interested in the same features but for me, a register view is very important. If you have already started, I want to help. I am an experienced C/C++/C# developer on desktop and embedded software.

    Yes, I have the cycles for the next three months -- near full+ time. Half/part time after that.

    Gregg Miskelly (@gregg-miskelly) is spot on. Non trivial work for sure. It is easy to see the user point of view but there are some architectural issues that involve VSCode base, MIEngine and cpptools. There are also presentation decisions. For instance, a (optional) register view can go along with the existing set of views for Variables, Watch, Stack, etc. But memory and disassembly views (with inline source) require a lot of real estate and might require their own window(s) in the document area.

    Technically, almost everything can go into cpptools or an extension of my own but I was thinking that any natively compiled code can benefit from these features. Not specifically for C/C++. Last thing I want is to create my own extension/debug-adapters when these features are generally needed by the community.

    Please let me know how I can help contribute ... the right way. I am requesting the architects of VSCode base, MIEngine, OpenDebugAD7 and cpptools to discuss, review and approve of a plan, I will do the rest. I just don't know how to contact them all. Pierson Lee (@pieandcakes) could perhaps guide me? I see similar requests on cpptools as well.

    Please PM me

  6. haneefdm commented on Mar 13, 2019

    @haneefdm
    Contributor

    Gregg Miskelly (@gregg-miskelly), looks like Pierson Lee (@pieandcakes) is on vacation until May 1st. Is there someone on the MIEngine or cpptools team that I could converse with?

  7. gregg-miskelly commented on Mar 14, 2019

    @gregg-miskelly
    Member

    Hi Haneef Mohammed (@haneefdm), thanks for your interest!

    Based on microsoft/vscode#31901, I don't think the VS Code team will have any interest in adding a disassembly window or memory window to VS Code. But you can open a new issue to ask if they would be willing to accept one. If not, adding it through the C++ extension should be fine. We just should be careful to keep the code isolated so that we can use it other places in the future.

    Let me follow up with some others and I will try to get back to you tomorrow with some guidance.

  8. haneefdm commented on Mar 14, 2019

    @haneefdm
    Contributor

    Thanks Gregg Miskelly (@gregg-miskelly)

    Yeah, I had very little hope the vscode core would entertain this, but I thought they should be in the loop just in case. I thought it was between MIEngine and vscode-cpptools. If another extension is preferable, then it would be nice if MIEngine and vscode-cpptools themselves are extensible for custom commands to the debugger. Would hate to duplicate all that great work. I already saw a couple of extensions that did that. I was thinking beyond my needs that it doesn't have to be C/C++ specific.

  9. haneefdm commented on Mar 14, 2019

    @haneefdm
    Contributor

    Also, my belief is that MIEngine already has basic support for registers and memory, etc. Even stepping through assembly code (stepi, nexti). Just presenting them to the user in a UI is what is missing in the end

  10. gregg-miskelly commented on Mar 14, 2019

    @gregg-miskelly
    Member

    Yeah, I had very little hope the vscode core would entertain this, but I thought they should be in the loop just in case. I thought it was between MIEngine and vscode-cpptools. If another extension is preferable, then it would be nice if MIEngine and vscode-cpptools themselves are extensible for custom commands to the debugger.

    Yes, I definitively think it should be done with as few ties as possible to MIEngine and/or cpptools. You are certainly welcolme to talk to the VS Code folks on that issue and see if they would accept a PR. Either way, we want to design an extension to the Debug Adapter Protocol which the disassembly/memory windows can consume. This could either be done as an npm package, or just by keeping the code isolated enough inside the cpptools repo that if another component wants it the code is easy to.

    Also, my belief is that MIEngine already has basic support for registers and memory, etc. Even stepping through assembly code (stepi, nexti). Just presenting them to the user in a UI is what is missing in the end

    For the disassembly and memory windows -- MIEngine should already have the support we need. It is just a matter of adding debug protocol elements for them and then connecting that to the debug protocol by enhancing OpenDebugAD7.

    For registers - I am thinking we might be better off just reusing either the watch window (by adding a '$registers' pseduo-variable) or by reusing the locals variable (by adding a custom scope for registers) rather than designing a registers window since such a window would need to be in the document well in VS Code and I am not sure that is really where folks would want it.

  11. haneefdm commented on Mar 25, 2019

    @haneefdm
    Contributor

    I made some progress, but I need help getting events when the debugger stops and continues to properly refresh a register view. I made a feature request here. My only testing so far has been with lldb on MacOS and gdb on an ARM board attached to my Mac. Will test soon on Windows.

    I posted my progress on adv-cppdbg as a separate extension (not ready for marketplace anytime soon)

    Please visit https://github.com/haneefdm/adv-cppdbg

    Gregg Miskelly (@gregg-miskelly) has a better idea (than mine) for registers is to create a fake global scope that contains all the registers. For performance reasons (and usability) I like a global scope (that is what they are) vs. the Watch window. I just took it as far as I could left to my own devices :-)

    I know this thread is about memory and disassembly views. Disassembly view is very involved but limiting without a Register view. So, I started there (baby steps). I know how to do a disassembly view especially for embedded folks but I don't think I have the needed API's to do it as an extension.

  12. ci70 commented on May 9, 2019

    @ci70

    What is the status on this?

  13. pieandcakes commented on May 9, 2019

    @pieandcakes
    Collaborator

    @optomux I think Haneef Mohammed (@haneefdm) (thank you!) is working on this during their free time.

  14. haneefdm commented on May 10, 2019

    @haneefdm
    Contributor

    Thanks to Pierson Lee (@pieandcakes),] & Gregg Miskelly (@gregg-miskelly) I got my major hurdle (almost) out of the way #844 and #855. Needed that to justify working on the rest.

    The DAP spec has to be enhanced first and adopted/prototyped before they can be implemented in MIEngine/cpptools or another extension. Thanks to Andrew Crawley (@andrewcrawley) for the following proposals

    Registers: microsoft/debug-adapter-protocol#41
    Memory / Disassembly: microsoft/debug-adapter-protocol#42

    Sorry, I've been away for a while but now I am back. Looking forward to taking a deep dive.

    We can implement views/windows without a spec change (outside of MS debug tools), but will not be pretty or efficient or generally available. The protocol proposals are for more than just C/C++, and it would be good to have them formalized.

  15. andrewcrawley commented on May 29, 2019

    @andrewcrawley
    Contributor

    Moving this discussion off of the defunct protocol proposal PR:

    Haneef Mohammed (@haneefdm):

    Gregg Miskelly (@gregg-miskelly) may I ask what the next steps are? and where I can help? my first wish is 'registers'

    I'm currently working on putting out a new version of the NuGet package that MIEngine uses to implement the Debug Adapter Protocol. Once the new version with the new protocol objects is out, you'll need to do the following to implement registers:

    1. In OpenDebugAD7's HandleScopesRequestAsync method, call EnumProperties on the frame again, passing the GUID for the "registers" filter (223ae797-bd09-4f28-8241-2763bdc5f713).
    2. If any properties are returned, the frame has registers, and you should emit a "Registers" scope with presentationHint set to registers and expensive set to true.
    3. Make other changes to OpenDebugAD7 to handle a variables request against that scope.

    Note that (as I described in the original registers proposal), VS uses a two-level structure for registers, where the set of register properties returned from a stack frame represent register categories (e.g. "CPU", "CPU Flags", etc), and those properties contain the actual registers and their values.

    Feel free to email me if you have specific implementation questions once the new NuGet package is out and you have a chance to get into this!

  16. 20 remaining items

  17. haneefdm commented on Aug 6, 2020

    @haneefdm
    Contributor

    Andrew Wang (@WardenGnaw)

    I couldn't find where you implemented this. I'll wait for your PR to the hextools extension.

    Yes, it is on a separate branch on our debugger that I have not published yet. I will provide the details soon A lot of it is already there for our old memory viewer It was done a long time ago by the wonderful author of that extension. I enhanced it a bit and trying for more

    I see this is just using the DebugAdapterTracker from the vscode package.

    Yes, but we used custom events generated from our own debug adapter. Again it was done a while ago. We should migrate to the DebugAdapterTracker but have not had the time to do so. It actually simplifies a few things. We also have to make sure we are responding to the right debugger session

  18. haneefdm commented on Aug 12, 2020

    @haneefdm
    Contributor

    The first step is done. I did a PR to use a non-zero base address and I hope it will be accepted

    microsoft/vscode-hexeditor#170

  19. haneefdm commented on Aug 12, 2020

    @haneefdm
  20. WardenGnaw commented on Aug 12, 2020

    @WardenGnaw
    Member

    I also have handled the DAP ReadMemory Request in a seperate branch and will be testing it with a modified VS Code C++ Extension that does the DebugAdapterTracking and can open the HexEditor with the URI.

  21. haneefdm commented on Aug 12, 2020

    @haneefdm
    Contributor

    What I did in my debugger extension frontend, once you have read the bytes from the debugger (gdb, llvm, etc.) is to write the data to a file and create a URI. My URI fsPath contains a C-Expression (instead of an address) which can fail because of invalid chars when writing to the file. For now, we left the URI the same and switchable between our memory viewer vs the new one. I still need to make sure my error handling is right, so please ignore that Please don't take the code below literally.

                    const filePath = path.join(vscode.workspace.workspaceFolders[0].uri.fsPath, '.vscode', 'cdmem', uri.fsPath);
                    const fsURI = vscode.Uri.parse(`file://${filePath}?baseAddress=${data.startAddress}`);
                    vscode.workspace.fs.writeFile(fsURI, Uint8Array.from(data.bytes)).then(() => {
                        vscode.commands.executeCommand("vscode.openWith", fsURI, "hexEditor.hexedit", { preview: false });
                        resolve('succesz');
                    }, (error) => {
                        const msg = (error.message || '') + '\nPerhaps expression for "address" contains invalid file name characters';
                        vscode.window.showErrorMessage(`Unable to create/write memory file memory from ${fsURI.toString()}: ${msg}`);
                        reject(error.toString());                    
                    });

    I have a problem right now that I am looking for a solution. Since the code above executes everytime the debugger pauses, it changes focus in a bad way (normal revert does not trigger showing stale contents although file on disk changed) and it changes the active window. Just FYI. Neither of that is good. I want to create a new window only if it does not already exist but since the hexeditor is a virtual document, I don't know if it was already has been created. I don't want to call vscode.commands.executeCommand if the window/tab already exists. I did not see a way to iterate/enumerate over virtual docs. This is actually a serious problem, I hope I will figure it out.

    When the debugger pauses for whatever reason, the focus should be on the code location and not the memory window(s). You can have multiple.right? Baby steps :-)

  22. Trass3r commented on Aug 24, 2020

    @Trass3r
    Contributor

    Just for the record, I have a crude but working prototype for disassembly debugging when no source is available.

  23. RazCrimson commented on Sep 22, 2020

    @RazCrimson

    Can u provide something like a preview of the extension? I(a student) am supposed to learn Assembly this semester and it seems like this will make debugging raw assembly code a lot more easier than running a bunch of -exec info registers.

  24. vannaka commented on Sep 22, 2020

    @vannaka

    @RazCrimson3 A great solution while your waiting on this is to configure gdb with register and memory views. See this config file: here. This gdb init file is a whole other experience to what you're used to with gdb, check it out.

  25. Trass3r commented on Sep 23, 2020

    @Trass3r
    Contributor

    @RazCrimson3 I recommend using the CodeLLDB extension or gdbgui until this is ready.

  26. RazCrimson commented on Sep 23, 2020

    @RazCrimson

    Luke Mammen (@vannaka) Trass3r Thank you for your recommendations, will try them out!

  27. WardenGnaw commented on Aug 31, 2021

    @WardenGnaw
    Member

    DAP Protocol for Disassembly and Memory have been implemented in MIEngine. The associated UI requirements are on VS Code.

    Please follow the following issues:

  28. locked as resolved and limited conversation to collaborators on Aug 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions