-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lldb-dap] Prevent using an implicit step-in
.
#143644
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#ifndef NUMBER_H | ||
#define NUMBER_H | ||
|
||
#include <cstddef> | ||
|
||
template <std::size_t Size> class Numbers { | ||
public: | ||
using ValueType = int; | ||
using PointerType = ValueType *; | ||
using ReferenceType = ValueType &; | ||
|
||
class Iterator { | ||
// all the operators needs to be inlined so that there is no call | ||
// instruction. | ||
public: | ||
__attribute__((always_inline)) explicit Iterator(PointerType ptr) | ||
: m_ptr(ptr) {} | ||
|
||
__attribute__((always_inline)) Iterator &operator++() noexcept { | ||
++m_ptr; | ||
return *this; | ||
}; | ||
|
||
__attribute__((always_inline)) Iterator operator++(int) noexcept { | ||
Iterator iter = *this; | ||
m_ptr++; | ||
return iter; | ||
} | ||
|
||
__attribute__((always_inline)) ReferenceType operator*() const noexcept { | ||
return *m_ptr; | ||
} | ||
__attribute__((always_inline)) bool | ||
operator==(const Iterator &iter) noexcept { | ||
return m_ptr == iter.m_ptr; | ||
} | ||
__attribute__((always_inline)) bool | ||
operator!=(const Iterator &iter) noexcept { | ||
return !(*this == iter); | ||
} | ||
|
||
private: | ||
PointerType m_ptr; | ||
}; | ||
|
||
PointerType data() { return static_cast<PointerType>(m_buffer); } | ||
|
||
Iterator begin() { return Iterator(data()); } | ||
Iterator cbegin() { return Iterator(data()); } | ||
Iterator end() { return Iterator(data() + Size); } | ||
Iterator cend() { return Iterator(data() + Size); } | ||
|
||
private: | ||
int m_buffer[Size]{}; | ||
}; | ||
|
||
#endif // NUMBER_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,23 @@ | ||
#include "Number.h" | ||
|
||
int function(int x) { | ||
if ((x % 2) == 0) | ||
return function(x - 1) + x; // breakpoint 1 | ||
else | ||
return x; | ||
} | ||
|
||
int main(int argc, char const *argv[]) { return function(2); } | ||
int function2() { | ||
Numbers<10> list; | ||
|
||
int result = 0; | ||
for (const int val : list) // position_after_step_over | ||
result++; // breakpoint 2 | ||
|
||
return result; | ||
} | ||
|
||
int main(int argc, char const *argv[]) { | ||
int func_result = function2(); | ||
return function(2) + func_result; // returns 13 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -581,19 +581,19 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame, | |
|
||
EmplaceSafeString(object, "name", frame_name); | ||
|
||
auto target = frame.GetThread().GetProcess().GetTarget(); | ||
auto source = CreateSource(frame.GetPCAddress(), target); | ||
lldb::SBTarget target = frame.GetThread().GetProcess().GetTarget(); | ||
protocol::Source source = CreateSource(frame); | ||
|
||
if (!IsAssemblySource(source)) { | ||
// This is a normal source with a valid line entry. | ||
auto line_entry = frame.GetLineEntry(); | ||
lldb::SBLineEntry line_entry = frame.GetLineEntry(); | ||
object.try_emplace("line", line_entry.GetLine()); | ||
auto column = line_entry.GetColumn(); | ||
uint32_t column = line_entry.GetColumn(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are any of these changes related to this patch? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I see that the |
||
object.try_emplace("column", column); | ||
} else if (frame.GetSymbol().IsValid()) { | ||
// This is a source where the disassembly is used, but there is a valid | ||
// symbol. Calculate the line of the current PC from the start of the | ||
// current symbol. | ||
lldb::SBTarget target = frame.GetThread().GetProcess().GetTarget(); | ||
lldb::SBInstructionList inst_list = target.ReadInstructions( | ||
frame.GetSymbol().GetStartAddress(), frame.GetPCAddress(), nullptr); | ||
size_t inst_line = inst_list.GetSize(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,6 +105,21 @@ protocol::Source CreateSource(lldb::SBAddress address, lldb::SBTarget &target) { | |
return CreateSource(line_entry.GetFileSpec()); | ||
} | ||
|
||
protocol::Source CreateSource(lldb::SBFrame frame) { | ||
if (!frame.IsValid()) | ||
return {}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should make this function return an |
||
|
||
const lldb::SBTarget target = frame.GetThread().GetProcess().GetTarget(); | ||
lldb::SBDebugger debugger = target.GetDebugger(); | ||
lldb::StopDisassemblyType stop_disassembly_display = | ||
GetStopDisassemblyDisplay(debugger); | ||
const lldb::SBAddress frame_pc = frame.GetPCAddress(); | ||
if (ShouldDisplayAssemblySource(frame_pc, stop_disassembly_display)) | ||
return CreateAssemblySource(target, frame_pc); | ||
|
||
return CreateSource(frame.GetLineEntry().GetFileSpec()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As with the comment on line 109, I think we should update There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am thinking maybe I move this refactor to a different PR so it is easier to review the main issue ?, Since the |
||
} | ||
|
||
bool IsAssemblySource(const protocol::Source &source) { | ||
// According to the specification, a source must have either `path` or | ||
// `sourceReference` specified. We use `path` for sources with known 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.
Would this patch become simpler if we called
StackFrame::GetFrameCodeAddressForSymbolication
instead ofGetPCAddress
here? I think that's how LLDB solves this problemThere 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.
We do not have access to the function because lldb-dap uses the
SB-API
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 if it makes sense here, but I want to point out that we can definitely consider adding new SB functions if they are useful for some users (like lldb-dap).