-
Notifications
You must be signed in to change notification settings - Fork 222
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
Implement disassembly debugging #1041
Conversation
@@ -2252,6 +2258,8 @@ private Task<string> ResetConsole() | |||
|
|||
public bool IsChildProcessDebugging => _childProcessHandler != null; | |||
|
|||
public string[] Features { get; private set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: instead of exposing an array, use a IReadOnlyCollection<string>
. You probably also want to initialize it to an empty collection since we will only have it for GDB.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lldb doesn't implement that part of the MI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You put your code that populates under an 'if (gdb)' path. I don't know for sure if LLDB supports -list-features
or not, but your code will not assign to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's probably better as a virtual method in the factory like in the other PR.
BeforeContinue(); | ||
ErrorBuilder builder = new ErrorBuilder(() => errorMessage); | ||
m_isStepping = true; | ||
if (!m_currentFrameHasSourceCode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_currentFrameHasSourceCode [](start = 17, length = 27)
- We need to add a client check here -- we don't want to do this in full Visual Studio (or other IDEs that have full disassembly support)
- We should probably check if the top frame of the specified thread has source, since the user can switch threads.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used in VS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
response.StackFrames.Add(new ProtocolMessages.StackFrame() | ||
// remember the state for the lowermost frame | ||
if (startFrame == 0 && i == 0) | ||
m_currentFrameHasSourceCode = textPosition.Source?.Path != null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_currentFrameHasSourceCode [](start = 28, length = 27)
You will wind up setting this to true if the top frame of any thread doesn't have source. It needs to be changed to a Dictionary/HashSet. I would probably also suggest changing the name from 'current' to 'top' since 'current frame' has another meaning that can be confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depends on the UI I guess. VSCode probably fetches only the current thread so it works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, VS Code fetches the stack of all threads very aggressively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Haven't noticed any fallout yet though.
While without the if I have. All frames of a thread were marked.
{ | ||
int sourceRef = (int)source.SourceReference; | ||
string content = TextPositionTuple.GetSourceForRef(sourceRef); | ||
response.MimeType = "text/x-lldb.disassembly"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x-lldb [](start = 42, length = 6)
Does something in VS Code already understand this type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's borrowed from the CodeLLDB extension.
Asm CodeLens doesn't support this kind of disassembly yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what VS Code uses the MimeType for. Does it matter what we put? Does it matter if CodeLLDB isn't installed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it isn't installed you won't get syntax highlighting. If it is you will.
@@ -24,30 +36,132 @@ private TextPositionTuple(Source source, int line, int column) | |||
public static TextPositionTuple GetTextPositionOfFrame(PathConverter converter, IDebugStackFrame2 frame) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetTextPositionOfFrame [](start = 40, length = 22)
Similar to my suggestion in the other review - you don't want to do this here, but rather in HandleStackTraceRequestAsync because there is no need to do this stuff for stopping event processing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well here it's deliberate, sort of. VSCode didn't use the stopped event source but maybe other clients do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The source in the stopped event was actually an extension added long ago to support testing. It should be fine to just use the original path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, something to add to the spec.
} | ||
|
||
// this frame is lacking source code | ||
source.Name = Path.ChangeExtension(source.Name, ".s") ?? "???"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name [](start = 54, length = 4)
source.Name
may be null. If your goal is to make a document of the disassembly of this function, maybe something like: Disassembly: <Func-Name>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which is fine according to the ChangeExtension docs.
The goal is to make file extension based syntax highlighting work.
|
||
return new TextPositionTuple(source, line, column); | ||
return new TextPositionTuple(source, srcline, srccolumn); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} [](start = 12, length = 1)
A few comments for the rest of this:
- We need a client check - we don't want to do this stuff with an IDE that has real disassembly support
- I don't think you want to do the disassembly up front. Instead we should keep a collection of sourceReferences and do the disassembly when the IDE requests source.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense.
The thing is there seems to be no way to find the start of the current function in gdb.
So different address requests belonging to the same function without actually disassembling seem to be impossible to relate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like VS uses DisassembleRequest though?
b2a5c7a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, in the VS case, we want to return whatever source path we have in the symbols. VS is fine with source paths that don't exist and will request disassembly if that is what the user chooses to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But how to handle this? I guess there'd need to be a client support flag to do it properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean how to check for VS? If yes, Gabrielle added support for this to AD7Session recently: https://github.com/gregg-miskelly/MIEngine/blob/896c72d633b39a0571b9599d15c5a8fd0f1fcf58/src/OpenDebugAD7/AD7DebugSession.cs#L632-L638
…ence implemented in TextPositionTuple so both StackTrace and StoppedEvent get it even though the stopped event source is currently not used by vscode for now we leverage CodeLLDB's disasm language definition
display stack frames without source differently in the UI
@Trass3r The VS Code team is currently working on a real disassembly window: microsoft/vscode#124163 so I don't think we will need this anymore. |
Yeah I know. Closing this. |
Proof of concept of disassembly debugging.
Will fix part of #816 and microsoft/vscode-cpptools#206.
Working:
Not working (in order of importance):
-data-disassemble -a
to get the entire current function: https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Data-Manipulation.html