Skip to content

Commit 30658e9

Browse files
committed
Fix variable request from reusing variable_ids
1 parent c7f3bdb commit 30658e9

File tree

4 files changed

+119
-25
lines changed

4 files changed

+119
-25
lines changed

lldb/tools/lldb-dap/Handler/ScopesRequestHandler.cpp

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ namespace lldb_dap {
2929
///
3030
/// \return
3131
/// A `protocol::Scope`
32-
static Scope CreateScope(const llvm::StringRef name, int64_t variablesReference,
33-
int64_t namedVariables, bool expensive) {
32+
Scope CreateScope(const llvm::StringRef name, int64_t variablesReference,
33+
int64_t namedVariables, bool expensive) {
3434
Scope scope;
3535
scope.name = name;
3636

@@ -75,22 +75,31 @@ ScopesRequestHandler::Run(const ScopesArguments &args) const {
7575
frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
7676
frame.GetThread().SetSelectedFrame(frame.GetFrameID());
7777
}
78-
dap.variables.locals = frame.GetVariables(/*arguments=*/true,
79-
/*locals=*/true,
80-
/*statics=*/false,
81-
/*in_scope_only=*/true);
82-
dap.variables.globals = frame.GetVariables(/*arguments=*/false,
83-
/*locals=*/false,
84-
/*statics=*/true,
85-
/*in_scope_only=*/true);
86-
dap.variables.registers = frame.GetRegisters();
87-
88-
std::vector scopes = {CreateScope("Locals", VARREF_LOCALS,
89-
dap.variables.locals.GetSize(), false),
90-
CreateScope("Globals", VARREF_GLOBALS,
91-
dap.variables.globals.GetSize(), false),
92-
CreateScope("Registers", VARREF_REGS,
93-
dap.variables.registers.GetSize(), false)};
78+
79+
uint32_t frame_id = frame.GetFrameID();
80+
81+
dap.variables.ReadyFrame(frame_id, frame);
82+
dap.variables.SwitchFrame(frame_id);
83+
84+
std::vector<Scope> scopes = {};
85+
86+
int64_t variable_reference = dap.variables.GetNewVariableReference(false);
87+
scopes.push_back(CreateScope("Locals", variable_reference,
88+
dap.variables.locals.GetSize(), false));
89+
90+
dap.variables.AddScopeKind(variable_reference, ScopeKind::Locals, frame_id);
91+
92+
variable_reference = dap.variables.GetNewVariableReference(false);
93+
scopes.push_back(CreateScope("Globals", variable_reference,
94+
dap.variables.globals.GetSize(), false));
95+
dap.variables.AddScopeKind(variable_reference, ScopeKind::Globals, frame_id);
96+
97+
variable_reference = dap.variables.GetNewVariableReference(false);
98+
scopes.push_back(CreateScope("Registers", variable_reference,
99+
dap.variables.registers.GetSize(), false));
100+
101+
dap.variables.AddScopeKind(variable_reference, ScopeKind::Registers,
102+
frame_id);
94103

95104
return ScopesResponseBody{std::move(scopes)};
96105
}

lldb/tools/lldb-dap/JSONUtils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef LLDB_TOOLS_LLDB_DAP_JSONUTILS_H
1010
#define LLDB_TOOLS_LLDB_DAP_JSONUTILS_H
1111

12+
#include "DAP.h"
1213
#include "DAPForward.h"
1314
#include "Protocol/ProtocolTypes.h"
1415
#include "lldb/API/SBCompileUnit.h"

lldb/tools/lldb-dap/Variables.cpp

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,42 @@
88

99
#include "Variables.h"
1010
#include "JSONUtils.h"
11+
#include "lldb/API/SBFrame.h"
1112

1213
using namespace lldb_dap;
1314

1415
lldb::SBValueList *Variables::GetTopLevelScope(int64_t variablesReference) {
15-
switch (variablesReference) {
16-
case VARREF_LOCALS:
16+
auto iter = m_scope_kinds.find(variablesReference);
17+
if (iter == m_scope_kinds.end()) {
18+
return nullptr;
19+
}
20+
21+
ScopeKind scope_kind = iter->second.first;
22+
uint32_t frame_id = iter->second.second;
23+
24+
if (!SwitchFrame(frame_id)) {
25+
return nullptr;
26+
}
27+
28+
switch (scope_kind) {
29+
case lldb_dap::ScopeKind::Locals:
1730
return &locals;
18-
case VARREF_GLOBALS:
31+
case lldb_dap::ScopeKind::Globals:
1932
return &globals;
20-
case VARREF_REGS:
33+
case lldb_dap::ScopeKind::Registers:
2134
return &registers;
22-
default:
23-
return nullptr;
2435
}
36+
37+
return nullptr;
2538
}
2639

2740
void Variables::Clear() {
2841
locals.Clear();
2942
globals.Clear();
3043
registers.Clear();
3144
m_referencedvariables.clear();
45+
m_frames.clear();
46+
m_next_temporary_var_ref = VARREF_FIRST_VAR_IDX;
3247
}
3348

3449
int64_t Variables::GetNewVariableReference(bool is_permanent) {
@@ -103,3 +118,56 @@ lldb::SBValue Variables::FindVariable(uint64_t variablesReference,
103118
}
104119
return variable;
105120
}
121+
122+
std::optional<ScopeKind>
123+
Variables::GetScopeKind(const int64_t variablesReference) {
124+
auto iter = m_scope_kinds.find(variablesReference);
125+
if (iter != m_scope_kinds.end()) {
126+
return iter->second.first;
127+
}
128+
129+
return std::nullopt;
130+
}
131+
132+
bool Variables::SwitchFrame(const uint32_t frame_id) {
133+
auto iter = m_frames.find(frame_id);
134+
135+
if (iter == m_frames.end()) {
136+
return false;
137+
}
138+
139+
auto [frame_locals, frame_globals, frame_registers] = iter->second;
140+
141+
locals = frame_locals;
142+
globals = frame_globals;
143+
registers = frame_registers;
144+
145+
return true;
146+
}
147+
148+
void Variables::ReadyFrame(uint32_t frame_id, lldb::SBFrame &frame) {
149+
if (m_frames.find(frame_id) == m_frames.end()) {
150+
151+
auto locals = frame.GetVariables(/*arguments=*/true,
152+
/*locals=*/true,
153+
/*statics=*/false,
154+
/*in_scope_only=*/true);
155+
156+
auto globals = frame.GetVariables(/*arguments=*/false,
157+
/*locals=*/false,
158+
/*statics=*/true,
159+
/*in_scope_only=*/true);
160+
161+
auto registers = frame.GetRegisters();
162+
163+
m_frames.insert(
164+
std::make_pair(frame_id, std::make_tuple(locals, globals, registers)));
165+
}
166+
}
167+
168+
void Variables::AddScopeKind(int64_t variable_reference, ScopeKind kind,
169+
uint32_t frame_id) {
170+
171+
m_scope_kinds[variable_reference] =
172+
std::make_pair(ScopeKind::Globals, frame_id);
173+
}

lldb/tools/lldb-dap/Variables.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "lldb/API/SBValue.h"
1313
#include "lldb/API/SBValueList.h"
1414
#include "llvm/ADT/DenseMap.h"
15+
#include <map>
1516

1617
#define VARREF_FIRST_VAR_IDX (int64_t)4
1718
#define VARREF_LOCALS (int64_t)1
@@ -20,6 +21,8 @@
2021

2122
namespace lldb_dap {
2223

24+
enum ScopeKind { Locals, Globals, Registers };
25+
2326
struct Variables {
2427
lldb::SBValueList locals;
2528
lldb::SBValueList globals;
@@ -47,12 +50,23 @@ struct Variables {
4750

4851
lldb::SBValue FindVariable(uint64_t variablesReference, llvm::StringRef name);
4952

53+
bool SwitchFrame(uint32_t frame_id);
54+
/// Initialize a frame if it hasn't been already, otherwise do nothing
55+
void ReadyFrame(uint32_t frame_id, lldb::SBFrame &frame);
56+
std::optional<ScopeKind> GetScopeKind(const int64_t variablesReference);
57+
5058
/// Clear all scope variables and non-permanent expandable variables.
5159
void Clear();
5260

61+
void AddScopeKind(int64_t variable_reference, ScopeKind kind,
62+
uint32_t frame_id);
63+
5364
private:
5465
/// Variable_reference start index of permanent expandable variable.
5566
static constexpr int64_t PermanentVariableStartIndex = (1ll << 32);
67+
int64_t m_next_temporary_var_ref{VARREF_FIRST_VAR_IDX};
68+
69+
std::map<int, std::pair<ScopeKind, uint32_t>> m_scope_kinds;
5670

5771
/// Variables that are alive in this stop state.
5872
/// Will be cleared when debuggee resumes.
@@ -62,7 +76,9 @@ struct Variables {
6276
/// These are the variables evaluated from debug console REPL.
6377
llvm::DenseMap<int64_t, lldb::SBValue> m_referencedpermanent_variables;
6478

65-
int64_t m_next_temporary_var_ref{VARREF_FIRST_VAR_IDX};
79+
std::map<uint32_t,
80+
std::tuple<lldb::SBValueList, lldb::SBValueList, lldb::SBValueList>>
81+
m_frames;
6682
int64_t m_next_permanent_var_ref{PermanentVariableStartIndex};
6783
};
6884

0 commit comments

Comments
 (0)