[Lldb-commits] [lldb] Make env and source map dictionaries #95137 (PR #106919)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Sep 4 12:59:47 PDT 2024
https://github.com/Da-Viper updated https://github.com/llvm/llvm-project/pull/106919
>From d2bddca1753b4c960895f51d7eb80b6efa7dc986 Mon Sep 17 00:00:00 2001
From: Ezike Ebuka <yerimyah1 at gmail.com>
Date: Sun, 1 Sep 2024 17:26:11 +0100
Subject: [PATCH 1/5] [lldb-dap] Make environment option an object
---
.../tools/lldb-dap/launch/TestDAP_launch.py | 4 +-
lldb/tools/lldb-dap/JSONUtils.cpp | 40 ++++++++++++++++---
lldb/tools/lldb-dap/JSONUtils.h | 22 ++++++++++
lldb/tools/lldb-dap/README.md | 5 ++-
lldb/tools/lldb-dap/lldb-dap.cpp | 8 +++-
lldb/tools/lldb-dap/package.json | 11 +++--
6 files changed, 77 insertions(+), 13 deletions(-)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
index a16f2da3c4df71..6b9993a2548b8d 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -229,7 +229,7 @@ def test_environment(self):
Tests launch of a simple program with environment variables
"""
program = self.getBuildArtifact("a.out")
- env = ["NO_VALUE", "WITH_VALUE=BAR", "EMPTY_VALUE=", "SPACE=Hello World"]
+ env = {"NO_VALUE": "", "WITH_VALUE":"BAR", "EMPTY_VALUE": "", "SPACE": "Hello World"}
self.build_and_launch(program, env=env)
self.continue_to_exit()
@@ -242,7 +242,7 @@ def test_environment(self):
lines.pop(0)
# Make sure each environment variable in "env" is actually set in the
# program environment that was printed to STDOUT
- for var in env:
+ for var in env.keys():
found = False
for program_var in lines:
if var in program_var:
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp
index 7338e7cf41eb03..29b3ad490af0b6 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -136,6 +136,31 @@ std::vector<std::string> GetStrings(const llvm::json::Object *obj,
return strs;
}
+std::unordered_map<std::string, std::string>
+GetStringMap(const llvm::json::Object &obj, llvm::StringRef key) {
+ std::unordered_map<std::string, std::string> strs;
+ const auto *const json_object = obj.getObject(key);
+ if (!json_object)
+ return strs;
+
+ for (const auto &[key, value] : *json_object) {
+ switch (value.kind()) {
+ case llvm::json::Value::String:
+ strs.emplace(key.str(), value.getAsString()->str());
+ break;
+ case llvm::json::Value::Number:
+ case llvm::json::Value::Boolean:
+ strs.emplace(key.str(), llvm::to_string(value));
+ break;
+ case llvm::json::Value::Null:
+ case llvm::json::Value::Object:
+ case llvm::json::Value::Array:
+ break;
+ }
+ }
+ return strs;
+}
+
static bool IsClassStructOrUnionType(lldb::SBType t) {
return (t.GetTypeClass() & (lldb::eTypeClassUnion | lldb::eTypeClassStruct |
lldb::eTypeClassArray)) != 0;
@@ -1370,13 +1395,16 @@ CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,
if (!cwd.empty())
run_in_terminal_args.try_emplace("cwd", cwd);
- // We need to convert the input list of environments variables into a
- // dictionary
- std::vector<std::string> envs = GetStrings(launch_request_arguments, "env");
+ std::unordered_map<std::string, std::string> envMap =
+ GetStringMap(*launch_request_arguments, "env");
llvm::json::Object environment;
- for (const std::string &env : envs) {
- size_t index = env.find('=');
- environment.try_emplace(env.substr(0, index), env.substr(index + 1));
+ for (const auto &[key, value] : envMap) {
+ if (key.empty())
+ g_dap.SendOutput(OutputType::Stderr,
+ "empty environment variable for value: \"" + value +
+ '\"');
+ else
+ environment.try_emplace(key, value);
}
run_in_terminal_args.try_emplace("env",
llvm::json::Value(std::move(environment)));
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index b6356630b72682..60d5db06560657 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -16,6 +16,7 @@
#include "llvm/Support/JSON.h"
#include <cstdint>
#include <optional>
+#include <unordered_map>
namespace lldb_dap {
@@ -152,6 +153,27 @@ bool ObjectContainsKey(const llvm::json::Object &obj, llvm::StringRef key);
std::vector<std::string> GetStrings(const llvm::json::Object *obj,
llvm::StringRef key);
+/// Extract an object of key value strings for the specified key from an object.
+///
+/// String values in the object will be extracted without any quotes
+/// around them. Numbers and Booleans will be converted into
+/// strings. Any NULL, array or objects values in the array will be
+/// ignored.
+///
+/// \param[in] obj
+/// A JSON object that we will attempt to extract the array from
+///
+/// \param[in] key
+/// The key to use when extracting the value
+///
+/// \return
+/// An object of key value strings for the specified \a key, or
+/// \a fail_value if there is no key that matches or if the
+/// value is not an object or key and values in the object are not
+/// strings, numbers or booleans.
+std::unordered_map<std::string, std::string>
+GetStringMap(const llvm::json::Object &obj, llvm::StringRef key);
+
/// Fill a response object given the request object.
///
/// The \a response object will get its "type" set to "response",
diff --git a/lldb/tools/lldb-dap/README.md b/lldb/tools/lldb-dap/README.md
index 11a14d29ab51e2..5b6fc5ef990e60 100644
--- a/lldb/tools/lldb-dap/README.md
+++ b/lldb/tools/lldb-dap/README.md
@@ -77,7 +77,10 @@ adds `FOO=1` and `bar` to the environment:
"name": "Debug",
"program": "/tmp/a.out",
"args": [ "one", "two", "three" ],
- "env": [ "FOO=1", "BAR" ],
+ "env": {
+ "FOO": "1"
+ "BAR": ""
+ }
}
```
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index c5c4b09f15622b..da0935dff69878 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -1831,7 +1831,13 @@ lldb::SBError LaunchProcess(const llvm::json::Object &request) {
launch_info.SetArguments(MakeArgv(args).data(), true);
// Pass any environment variables along that the user specified.
- auto envs = GetStrings(arguments, "env");
+ auto envMap = GetStringMap(*arguments, "env");
+ std::vector<std::string> envs;
+ envs.reserve(envMap.size());
+ for (const auto &[key, value] : envMap) {
+ envs.emplace_back(key + '=' + value);
+ }
+
if (!envs.empty())
launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true);
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 4f4261d1718c01..3867302a841913 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -160,9 +160,14 @@
"default": "${workspaceRoot}"
},
"env": {
- "type": "array",
- "description": "Additional environment variables to set when launching the program. This is an array of strings that contains the variable name followed by an optional '=' character and the environment variable's value.",
- "default": []
+ "type": "object",
+ "description": "Additional environment variables to set when launching the program. E.g. `{ \"FOO\": \"1\" }`",
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "default": {}
},
"stopOnEntry": {
"type": "boolean",
>From a3827ed57f655ab803fa28ea7f97e5274322bf0e Mon Sep 17 00:00:00 2001
From: Ezike Ebuka <yerimyah1 at gmail.com>
Date: Mon, 2 Sep 2024 14:25:07 +0100
Subject: [PATCH 2/5] [lldb-dap] format python test code
---
lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
index 6b9993a2548b8d..a56ad032772cbb 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -229,7 +229,12 @@ def test_environment(self):
Tests launch of a simple program with environment variables
"""
program = self.getBuildArtifact("a.out")
- env = {"NO_VALUE": "", "WITH_VALUE":"BAR", "EMPTY_VALUE": "", "SPACE": "Hello World"}
+ env = {
+ "NO_VALUE": "",
+ "WITH_VALUE": "BAR",
+ "EMPTY_VALUE": "",
+ "SPACE": "Hello World",
+ }
self.build_and_launch(program, env=env)
self.continue_to_exit()
>From b0dcf84e0b38dd69813f3aa0f827fb5a70d369f8 Mon Sep 17 00:00:00 2001
From: Ezike Ebuka <yerimyah1 at gmail.com>
Date: Mon, 2 Sep 2024 23:56:40 +0100
Subject: [PATCH 3/5] [lldb-dap] Clean: use Environment class instead of manual
concatenation
---
lldb/tools/lldb-dap/lldb-dap.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index da0935dff69878..7df84bd72794fd 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -51,6 +51,7 @@
#include <thread>
#include <vector>
+#include "lldb/API/SBEnvironment.h"
#include "lldb/API/SBStream.h"
#include "lldb/Host/Config.h"
#include "llvm/ADT/ArrayRef.h"
@@ -1832,14 +1833,13 @@ lldb::SBError LaunchProcess(const llvm::json::Object &request) {
// Pass any environment variables along that the user specified.
auto envMap = GetStringMap(*arguments, "env");
- std::vector<std::string> envs;
- envs.reserve(envMap.size());
+ lldb::SBEnvironment envs{};
for (const auto &[key, value] : envMap) {
- envs.emplace_back(key + '=' + value);
+ envs.Set(key.c_str(), value.c_str(), true);
}
- if (!envs.empty())
- launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true);
+ if (envs.GetNumValues() != 0)
+ launch_info.SetEnvironment(envs, true);
auto flags = launch_info.GetLaunchFlags();
>From e82fe88453be92352ea56ffbf3a585384c54544a Mon Sep 17 00:00:00 2001
From: Ezike Ebuka <yerimyah1 at gmail.com>
Date: Wed, 4 Sep 2024 18:54:35 +0100
Subject: [PATCH 4/5] [lldb-dap] support both array and object env types
---
.../tools/lldb-dap/launch/TestDAP_launch.py | 34 ++++++++++++++++-
lldb/tools/lldb-dap/lldb-dap.cpp | 37 +++++++++++++++----
lldb/tools/lldb-dap/package.json | 28 ++++++++++----
3 files changed, 81 insertions(+), 18 deletions(-)
diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
index a56ad032772cbb..7898d01457afc4 100644
--- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
+++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py
@@ -224,7 +224,7 @@ def test_args(self):
'arg[%i] "%s" not in "%s"' % (i + 1, quoted_arg, lines[i]),
)
- def test_environment(self):
+ def test_environment_with_object(self):
"""
Tests launch of a simple program with environment variables
"""
@@ -235,6 +235,36 @@ def test_environment(self):
"EMPTY_VALUE": "",
"SPACE": "Hello World",
}
+
+ self.build_and_launch(program, env=env)
+ self.continue_to_exit()
+
+ # Now get the STDOUT and verify our arguments got passed correctly
+ output = self.get_stdout()
+ self.assertTrue(output and len(output) > 0, "expect program output")
+ lines = output.splitlines()
+ # Skip the all arguments so we have only environment vars left
+ while len(lines) and lines[0].startswith("arg["):
+ lines.pop(0)
+ # Make sure each environment variable in "env" is actually set in the
+ # program environment that was printed to STDOUT
+ for var in env:
+ found = False
+ for program_var in lines:
+ if var in program_var:
+ found = True
+ break
+ self.assertTrue(
+ found, '"%s" must exist in program environment (%s)' % (var, lines)
+ )
+
+ def test_environment_with_array(self):
+ """
+ Tests launch of a simple program with environment variables
+ """
+ program = self.getBuildArtifact("a.out")
+ env = ["NO_VALUE", "WITH_VALUE=BAR", "EMPTY_VALUE=", "SPACE=Hello World"]
+
self.build_and_launch(program, env=env)
self.continue_to_exit()
@@ -247,7 +277,7 @@ def test_environment(self):
lines.pop(0)
# Make sure each environment variable in "env" is actually set in the
# program environment that was printed to STDOUT
- for var in env.keys():
+ for var in env:
found = False
for program_var in lines:
if var in program_var:
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index 7df84bd72794fd..1bb39e9aab1cb7 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -185,6 +185,33 @@ std::vector<const char *> MakeArgv(const llvm::ArrayRef<std::string> &strs) {
return argv;
}
+// Gets all the environment variables from the json object depending on if the
+// kind is an object or an array.
+lldb::SBEnvironment
+GetEnvironmentFromArguments(const llvm::json::Object &arguments) {
+ lldb::SBEnvironment envs{};
+ constexpr llvm::StringRef env_key = "env";
+ const auto *env_type = arguments.get(env_key);
+
+ if (!env_type)
+ return envs;
+
+ if (env_type->kind() == llvm::json::Value::Object) {
+ auto env_map = GetStringMap(arguments, env_key);
+ for (const auto &[key, value] : env_map) {
+ envs.Set(key.c_str(), value.c_str(), true);
+ }
+ } else if (env_type->kind() == llvm::json::Value::Array) {
+ const auto envs_strings = GetStrings(&arguments, env_key);
+ lldb::SBStringList entries{};
+ for (const auto &env : envs_strings) {
+ entries.AppendString(env.c_str());
+ }
+ envs.SetEntries(entries, true);
+ }
+ return envs;
+}
+
// Send a "exited" event to indicate the process has exited.
void SendProcessExitedEvent(lldb::SBProcess &process) {
llvm::json::Object event(CreateEventObject("exited"));
@@ -1832,14 +1859,8 @@ lldb::SBError LaunchProcess(const llvm::json::Object &request) {
launch_info.SetArguments(MakeArgv(args).data(), true);
// Pass any environment variables along that the user specified.
- auto envMap = GetStringMap(*arguments, "env");
- lldb::SBEnvironment envs{};
- for (const auto &[key, value] : envMap) {
- envs.Set(key.c_str(), value.c_str(), true);
- }
-
- if (envs.GetNumValues() != 0)
- launch_info.SetEnvironment(envs, true);
+ const auto envs = GetEnvironmentFromArguments(*arguments);
+ launch_info.SetEnvironment(envs, true);
auto flags = launch_info.GetLaunchFlags();
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 3867302a841913..c0e72690162763 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -160,14 +160,26 @@
"default": "${workspaceRoot}"
},
"env": {
- "type": "object",
- "description": "Additional environment variables to set when launching the program. E.g. `{ \"FOO\": \"1\" }`",
- "patternProperties": {
- ".*": {
- "type": "string"
+ "anyOf": [
+ {
+ "type": "object",
+ "description": "Additional environment variables to set when launching the program. E.g. `{ \"FOO\": \"1\" }`",
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "default": {}
+ },
+ {
+ "type": "array",
+ "description": "Additional environment variables to set when launching the program. E.g. `[\"FOO=1\", \"BAR\"]`",
+ "items": {
+ "type": "string"
+ },
+ "default": {}
}
- },
- "default": {}
+ ]
},
"stopOnEntry": {
"type": "boolean",
@@ -426,4 +438,4 @@
}
]
}
-}
+}
\ No newline at end of file
>From 7c20d5d91d6a456058437af73e56f311b513d8ff Mon Sep 17 00:00:00 2001
From: Ezike Ebuka <yerimyah1 at gmail.com>
Date: Wed, 4 Sep 2024 20:59:28 +0100
Subject: [PATCH 5/5] [lldb-dap] support object type of setting source map
---
.../lldb-dap/coreFile/TestDAP_coreFile.py | 16 +++++-
lldb/tools/lldb-dap/lldb-dap.cpp | 23 +++++---
lldb/tools/lldb-dap/package.json | 56 +++++++++++++++++--
3 files changed, 80 insertions(+), 15 deletions(-)
diff --git a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py
index b85b6048439639..5189435185607f 100644
--- a/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py
+++ b/lldb/test/API/tools/lldb-dap/coreFile/TestDAP_coreFile.py
@@ -58,7 +58,7 @@ def test_core_file(self):
self.assertEqual(self.get_stackFrames(), expected_frames)
@skipIfLLVMTargetMissing("X86")
- def test_core_file_source_mapping(self):
+ def test_core_file_source_mapping_array(self):
"""Test that sourceMap property is correctly applied when loading a core"""
current_dir = os.path.dirname(__file__)
exe_file = os.path.join(current_dir, "linux-x86_64.out")
@@ -70,3 +70,17 @@ def test_core_file_source_mapping(self):
self.attach(exe_file, coreFile=core_file, sourceMap=source_map)
self.assertIn(current_dir, self.get_stackFrames()[0]["source"]["path"])
+
+ @skipIfLLVMTargetMissing("X86")
+ def test_core_file_source_mapping_object(self):
+ """Test that sourceMap property is correctly applied when loading a core"""
+ current_dir = os.path.dirname(__file__)
+ exe_file = os.path.join(current_dir, "linux-x86_64.out")
+ core_file = os.path.join(current_dir, "linux-x86_64.core")
+
+ self.create_debug_adaptor()
+
+ source_map = {"/home/labath/test": current_dir}
+ self.attach(exe_file, coreFile=core_file, sourceMap=source_map)
+
+ self.assertIn(current_dir, self.get_stackFrames()[0]["source"]["path"])
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index 1bb39e9aab1cb7..df999fd7316b50 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -633,25 +633,32 @@ void SetSourceMapFromArguments(const llvm::json::Object &arguments) {
std::string sourceMapCommand;
llvm::raw_string_ostream strm(sourceMapCommand);
strm << "settings set target.source-map ";
- auto sourcePath = GetString(arguments, "sourcePath");
+ const auto sourcePath = GetString(arguments, "sourcePath");
// sourceMap is the new, more general form of sourcePath and overrides it.
- auto sourceMap = arguments.getArray("sourceMap");
- if (sourceMap) {
- for (const auto &value : *sourceMap) {
- auto mapping = value.getAsArray();
+ constexpr llvm::StringRef sourceMapKey = "sourceMap";
+
+ if (const auto *sourceMapArray = arguments.getArray(sourceMapKey)) {
+ for (const auto &value : *sourceMapArray) {
+ const auto *mapping = value.getAsArray();
if (mapping == nullptr || mapping->size() != 2 ||
(*mapping)[0].kind() != llvm::json::Value::String ||
(*mapping)[1].kind() != llvm::json::Value::String) {
g_dap.SendOutput(OutputType::Console, llvm::StringRef(sourceMapHelp));
return;
}
- auto mapFrom = GetAsString((*mapping)[0]);
- auto mapTo = GetAsString((*mapping)[1]);
+ const auto mapFrom = GetAsString((*mapping)[0]);
+ const auto mapTo = GetAsString((*mapping)[1]);
strm << "\"" << mapFrom << "\" \"" << mapTo << "\" ";
}
+ } else if (const auto *sourceMapObj = arguments.getObject(sourceMapKey)) {
+ for (const auto &[key, value] : *sourceMapObj) {
+ if (value.kind() == llvm::json::Value::String) {
+ strm << "\"" << key.str() << "\" \"" << GetAsString(value) << "\" ";
+ }
+ }
} else {
- if (ObjectContainsKey(arguments, "sourceMap")) {
+ if (ObjectContainsKey(arguments, sourceMapKey)) {
g_dap.SendOutput(OutputType::Console, llvm::StringRef(sourceMapHelp));
return;
}
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index c0e72690162763..ee5d473c728540 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -211,9 +211,31 @@
"description": "Specify a source path to remap \"./\" to allow full paths to be used when setting breakpoints in binaries that have relative source paths."
},
"sourceMap": {
- "type": "array",
- "description": "Specify an array of path remappings; each element must itself be a two element array containing a source and destination path name. Overrides sourcePath.",
- "default": []
+ "anyOf": [
+ {
+ "type": "object",
+ "description": "Specify an object of path remappings; each entry has a key containing the source path and a value containing the destination path. E.g `{ \"/the/source/path\": \"/the/destination/path\" }`. Overrides sourcePath.",
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "default": {}
+ },
+ {
+ "type": "array",
+ "description": "Specify an array of path remappings; each element must itself be a two element array containing a source and destination path name. Overrides sourcePath.",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": {
+ "type": "string"
+ }
+ },
+ "default": []
+ }
+ ]
},
"debuggerRoot": {
"type": "string",
@@ -316,9 +338,31 @@
"description": "Specify a source path to remap \"./\" to allow full paths to be used when setting breakpoints in binaries that have relative source paths."
},
"sourceMap": {
- "type": "array",
- "description": "Specify an array of path remappings; each element must itself be a two element array containing a source and destination path name. Overrides sourcePath.",
- "default": []
+ "anyOf": [
+ {
+ "type": "object",
+ "description": "Specify an object of path remappings; each entry has a key containing the source path and a value containing the destination path. E.g `{ \"/the/source/path\": \"/the/destination/path\" }`. Overrides sourcePath.",
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "default": {}
+ },
+ {
+ "type": "array",
+ "description": "Specify an array of path remappings; each element must itself be a two element array containing a source and destination path name. Overrides sourcePath.",
+ "items": {
+ "type": "array",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": {
+ "type": "string"
+ }
+ },
+ "default": []
+ }
+ ]
},
"debuggerRoot": {
"type": "string",
More information about the lldb-commits
mailing list