anton.kolesov updated this revision to Diff 243828.
anton.kolesov retitled this revision from "[lldb] Set executable module when
adding modules to the Target" to "[lldb-vscode] Ensure that target matches the
executable file".
anton.kolesov edited the summary of this revision.
anton.kolesov added a comment.
Reverted to the original idea of modifying lldb-vscode. Unlike first version,
this commit also modifies request_attach to have the same behaviour. Two new
properties are added to request arguments: "targetTriple" and "platformName" to
specify values to respective arguments of SBDebugger::CreateTarget().
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D70847/new/
https://reviews.llvm.org/D70847
Files:
lldb/tools/lldb-vscode/lldb-vscode.cpp
lldb/tools/lldb-vscode/package.json
Index: lldb/tools/lldb-vscode/package.json
===================================================================
--- lldb/tools/lldb-vscode/package.json
+++ lldb/tools/lldb-vscode/package.json
@@ -122,6 +122,14 @@
"type": "string",
"description": "Specify a working directory to set the debug adaptor to so relative object files can be located."
},
+ "targetTriple": {
+ "type": "string",
+ "description": "Triplet of the target architecture to override value derived from the program file."
+ },
+ "platformName": {
+ "type": "string",
+ "description": "Name of the execution platform to override value derived from the program file."
+ },
"initCommands": {
"type": "array",
"description": "Initialization commands executed upon debugger startup.",
@@ -175,6 +183,14 @@
"type": "string",
"description": "Specify a working directory to set the debug adaptor to so relative object files can be located."
},
+ "targetTriple": {
+ "type": "string",
+ "description": "Triplet of the target architecture to override value derived from the program file."
+ },
+ "platformName": {
+ "type": "string",
+ "description": "Name of the execution platform to override value derived from the program file."
+ },
"attachCommands": {
"type": "array",
"description": "Custom commands that are executed instead of attaching to a process ID or to a process by name. These commands may optionally create a new target and must perform an attach. A valid process must exist after these commands complete or the \"attach\" will fail.",
Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===================================================================
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -110,6 +110,16 @@
return newsockfd;
}
+void AddBreakpointListener(VSCode &vscode) {
+ // Configure breakpoint event listeners for the target.
+ lldb::SBListener listener = vscode.debugger.GetListener();
+ listener.StartListeningForEvents(
+ vscode.target.GetBroadcaster(),
+ lldb::SBTarget::eBroadcastBitBreakpointChanged);
+ listener.StartListeningForEvents(vscode.broadcaster,
+ eBroadcastBitStopEventThread);
+}
+
std::vector<const char *> MakeArgv(const llvm::ArrayRef<std::string> &strs) {
// Create and return an array of "const char *", one for each C string in
// "strs" and terminate the list with a NULL. This can be used for argument
@@ -512,27 +522,45 @@
// Run any initialize LLDB commands the user specified in the launch.json
g_vsc.RunInitCommands();
- // Grab the name of the program we need to debug and set it as the first
- // argument that will be passed to the program we will debug.
- const auto program = GetString(arguments, "program");
- if (!program.empty()) {
- lldb::SBFileSpec program_fspec(program.data(), true /*resolve_path*/);
-
- g_vsc.launch_info.SetExecutableFile(program_fspec,
- false /*add_as_first_arg*/);
- const char *target_triple = nullptr;
- const char *uuid_cstr = nullptr;
- // Stand alone debug info file if different from executable
- const char *symfile = nullptr;
- g_vsc.target.AddModule(program.data(), target_triple, uuid_cstr, symfile);
- if (error.Fail()) {
- response["success"] = llvm::json::Value(false);
- EmplaceSafeString(response, "message", std::string(error.GetCString()));
- g_vsc.SendJSON(llvm::json::Value(std::move(response)));
- return;
- }
+ // Grab the name of the program we need to debug and create a target using
+ // the given program as an argument. Executable file can be a source of target
+ // architecture and platform, if they differ from the host. Setting exe path
+ // in launch info is useless because Target.Launch() will not change
+ // architecture and platform, therefore they should be known at the target
+ // creation. We also use target triple and platform from the launch
+ // configuration, if given, since in some cases ELF file doesn't contain
+ // enough information to determine correct arch and platform (or ELF can be
+ // omitted at all), so it is good to leave the user an apportunity to specify
+ // those. Any of those three can be left empty
+ llvm::StringRef target_triple = GetString(arguments, "targetTriple");
+ llvm::StringRef platform_name = GetString(arguments, "platformName");
+ llvm::StringRef program = GetString(arguments, "program");
+ lldb::SBError status;
+ g_vsc.target = g_vsc.debugger.CreateTarget(
+ program.data(),
+ target_triple.data(),
+ platform_name.data(),
+ true, // Add dependent modules.
+ status
+ );
+
+ if (!g_vsc.target.IsValid()) {
+ response["success"] = llvm::json::Value(false);
+ std::string errmsg;
+ if (status.Fail())
+ errmsg = llvm::formatv(
+ "Could not create a target for a program '{0}': {1}.",
+ program, status.GetCString());
+ else
+ errmsg = llvm::formatv("Could not create a target for a program '{0}'.",
+ program);
+ EmplaceSafeString(response, "message", errmsg);
+ g_vsc.SendJSON(llvm::json::Value(std::move(response)));
+ return;
}
+ AddBreakpointListener(g_vsc);
+
const bool detatchOnError = GetBoolean(arguments, "detachOnError", false);
g_vsc.launch_info.SetDetachOnError(detatchOnError);
@@ -951,7 +979,7 @@
for (size_t i = 0; i < count; i++) {
std::string match = matches.GetStringAtIndex(i);
std::string description = descriptions.GetStringAtIndex(i);
-
+
llvm::json::Object item;
llvm::StringRef match_ref = match;
@@ -1217,13 +1245,6 @@
g_vsc.debugger.SetErrorFileHandle(out, false);
}
- g_vsc.target = g_vsc.debugger.CreateTarget(nullptr);
- lldb::SBListener listener = g_vsc.debugger.GetListener();
- listener.StartListeningForEvents(
- g_vsc.target.GetBroadcaster(),
- lldb::SBTarget::eBroadcastBitBreakpointChanged);
- listener.StartListeningForEvents(g_vsc.broadcaster,
- eBroadcastBitStopEventThread);
// Start our event thread so we can receive events from the debugger, target,
// process and more.
g_vsc.event_thread = std::thread(EventThreadFunction);
@@ -1261,7 +1282,7 @@
// The debug adapter supports the stepInTargetsRequest.
body.try_emplace("supportsStepInTargetsRequest", false);
// We need to improve the current implementation of completions in order to
- // enable it again. For some context, this is how VSCode works:
+ // enable it again. For some context, this is how VSCode works:
// - VSCode sends a completion request whenever chars are added, the user
// triggers completion manually via CTRL-space or similar mechanisms, but
// not when there's a deletion. Besides, VSCode doesn't let us know which
@@ -1365,39 +1386,59 @@
SetSourceMapFromArguments(*arguments);
- // Run any initialize LLDB commands the user specified in the launch.json
+ // Run any initialize LLDB commands the user specified in the launch.json.
+ // This is run before target is created, so commands can't do anything with
+ // the targets - preRunCommands are run with the target.
g_vsc.RunInitCommands();
+ // Grab the name of the program we need to debug and create a target using
+ // the given program as an argument. Executable file can be a source of target
+ // architecture and platform, if they differ from the host. Setting exe path
+ // in launch info is useless because Target.Launch() will not change
+ // architecture and platform, therefore they should be known at the target
+ // creation. We also use target triple and platform from the launch
+ // configuration, if given, since in some cases ELF file doesn't contain
+ // enough information to determine correct arch and platform (or ELF can be
+ // omitted at all), so it is good to leave the user an apportunity to specify
+ // those. Any of those three can be left empty
+ llvm::StringRef target_triple = GetString(arguments, "targetTriple");
+ llvm::StringRef platform_name = GetString(arguments, "platformName");
+ llvm::StringRef program = GetString(arguments, "program");
+ lldb::SBError status;
+ g_vsc.target = g_vsc.debugger.CreateTarget(
+ program.data(),
+ target_triple.data(),
+ platform_name.data(),
+ true, // Add dependent modules.
+ status
+ );
+
+ if (!g_vsc.target.IsValid()) {
+ response["success"] = llvm::json::Value(false);
+ std::string errmsg;
+ if (status.Fail())
+ errmsg = llvm::formatv(
+ "Could not create a target for a program '{0}': {1}.",
+ program, status.GetCString());
+ else
+ errmsg = llvm::formatv("Could not create a target for a program '{0}'.",
+ program);
+ EmplaceSafeString(response, "message", errmsg);
+ g_vsc.SendJSON(llvm::json::Value(std::move(response)));
+ return;
+ }
+
+ AddBreakpointListener(g_vsc);
+
+ // Instantiate a launch info instance for the target.
+ g_vsc.launch_info = g_vsc.target.GetLaunchInfo();
+
// Grab the current working directory if there is one and set it in the
// launch info.
const auto cwd = GetString(arguments, "cwd");
if (!cwd.empty())
g_vsc.launch_info.SetWorkingDirectory(cwd.data());
- // Grab the name of the program we need to debug and set it as the first
- // argument that will be passed to the program we will debug.
- llvm::StringRef program = GetString(arguments, "program");
- if (!program.empty()) {
- lldb::SBFileSpec program_fspec(program.data(), true /*resolve_path*/);
- g_vsc.launch_info.SetExecutableFile(program_fspec,
- true /*add_as_first_arg*/);
- const char *target_triple = nullptr;
- const char *uuid_cstr = nullptr;
- // Stand alone debug info file if different from executable
- const char *symfile = nullptr;
- lldb::SBModule module = g_vsc.target.AddModule(
- program.data(), target_triple, uuid_cstr, symfile);
- if (!module.IsValid()) {
- response["success"] = llvm::json::Value(false);
-
- EmplaceSafeString(
- response, "message",
- llvm::formatv("Could not load program '{0}'.", program).str());
- g_vsc.SendJSON(llvm::json::Value(std::move(response)));
- return;
- }
- }
-
// Extract any extra arguments and append them to our program arguments for
// when we launch
auto args = GetStrings(arguments, "args");
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits