-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lldb-dap] Show assembly depending on stop-disassembly-display
settings
#136494
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
[lldb-dap] Show assembly depending on stop-disassembly-display
settings
#136494
Conversation
@llvm/pr-subscribers-lldb Author: Ely Ronnen (eronnen) ChangesShow assembly code when the source code for a frame is not available in the debugger machine Fix #136492 After the fix: Screencast.From.2025-04-20.18-00-30.webmFull diff: https://github.com/llvm/llvm-project/pull/136494.diff 1 Files Affected:
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp
index 33f10c93d2ada..5b647950cfc6e 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -750,9 +750,11 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame,
EmplaceSafeString(object, "name", frame_name);
auto line_entry = frame.GetLineEntry();
+ auto file_spec = line_entry.GetFileSpec();
// A line entry of 0 indicates the line is compiler generated i.e. no source
// file is associated with the frame.
- if (line_entry.GetFileSpec().IsValid() &&
+ if (file_spec.IsValid() &&
+ file_spec.Exists() &&
(line_entry.GetLine() != 0 ||
line_entry.GetLine() != LLDB_INVALID_LINE_NUMBER)) {
object.try_emplace("source", CreateSource(line_entry));
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
f9d6bcd
to
c7da2d8
Compare
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 change LGTM but please add a test. You should be able to remove the source file between building and launching LLDB. I believe there are some examples of that in the LLDB test suite.
Maybe I'm missing something, but I disagree with this change. We're talking about when you're stopped in a stack frame that has debug info (a file and line number), but the source file is unavailable, right. There is a setting to control this behavior already -- People who are debugging at a source level, generally, do not want to see assembly, and in fact will be confused if they are shown assembly. We do not want to show assembly for a stack frame where we have a debug filename and line number, by default. The user may not have set up the target.source-map to map lldb to the source file, and could be looking at it in another source window as they're stepping, or they may know roughly how many lines a method has as they step through it. The assembly only adds distraction to them. Am I misunderstanding what we're talking about here? |
@jasonmolenda fair enough, but still as a user who would like to see assembly instead of an error when the source is not available I don't have any solution currently. If I were to check the |
One side note, I was commenting while not 100% awake and didn't realize this was only in the DAP side of the codebase, I have less weight to argue one way or the other there. After I posted that I was like, I wonder why I didn't see the My comment is much weaker when it's only impacting the DAP replies, fwiw. I think from a UI perspective defaulting to not showing assembly when we have filename & line number is the best tradeoff for users, but like most UI things it's debatable. I think using |
Just to be super clear, if we were talking about core lldb behavior, I would be insistent about how it behaves. But we're talking about DAP and i'm just a bystander on that part of the codebase, and my feedback is just an opinion that you might want to consider, but don't feel like you need to address my point. |
c7da2d8
to
d2062b8
Compare
✅ With the latest revision this PR passed the Python code formatter. |
d2062b8
to
dd8735e
Compare
I refactored the code now to use the |
Maybe this setting should be exposed in the vscode launch configuration so it will be more findable for users though |
stop-disassembly-display
settings
lldb/tools/lldb-dap/LLDBUtils.cpp
Outdated
debugger.GetCommandInterpreter().HandleCommand( | ||
"settings show stop-disassembly-display", result); | ||
if (result.Succeeded()) { | ||
std::string output = result.GetOutput(); | ||
size_t pos = output.find("stop-disassembly-display"); | ||
if (pos != std::string::npos) { | ||
size_t start = output.find("= ", pos) + 2; | ||
size_t end = output.find("\n", start); | ||
stop_disassembly_display = | ||
output.substr(start, end - start); // trim whitespace | ||
} | ||
} |
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.
Can this use SBDebugger::GetSetting
?
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.
Changed it to SBDebugger::GetSetting
now, apparently OptionValueEnumeration::ToJSON
implementation was missing
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.
created a pull request. I made the change for some time but forgot to push it.
dd8735e
to
cd8941d
Compare
if (m_enumerations.GetValueAtIndexUnchecked(i).value == m_current_value) { | ||
return m_enumerations.GetCStringAtIndex(i).GetStringRef(); | ||
} |
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 (m_enumerations.GetValueAtIndexUnchecked(i).value == m_current_value) { | |
return m_enumerations.GetCStringAtIndex(i).GetStringRef(); | |
} | |
if (m_enumerations.GetValueAtIndexUnchecked(i).value == m_current_value) | |
return m_enumerations.GetCStringAtIndex(i).GetStringRef(); |
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/tools/lldb-dap/DAP.h
Outdated
/// The value of stop-disassembly-display setting in LLDB. | ||
std::string stop_disassembly_display; |
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'm wondering if we should be caching this. Querying the debugger for a setting should be cheap enough that we could do it whenever we need to know. The added benefit is that you'll be able to change the setting and have it take immediate effect, while with the current approach you'd have to create new debug session.
Personally I'm leaning toward computing this once per request.
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.
Agree, changed it
lldb/tools/lldb-dap/LLDBUtils.cpp
Outdated
return result_string; | ||
} | ||
|
||
return "no-debuginfo"; |
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 like hard-coding a default value here. If for whatever reason this ever were to change, that person needs to remember to do the same thing here. Instead, could we make this return a std::optional<std::string>
.
Even better, instead of having this return a string, I would create a new enum for this setting in lldb-dap and have this return an enum value instead of a string. If we move the enum from Debugger.h
into lldb-enumerations.h
we can parse it with an llvm::StringSwitch and reuse it across lldb-dap.
enum StopDisassemblyType {
eStopDisassemblyTypeNever = 0,
eStopDisassemblyTypeNoDebugInfo,
eStopDisassemblyTypeNoSource,
eStopDisassemblyTypeAlways
};
I guess that would still require a default value, but at least it's easier to grep for the enum value than for the corresponding string.
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.
not sure I understand the suggestion, do you mean having an alternative setting in the lldb-dap launch configuration and use it instead of debugger.GetSetting
, or just export the existing StopDisassemblyType
enum and convert the current GetSetting
to use 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.
anyway I moved the enum to lldb-enumerations.h
326bdd3
to
2ec7e34
Compare
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 exactly what I had in mind, thank you! This LGTM modulo the nit.
@@ -1383,6 +1383,14 @@ enum CommandReturnObjectCallbackResult { | |||
eCommandReturnObjectPrintCallbackHandled = 1, | |||
}; | |||
|
|||
// Used to determine when to show 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.
// Used to determine when to show disassembly | |
/// Used to determine when to show 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.
💯
f13a16f
to
19dc107
Compare
@JDevlieghere Fixed comments and conflicts with |
...test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py
Outdated
Show resolved
Hide resolved
...test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py
Outdated
Show resolved
Hide resolved
...test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/TestDAP_stackTraceDisassemblyDisplay.py
Outdated
Show resolved
Hide resolved
lldb/test/API/tools/lldb-dap/stackTraceDisassemblyDisplay/main.c
Outdated
Show resolved
Hide resolved
@da-viper Fixed your comments, also now that the |
@@ -0,0 +1,8 @@ | |||
#include <stdint.h> |
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.
don't need the header
#include <stdint.h> |
LGTM |
@JDevlieghere any chance to merge? |
There's a conflict in |
c9dd464
to
caf6db4
Compare
fix TestDAP_coreFile.py with source maps use stop-disassembly-display setting to determine when to show disassembly * Use GetSetting instead of Handle command * Implement OptionValueEnumeration::ToJSON export StopDisassemblyType enum fix comment cleaner stackTraceDisassemblyDisplay tests remove include in main.c in test
caf6db4
to
4061321
Compare
@JDevlieghere You can merge :) |
…ings (llvm#136494) Show assembly code when the source code for a frame is not available in the debugger machine Edit: this functionality will work only when using `stop-disassembly-display = no-source` in the settings Fix llvm#136492 After the fix: [Screencast From 2025-04-20 18-00-30.webm](https://github.com/user-attachments/assets/1ce41715-cf4f-42a1-8f5c-6196b9d685dc)
…ings (llvm#136494) Show assembly code when the source code for a frame is not available in the debugger machine Edit: this functionality will work only when using `stop-disassembly-display = no-source` in the settings Fix llvm#136492 After the fix: [Screencast From 2025-04-20 18-00-30.webm](https://github.com/user-attachments/assets/1ce41715-cf4f-42a1-8f5c-6196b9d685dc)
…ings (llvm#136494) Show assembly code when the source code for a frame is not available in the debugger machine Edit: this functionality will work only when using `stop-disassembly-display = no-source` in the settings Fix llvm#136492 After the fix: [Screencast From 2025-04-20 18-00-30.webm](https://github.com/user-attachments/assets/1ce41715-cf4f-42a1-8f5c-6196b9d685dc)
…ings (llvm#136494) Show assembly code when the source code for a frame is not available in the debugger machine Edit: this functionality will work only when using `stop-disassembly-display = no-source` in the settings Fix llvm#136492 After the fix: [Screencast From 2025-04-20 18-00-30.webm](https://github.com/user-attachments/assets/1ce41715-cf4f-42a1-8f5c-6196b9d685dc)
…ings (llvm#136494) Show assembly code when the source code for a frame is not available in the debugger machine Edit: this functionality will work only when using `stop-disassembly-display = no-source` in the settings Fix llvm#136492 After the fix: [Screencast From 2025-04-20 18-00-30.webm](https://github.com/user-attachments/assets/1ce41715-cf4f-42a1-8f5c-6196b9d685dc)
Show assembly code when the source code for a frame is not available in the debugger machine
Edit: this functionality will work only when using
stop-disassembly-display = no-source
in the settingsFix #136492
After the fix:
Screencast.From.2025-04-20.18-00-30.webm