aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py47
-rw-r--r--lldb/test/API/tools/lldb-dap/databreakpoint/Makefile3
-rw-r--r--lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py123
-rw-r--r--lldb/test/API/tools/lldb-dap/databreakpoint/main.cpp17
-rw-r--r--lldb/tools/lldb-dap/CMakeLists.txt1
-rw-r--r--lldb/tools/lldb-dap/DAPForward.h2
-rw-r--r--lldb/tools/lldb-dap/Watchpoint.cpp48
-rw-r--r--lldb/tools/lldb-dap/Watchpoint.h34
-rw-r--r--lldb/tools/lldb-dap/lldb-dap.cpp307
-rw-r--r--llvm/utils/gn/secondary/lldb/tools/lldb-dap/BUILD.gn1
10 files changed, 34 insertions, 549 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
index 27a76a6..bb863bb 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
@@ -501,18 +501,6 @@ class DebugCommunication(object):
return variable["value"]
return None
- def get_local_variable_child(self, name, child_name, frameIndex=0, threadId=None):
- local = self.get_local_variable(name, frameIndex, threadId)
- if local["variablesReference"] == 0:
- return None
- children = self.request_variables(local["variablesReference"])["body"][
- "variables"
- ]
- for child in children:
- if child["name"] == child_name:
- return child
- return None
-
def replay_packets(self, replay_file_path):
f = open(replay_file_path, "r")
mode = "invalid"
@@ -907,41 +895,6 @@ class DebugCommunication(object):
}
return self.send_recv(command_dict)
- def request_dataBreakpointInfo(
- self, variablesReference, name, frameIndex=0, threadId=None
- ):
- stackFrame = self.get_stackFrame(frameIndex=frameIndex, threadId=threadId)
- if stackFrame is None:
- return []
- args_dict = {
- "variablesReference": variablesReference,
- "name": name,
- "frameId": stackFrame["id"],
- }
- command_dict = {
- "command": "dataBreakpointInfo",
- "type": "request",
- "arguments": args_dict,
- }
- return self.send_recv(command_dict)
-
- def request_setDataBreakpoint(self, dataBreakpoints):
- """dataBreakpoints is a list of dictionary with following fields:
- {
- dataId: (address in hex)/(size in bytes)
- accessType: read/write/readWrite
- [condition]: string
- [hitCondition]: string
- }
- """
- args_dict = {"breakpoints": dataBreakpoints}
- command_dict = {
- "command": "setDataBreakpoints",
- "type": "request",
- "arguments": args_dict,
- }
- return self.send_recv(command_dict)
-
def request_compileUnits(self, moduleId):
args_dict = {"moduleId": moduleId}
command_dict = {
diff --git a/lldb/test/API/tools/lldb-dap/databreakpoint/Makefile b/lldb/test/API/tools/lldb-dap/databreakpoint/Makefile
deleted file mode 100644
index 99998b2..0000000
--- a/lldb/test/API/tools/lldb-dap/databreakpoint/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-CXX_SOURCES := main.cpp
-
-include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py b/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py
deleted file mode 100644
index 40ca647..0000000
--- a/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py
+++ /dev/null
@@ -1,123 +0,0 @@
-"""
-Test lldb-dap dataBreakpointInfo and setDataBreakpoints requests
-"""
-
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-import lldbdap_testcase
-
-
-class TestDAP_setDataBreakpoints(lldbdap_testcase.DAPTestCaseBase):
- def setUp(self):
- lldbdap_testcase.DAPTestCaseBase.setUp(self)
- self.accessTypes = ["read", "write", "readWrite"]
-
- @skipIfWindows
- @skipIfRemote
- def test_expression(self):
- """Tests setting data breakpoints on expression."""
- program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
- source = "main.cpp"
- first_loop_break_line = line_number(source, "// first loop breakpoint")
- self.set_source_breakpoints(source, [first_loop_break_line])
- self.continue_to_next_stop()
- self.dap_server.get_stackFrame()
- # Test setting write watchpoint using expressions: &x, arr+2
- response_x = self.dap_server.request_dataBreakpointInfo(0, "4@&x")
- response_arr_2 = self.dap_server.request_dataBreakpointInfo(0, "1@arr+2")
- # Test response from dataBreakpointInfo request.
- self.assertEquals(response_x["body"]["dataId"].split("/")[1], "4")
- self.assertEquals(response_x["body"]["accessTypes"], self.accessTypes)
- self.assertEquals(response_arr_2["body"]["dataId"].split("/")[1], "1")
- self.assertEquals(response_arr_2["body"]["accessTypes"], self.accessTypes)
- dataBreakpoints = [
- {"dataId": response_x["body"]["dataId"], "accessType": "write"},
- {"dataId": response_arr_2["body"]["dataId"], "accessType": "write"},
- ]
- self.dap_server.request_setDataBreakpoint(dataBreakpoints)
-
- self.dap_server.request_continue()
- self.dap_server.wait_for_stopped()
- x_val = self.dap_server.get_local_variable_value("x")
- i_val = self.dap_server.get_local_variable_value("i")
- self.assertEquals(x_val, "2")
- self.assertEquals(i_val, "1")
-
- self.dap_server.request_continue()
- self.dap_server.wait_for_stopped()
- arr_2 = self.dap_server.get_local_variable_child("arr", "[2]")
- i_val = self.dap_server.get_local_variable_value("i")
- self.assertEquals(arr_2["value"], "'z'")
- self.assertEquals(i_val, "2")
-
- @skipIfWindows
- @skipIfRemote
- def test_functionality(self):
- """Tests setting data breakpoints on variable."""
- program = self.getBuildArtifact("a.out")
- self.build_and_launch(program)
- source = "main.cpp"
- first_loop_break_line = line_number(source, "// first loop breakpoint")
- self.set_source_breakpoints(source, [first_loop_break_line])
- self.continue_to_next_stop()
- self.dap_server.get_local_variables()
- # Test write watchpoints on x, arr[2]
- response_x = self.dap_server.request_dataBreakpointInfo(1, "x")
- arr = self.dap_server.get_local_variable("arr")
- response_arr_2 = self.dap_server.request_dataBreakpointInfo(
- arr["variablesReference"], "[2]"
- )
-
- # Test response from dataBreakpointInfo request.
- self.assertEquals(response_x["body"]["dataId"].split("/")[1], "4")
- self.assertEquals(response_x["body"]["accessTypes"], self.accessTypes)
- self.assertEquals(response_arr_2["body"]["dataId"].split("/")[1], "1")
- self.assertEquals(response_arr_2["body"]["accessTypes"], self.accessTypes)
- dataBreakpoints = [
- {"dataId": response_x["body"]["dataId"], "accessType": "write"},
- {"dataId": response_arr_2["body"]["dataId"], "accessType": "write"},
- ]
- self.dap_server.request_setDataBreakpoint(dataBreakpoints)
-
- self.continue_to_next_stop()
- x_val = self.dap_server.get_local_variable_value("x")
- i_val = self.dap_server.get_local_variable_value("i")
- self.assertEquals(x_val, "2")
- self.assertEquals(i_val, "1")
-
- self.continue_to_next_stop()
- arr_2 = self.dap_server.get_local_variable_child("arr", "[2]")
- i_val = self.dap_server.get_local_variable_value("i")
- self.assertEquals(arr_2["value"], "'z'")
- self.assertEquals(i_val, "2")
- self.dap_server.request_setDataBreakpoint([])
-
- # Test hit condition
- second_loop_break_line = line_number(source, "// second loop breakpoint")
- breakpoint_ids = self.set_source_breakpoints(source, [second_loop_break_line])
- self.continue_to_breakpoints(breakpoint_ids)
- dataBreakpoints = [
- {
- "dataId": response_x["body"]["dataId"],
- "accessType": "write",
- "hitCondition": "2",
- }
- ]
- self.dap_server.request_setDataBreakpoint(dataBreakpoints)
- self.continue_to_next_stop()
- x_val = self.dap_server.get_local_variable_value("x")
- self.assertEquals(x_val, "3")
-
- # Test condition
- dataBreakpoints = [
- {
- "dataId": response_x["body"]["dataId"],
- "accessType": "write",
- "condition": "x==10",
- }
- ]
- self.dap_server.request_setDataBreakpoint(dataBreakpoints)
- self.continue_to_next_stop()
- x_val = self.dap_server.get_local_variable_value("x")
- self.assertEquals(x_val, "10")
diff --git a/lldb/test/API/tools/lldb-dap/databreakpoint/main.cpp b/lldb/test/API/tools/lldb-dap/databreakpoint/main.cpp
deleted file mode 100644
index 8082fe0..0000000
--- a/lldb/test/API/tools/lldb-dap/databreakpoint/main.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-int main(int argc, char const *argv[]) {
- // Test for data breakpoint
- int x = 0;
- char arr[4] = {'a', 'b', 'c', 'd'};
- for (int i = 0; i < 5; ++i) { // first loop breakpoint
- if (i == 1) {
- x = i + 1;
- } else if (i == 2) {
- arr[i] = 'z';
- }
- }
-
- x = 1;
- for (int i = 0; i < 10; ++i) { // second loop breakpoint
- ++x;
- }
-}
diff --git a/lldb/tools/lldb-dap/CMakeLists.txt b/lldb/tools/lldb-dap/CMakeLists.txt
index f8f0d86..f8c0e4e 100644
--- a/lldb/tools/lldb-dap/CMakeLists.txt
+++ b/lldb/tools/lldb-dap/CMakeLists.txt
@@ -37,7 +37,6 @@ add_lldb_tool(lldb-dap
RunInTerminal.cpp
SourceBreakpoint.cpp
DAP.cpp
- Watchpoint.cpp
LINK_LIBS
liblldb
diff --git a/lldb/tools/lldb-dap/DAPForward.h b/lldb/tools/lldb-dap/DAPForward.h
index 8c79488..fffff1e 100644
--- a/lldb/tools/lldb-dap/DAPForward.h
+++ b/lldb/tools/lldb-dap/DAPForward.h
@@ -14,7 +14,6 @@ struct BreakpointBase;
struct ExceptionBreakpoint;
struct FunctionBreakpoint;
struct SourceBreakpoint;
-struct Watchpoint;
} // namespace lldb_dap
namespace lldb {
@@ -40,7 +39,6 @@ class SBStringList;
class SBTarget;
class SBThread;
class SBValue;
-class SBWatchpoint;
} // namespace lldb
#endif
diff --git a/lldb/tools/lldb-dap/Watchpoint.cpp b/lldb/tools/lldb-dap/Watchpoint.cpp
deleted file mode 100644
index 2f176e0..0000000
--- a/lldb/tools/lldb-dap/Watchpoint.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//===-- Watchpoint.cpp ------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "Watchpoint.h"
-#include "DAP.h"
-#include "JSONUtils.h"
-#include "llvm/ADT/StringExtras.h"
-
-namespace lldb_dap {
-Watchpoint::Watchpoint(const llvm::json::Object &obj) : BreakpointBase(obj) {
- llvm::StringRef dataId = GetString(obj, "dataId");
- std::string accessType = GetString(obj, "accessType").str();
- auto [addr_str, size_str] = dataId.split('/');
- lldb::addr_t addr;
- size_t size;
- llvm::to_integer(addr_str, addr, 16);
- llvm::to_integer(size_str, size);
- lldb::SBWatchpointOptions options;
- options.SetWatchpointTypeRead(accessType != "write");
- if (accessType != "read")
- options.SetWatchpointTypeWrite(lldb::eWatchpointWriteTypeOnModify);
- wp = g_dap.target.WatchpointCreateByAddress(addr, size, options, error);
- SetCondition();
- SetHitCondition();
-}
-
-void Watchpoint::SetCondition() { wp.SetCondition(condition.c_str()); }
-
-void Watchpoint::SetHitCondition() {
- uint64_t hitCount = 0;
- if (llvm::to_integer(hitCondition, hitCount))
- wp.SetIgnoreCount(hitCount - 1);
-}
-
-void Watchpoint::CreateJsonObject(llvm::json::Object &object) {
- if (error.Success()) {
- object.try_emplace("verified", true);
- } else {
- object.try_emplace("verified", false);
- EmplaceSafeString(object, "message", error.GetCString());
- }
-}
-} // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/Watchpoint.h b/lldb/tools/lldb-dap/Watchpoint.h
deleted file mode 100644
index 026b07d..0000000
--- a/lldb/tools/lldb-dap/Watchpoint.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===-- Watchpoint.h --------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_TOOLS_LLDB_DAP_WATCHPOINT_H
-#define LLDB_TOOLS_LLDB_DAP_WATCHPOINT_H
-
-#include "BreakpointBase.h"
-#include "lldb/API/SBError.h"
-#include "lldb/API/SBWatchpoint.h"
-#include "lldb/API/SBWatchpointOptions.h"
-
-namespace lldb_dap {
-
-struct Watchpoint : public BreakpointBase {
- // The LLDB breakpoint associated wit this watchpoint.
- lldb::SBWatchpoint wp;
- lldb::SBError error;
-
- Watchpoint() = default;
- Watchpoint(const llvm::json::Object &obj);
- Watchpoint(lldb::SBWatchpoint wp) : wp(wp) {}
-
- void SetCondition() override;
- void SetHitCondition() override;
- void CreateJsonObject(llvm::json::Object &object) override;
-};
-} // namespace lldb_dap
-
-#endif
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index 6bf2ec2..6702234 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "DAP.h"
-#include "Watchpoint.h"
#include <cassert>
#include <climits>
@@ -561,46 +560,6 @@ void EventThreadFunction() {
}
}
-lldb::SBValue FindVariable(uint64_t variablesReference, llvm::StringRef name) {
- lldb::SBValue variable;
- if (lldb::SBValueList *top_scope = GetTopLevelScope(variablesReference)) {
- bool is_duplicated_variable_name = name.contains(" @");
- // variablesReference is one of our scopes, not an actual variable it is
- // asking for a variable in locals or globals or registers
- int64_t end_idx = top_scope->GetSize();
- // Searching backward so that we choose the variable in closest scope
- // among variables of the same name.
- for (int64_t i = end_idx - 1; i >= 0; --i) {
- lldb::SBValue curr_variable = top_scope->GetValueAtIndex(i);
- std::string variable_name = CreateUniqueVariableNameForDisplay(
- curr_variable, is_duplicated_variable_name);
- if (variable_name == name) {
- variable = curr_variable;
- break;
- }
- }
- } else {
- // This is not under the globals or locals scope, so there are no duplicated
- // names.
-
- // We have a named item within an actual variable so we need to find it
- // withing the container variable by name.
- lldb::SBValue container = g_dap.variables.GetVariable(variablesReference);
- variable = container.GetChildMemberWithName(name.data());
- if (!variable.IsValid()) {
- if (name.starts_with("[")) {
- llvm::StringRef index_str(name.drop_front(1));
- uint64_t index = 0;
- if (!index_str.consumeInteger(0, index)) {
- if (index_str == "]")
- variable = container.GetChildAtIndex(index);
- }
- }
- }
- }
- return variable;
-}
-
// Both attach and launch take a either a sourcePath or sourceMap
// argument (or neither), from which we need to set the target.source-map.
void SetSourceMapFromArguments(const llvm::json::Object &arguments) {
@@ -1688,8 +1647,6 @@ void request_initialize(const llvm::json::Object &request) {
body.try_emplace("supportsProgressReporting", true);
// The debug adapter supports 'logMessage' in breakpoint.
body.try_emplace("supportsLogPoints", true);
- // The debug adapter supports data watchpoints.
- body.try_emplace("supportsDataBreakpoints", true);
response.try_emplace("body", std::move(body));
g_dap.SendJSON(llvm::json::Value(std::move(response)));
@@ -2634,231 +2591,6 @@ void request_setFunctionBreakpoints(const llvm::json::Object &request) {
g_dap.SendJSON(llvm::json::Value(std::move(response)));
}
-// "DataBreakpointInfoRequest": {
-// "allOf": [ { "$ref": "#/definitions/Request" }, {
-// "type": "object",
-// "description": "Obtains information on a possible data breakpoint that
-// could be set on an expression or variable.\nClients should only call this
-// request if the corresponding capability `supportsDataBreakpoints` is
-// true.", "properties": {
-// "command": {
-// "type": "string",
-// "enum": [ "dataBreakpointInfo" ]
-// },
-// "arguments": {
-// "$ref": "#/definitions/DataBreakpointInfoArguments"
-// }
-// },
-// "required": [ "command", "arguments" ]
-// }]
-// },
-// "DataBreakpointInfoArguments": {
-// "type": "object",
-// "description": "Arguments for `dataBreakpointInfo` request.",
-// "properties": {
-// "variablesReference": {
-// "type": "integer",
-// "description": "Reference to the variable container if the data
-// breakpoint is requested for a child of the container. The
-// `variablesReference` must have been obtained in the current suspended
-// state. See 'Lifetime of Object References' in the Overview section for
-// details."
-// },
-// "name": {
-// "type": "string",
-// "description": "The name of the variable's child to obtain data
-// breakpoint information for.\nIf `variablesReference` isn't specified,
-// this can be an expression."
-// },
-// "frameId": {
-// "type": "integer",
-// "description": "When `name` is an expression, evaluate it in the scope
-// of this stack frame. If not specified, the expression is evaluated in
-// the global scope. When `variablesReference` is specified, this property
-// has no effect."
-// }
-// },
-// "required": [ "name" ]
-// },
-// "DataBreakpointInfoResponse": {
-// "allOf": [ { "$ref": "#/definitions/Response" }, {
-// "type": "object",
-// "description": "Response to `dataBreakpointInfo` request.",
-// "properties": {
-// "body": {
-// "type": "object",
-// "properties": {
-// "dataId": {
-// "type": [ "string", "null" ],
-// "description": "An identifier for the data on which a data
-// breakpoint can be registered with the `setDataBreakpoints`
-// request or null if no data breakpoint is available. If a
-// `variablesReference` or `frameId` is passed, the `dataId` is
-// valid in the current suspended state, otherwise it's valid
-// indefinitely. See 'Lifetime of Object References' in the Overview
-// section for details. Breakpoints set using the `dataId` in the
-// `setDataBreakpoints` request may outlive the lifetime of the
-// associated `dataId`."
-// },
-// "description": {
-// "type": "string",
-// "description": "UI string that describes on what data the
-// breakpoint is set on or why a data breakpoint is not available."
-// },
-// "accessTypes": {
-// "type": "array",
-// "items": {
-// "$ref": "#/definitions/DataBreakpointAccessType"
-// },
-// "description": "Attribute lists the available access types for a
-// potential data breakpoint. A UI client could surface this
-// information."
-// },
-// "canPersist": {
-// "type": "boolean",
-// "description": "Attribute indicates that a potential data
-// breakpoint could be persisted across sessions."
-// }
-// },
-// "required": [ "dataId", "description" ]
-// }
-// },
-// "required": [ "body" ]
-// }]
-// }
-void request_dataBreakpointInfo(const llvm::json::Object &request) {
- llvm::json::Object response;
- FillResponse(request, response);
- llvm::json::Object body;
- lldb::SBError error;
- llvm::json::Array accessTypes{"read", "write", "readWrite"};
- const auto *arguments = request.getObject("arguments");
- const auto variablesReference =
- GetUnsigned(arguments, "variablesReference", 0);
- llvm::StringRef name = GetString(arguments, "name");
- lldb::SBFrame frame = g_dap.GetLLDBFrame(*arguments);
- lldb::SBValue variable = FindVariable(variablesReference, name);
- std::string addr, size;
-
- if (variable.IsValid()) {
- addr = llvm::utohexstr(variable.GetLoadAddress());
- size = llvm::utostr(variable.GetByteSize());
- } else if (variablesReference == 0 && frame.IsValid()) {
- // Name might be an expression. In this case we assume that name is composed
- // of the number of bytes to watch and expression, separated by '@':
- // "${size}@${expression}"
- llvm::StringRef expr;
- std::tie(size, expr) = name.split('@');
- lldb::SBValue value = frame.EvaluateExpression(expr.data());
- if (value.GetError().Fail()) {
- lldb::SBError error = value.GetError();
- const char *error_cstr = error.GetCString();
- body.try_emplace("dataId", nullptr);
- body.try_emplace("description", error_cstr && error_cstr[0]
- ? std::string(error_cstr)
- : "evaluation failed");
- } else
- addr = llvm::utohexstr(value.GetValueAsUnsigned());
- } else {
- auto state = g_dap.target.GetProcess().GetState();
- body.try_emplace("dataId", nullptr);
- body.try_emplace("description",
- "variable not found: " + llvm::utostr(state));
- }
-
- if (!body.getObject("dataId")) {
- body.try_emplace("dataId", addr + "/" + size);
- body.try_emplace("accessTypes", std::move(accessTypes));
- body.try_emplace("description",
- size + " bytes at " + addr + " " + name.str());
- }
- response.try_emplace("body", std::move(body));
- g_dap.SendJSON(llvm::json::Value(std::move(response)));
-}
-
-// "SetDataBreakpointsRequest": {
-// "allOf": [ { "$ref": "#/definitions/Request" }, {
-// "type": "object",
-// "description": "Replaces all existing data breakpoints with new data
-// breakpoints.\nTo clear all data breakpoints, specify an empty
-// array.\nWhen a data breakpoint is hit, a `stopped` event (with reason
-// `data breakpoint`) is generated.\nClients should only call this request
-// if the corresponding capability `supportsDataBreakpoints` is true.",
-// "properties": {
-// "command": {
-// "type": "string",
-// "enum": [ "setDataBreakpoints" ]
-// },
-// "arguments": {
-// "$ref": "#/definitions/SetDataBreakpointsArguments"
-// }
-// },
-// "required": [ "command", "arguments" ]
-// }]
-// },
-// "SetDataBreakpointsArguments": {
-// "type": "object",
-// "description": "Arguments for `setDataBreakpoints` request.",
-// "properties": {
-// "breakpoints": {
-// "type": "array",
-// "items": {
-// "$ref": "#/definitions/DataBreakpoint"
-// },
-// "description": "The contents of this array replaces all existing data
-// breakpoints. An empty array clears all data breakpoints."
-// }
-// },
-// "required": [ "breakpoints" ]
-// },
-// "SetDataBreakpointsResponse": {
-// "allOf": [ { "$ref": "#/definitions/Response" }, {
-// "type": "object",
-// "description": "Response to `setDataBreakpoints` request.\nReturned is
-// information about each breakpoint created by this request.",
-// "properties": {
-// "body": {
-// "type": "object",
-// "properties": {
-// "breakpoints": {
-// "type": "array",
-// "items": {
-// "$ref": "#/definitions/Breakpoint"
-// },
-// "description": "Information about the data breakpoints. The array
-// elements correspond to the elements of the input argument
-// `breakpoints` array."
-// }
-// },
-// "required": [ "breakpoints" ]
-// }
-// },
-// "required": [ "body" ]
-// }]
-// }
-void request_setDataBreakpoints(const llvm::json::Object &request) {
- llvm::json::Object response;
- lldb::SBError error;
- FillResponse(request, response);
- const auto *arguments = request.getObject("arguments");
- const auto *breakpoints = arguments->getArray("breakpoints");
- llvm::json::Array response_breakpoints;
- g_dap.target.DeleteAllWatchpoints();
- if (breakpoints) {
- for (const auto &bp : *breakpoints) {
- const auto *bp_obj = bp.getAsObject();
- if (bp_obj) {
- Watchpoint wp(*bp_obj);
- AppendBreakpoint(&wp, response_breakpoints);
- }
- }
- }
- llvm::json::Object body;
- body.try_emplace("breakpoints", std::move(response_breakpoints));
- response.try_emplace("body", std::move(body));
- g_dap.SendJSON(llvm::json::Value(std::move(response)));
-}
-
// "SourceRequest": {
// "allOf": [ { "$ref": "#/definitions/Request" }, {
// "type": "object",
@@ -3342,6 +3074,7 @@ void request_setVariable(const llvm::json::Object &request) {
const auto variablesReference =
GetUnsigned(arguments, "variablesReference", 0);
llvm::StringRef name = GetString(arguments, "name");
+ bool is_duplicated_variable_name = name.contains(" @");
const auto value = GetString(arguments, "value");
// Set success to false just in case we don't find the variable by name
@@ -3362,8 +3095,40 @@ void request_setVariable(const llvm::json::Object &request) {
const auto id_value = GetUnsigned(arguments, "id", UINT64_MAX);
if (id_value != UINT64_MAX) {
variable = g_dap.variables.GetVariable(id_value);
+ } else if (lldb::SBValueList *top_scope =
+ GetTopLevelScope(variablesReference)) {
+ // variablesReference is one of our scopes, not an actual variable it is
+ // asking for a variable in locals or globals or registers
+ int64_t end_idx = top_scope->GetSize();
+ // Searching backward so that we choose the variable in closest scope
+ // among variables of the same name.
+ for (int64_t i = end_idx - 1; i >= 0; --i) {
+ lldb::SBValue curr_variable = top_scope->GetValueAtIndex(i);
+ std::string variable_name = CreateUniqueVariableNameForDisplay(
+ curr_variable, is_duplicated_variable_name);
+ if (variable_name == name) {
+ variable = curr_variable;
+ break;
+ }
+ }
} else {
- variable = FindVariable(variablesReference, name);
+ // This is not under the globals or locals scope, so there are no duplicated
+ // names.
+
+ // We have a named item within an actual variable so we need to find it
+ // withing the container variable by name.
+ lldb::SBValue container = g_dap.variables.GetVariable(variablesReference);
+ variable = container.GetChildMemberWithName(name.data());
+ if (!variable.IsValid()) {
+ if (name.starts_with("[")) {
+ llvm::StringRef index_str(name.drop_front(1));
+ uint64_t index = 0;
+ if (!index_str.consumeInteger(0, index)) {
+ if (index_str == "]")
+ variable = container.GetChildAtIndex(index);
+ }
+ }
+ }
}
if (variable.IsValid()) {
@@ -3846,10 +3611,6 @@ void RegisterRequestCallbacks() {
request_setExceptionBreakpoints);
g_dap.RegisterRequestCallback("setFunctionBreakpoints",
request_setFunctionBreakpoints);
- g_dap.RegisterRequestCallback("dataBreakpointInfo",
- request_dataBreakpointInfo);
- g_dap.RegisterRequestCallback("setDataBreakpoints",
- request_setDataBreakpoints);
g_dap.RegisterRequestCallback("setVariable", request_setVariable);
g_dap.RegisterRequestCallback("source", request_source);
g_dap.RegisterRequestCallback("stackTrace", request_stackTrace);
diff --git a/llvm/utils/gn/secondary/lldb/tools/lldb-dap/BUILD.gn b/llvm/utils/gn/secondary/lldb/tools/lldb-dap/BUILD.gn
index a752b61b..98c2068 100644
--- a/llvm/utils/gn/secondary/lldb/tools/lldb-dap/BUILD.gn
+++ b/llvm/utils/gn/secondary/lldb/tools/lldb-dap/BUILD.gn
@@ -52,6 +52,5 @@ executable("lldb-dap") {
"RunInTerminal.cpp",
"SourceBreakpoint.cpp",
"lldb-dap.cpp",
- "Watchpoint.cpp",
]
}