wallace updated this revision to Diff 314151.
wallace added a comment.
Herald added a subscriber: JDevlieghere.
nit
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D93951/new/
https://reviews.llvm.org/D93951
Files:
lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py
lldb/tools/lldb-vscode/JSONUtils.cpp
lldb/tools/lldb-vscode/JSONUtils.h
lldb/tools/lldb-vscode/Options.td
lldb/tools/lldb-vscode/VSCode.h
lldb/tools/lldb-vscode/lldb-vscode.cpp
Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===================================================================
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1441,6 +1441,47 @@
g_vsc.SendJSON(llvm::json::Value(std::move(response)));
}
+std::string CreateRunInTerminalPidFile() {
+ llvm::SmallString<256> temp_file;
+ if (std::error_code EC = llvm::sys::fs::getPotentiallyUniqueTempFileName(
+ "lldb-vscode-run-in-terminal", "pid", temp_file)) {
+ llvm::errs() << "Error making unique filename: " << EC.message() << "!\n";
+ exit(1);
+ }
+ std::string pid_file = temp_file.str().str();
+ // We'll use a fifo file to communicate the target's pid with the debug
+ // adaptor.
+#if !defined(_WIN32)
+ if (int err = mkfifo(pid_file.c_str(), 0666)) {
+ perror("mkfifo failed");
+ exit(1);
+ }
+#endif
+ return pid_file;
+}
+
+void CleanUpRunInTerminalPidFile(const std::string &pid_file) {
+#if !defined(_WIN32)
+ unlink(pid_file.c_str());
+#endif
+}
+
+lldb::pid_t GetRunInTerminalDebuggeePid(const std::string &pid_file) {
+ lldb::pid_t pid;
+ std::ifstream pid_file_reader(pid_file, std::ifstream::in);
+ pid_file_reader >> pid;
+ return pid;
+}
+
+void NotifyRunInTerminalDebuggeeWasAttached(const std::string &pid_file) {
+ // We create a file to notify the debuggee that we attached.
+ std::ofstream did_attach_file(pid_file + ".attached");
+}
+
+bool RunInTerminalDebugeeWasAttached(const std::string &pid_file) {
+ return llvm::sys::fs::exists(pid_file + ".attached");
+}
+
void request_runInTerminal(const llvm::json::Object &launch_request,
llvm::json::Object &launch_response) {
// We have already created a target that has a valid "program" path to the
@@ -1449,11 +1490,12 @@
g_vsc.is_attach = true;
lldb::SBAttachInfo attach_info;
lldb::SBError error;
- attach_info.SetWaitForLaunch(true, /*async*/ true);
- g_vsc.target.Attach(attach_info, error);
- llvm::json::Object reverse_request =
- CreateRunInTerminalReverseRequest(launch_request);
+ // The debuggee will write its pid to this file
+ std::string pid_file = CreateRunInTerminalPidFile();
+
+ llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest(
+ launch_request, g_vsc.debug_adaptor_path, pid_file);
llvm::json::Object reverse_response;
lldb_vscode::PacketStatus status =
g_vsc.SendReverseRequest(reverse_request, reverse_response);
@@ -1461,24 +1503,32 @@
error.SetErrorString("Process cannot be launched by IDE.");
if (error.Success()) {
- // Wait for the attach stop event to happen or for a timeout.
- g_vsc.waiting_for_run_in_terminal = true;
- static std::mutex mutex;
- std::unique_lock<std::mutex> locker(mutex);
- g_vsc.request_in_terminal_cv.wait_for(locker, std::chrono::seconds(10));
+ lldb::pid_t pid = GetRunInTerminalDebuggeePid(pid_file);
+ attach_info.SetProcessID(pid);
+
+ g_vsc.debugger.SetAsync(false);
+ g_vsc.target.Attach(attach_info, error);
auto attached_pid = g_vsc.target.GetProcess().GetProcessID();
if (attached_pid == LLDB_INVALID_PROCESS_ID)
error.SetErrorString("Failed to attach to a process");
- else
- SendProcessEvent(Attach);
+ else {
+ NotifyRunInTerminalDebuggeeWasAttached(pid_file);
+ // We resume the process to let stopOnEntry decide whether to stop the
+ // process or not.
+ g_vsc.target.GetProcess().Continue();
+ }
+ g_vsc.debugger.SetAsync(true);
}
+ CleanUpRunInTerminalPidFile(pid_file);
+
if (error.Fail()) {
launch_response["success"] = llvm::json::Value(false);
EmplaceSafeString(launch_response, "message",
std::string(error.GetCString()));
} else {
+ SendProcessEvent(Attach);
launch_response["success"] = llvm::json::Value(true);
g_vsc.SendJSON(CreateEventObject("initialized"));
}
@@ -1556,12 +1606,6 @@
return;
}
- if (GetBoolean(arguments, "runInTerminal", false)) {
- request_runInTerminal(request, response);
- g_vsc.SendJSON(llvm::json::Value(std::move(response)));
- return;
- }
-
// Instantiate a launch info instance for the target.
auto launch_info = g_vsc.target.GetLaunchInfo();
@@ -1597,6 +1641,13 @@
// Run any pre run LLDB commands the user specified in the launch.json
g_vsc.RunPreRunCommands();
+
+ if (GetBoolean(arguments, "runInTerminal", false)) {
+ request_runInTerminal(request, response);
+ g_vsc.SendJSON(llvm::json::Value(std::move(response)));
+ return;
+ }
+
if (launchCommands.empty()) {
// Disable async events so the launch will be successful when we return from
// the launch call and the launch will happen synchronously
@@ -2949,6 +3000,36 @@
}
int main(int argc, char *argv[]) {
+ g_vsc.debug_adaptor_path = argv[0];
+
+ LLDBVSCodeOptTable T;
+ unsigned MAI, MAC;
+ llvm::ArrayRef<const char *> ArgsArr = llvm::makeArrayRef(argv + 1, argc);
+ llvm::opt::InputArgList input_args = T.ParseArgs(ArgsArr, MAI, MAC);
+
+#if !defined(_WIN32)
+ if (auto *target_arg = input_args.getLastArg(OPT_launch_target)) {
+ std::string pid_file = input_args.getLastArg(OPT_pid_file)->getValue();
+ std::ofstream pid_file_writer(pid_file, std::ofstream::out);
+ pid_file_writer << getpid() << std::endl;
+ pid_file_writer.close();
+
+ // 20 seconds waiting to be attached. We don't wait indefinitely using a
+ // signal to prevent being paused forever.
+ for (int i = 0; i < 2000; i++) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ if (RunInTerminalDebugeeWasAttached(pid_file)) {
+ const char *target = target_arg->getValue();
+ execv(target, argv + target_arg->getIndex() + 2);
+ perror("Couldn't launch target");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ llvm::outs() << "lldb-vscode didn't attach to this process";
+ exit(EXIT_FAILURE);
+ }
+#endif
// Initialize LLDB first before we do anything.
lldb::SBDebugger::Initialize();
@@ -2957,11 +3038,6 @@
int portno = -1;
- LLDBVSCodeOptTable T;
- unsigned MAI, MAC;
- llvm::ArrayRef<const char *> ArgsArr = llvm::makeArrayRef(argv + 1, argc);
- llvm::opt::InputArgList input_args = T.ParseArgs(ArgsArr, MAI, MAC);
-
if (input_args.hasArg(OPT_help)) {
printHelp(T, llvm::sys::path::filename(argv[0]));
return 0;
Index: lldb/tools/lldb-vscode/VSCode.h
===================================================================
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -77,6 +77,7 @@
};
struct VSCode {
+ std::string debug_adaptor_path;
InputStream input;
OutputStream output;
lldb::SBDebugger debugger;
Index: lldb/tools/lldb-vscode/Options.td
===================================================================
--- lldb/tools/lldb-vscode/Options.td
+++ lldb/tools/lldb-vscode/Options.td
@@ -23,3 +23,20 @@
def: Separate<["-"], "p">,
Alias<port>,
HelpText<"Alias for --port">;
+
+def launch_target: Separate<["--", "-"], "launch-target">,
+ MetaVarName<"<target>">,
+ HelpText<"Launch a target for the launchInTerminal request. Any argument "
+ "provided after this one will be passed to the target. The parameter "
+ "--pid-file must also be specified.">;
+def: Separate<["-"], "t">,
+ Alias<launch_target>,
+ HelpText<"Alias for --launch-target">;
+
+def pid_file: Separate<["--", "-"], "pid-file">,
+ MetaVarName<"<pid-file>">,
+ HelpText<"File to write the pid of the target launched with the "
+ "--launch-target option.">;
+def: Separate<["-"], "f">,
+ Alias<pid_file>,
+ HelpText<"Alias for --pid-file">;
Index: lldb/tools/lldb-vscode/JSONUtils.h
===================================================================
--- lldb/tools/lldb-vscode/JSONUtils.h
+++ lldb/tools/lldb-vscode/JSONUtils.h
@@ -449,11 +449,20 @@
/// The original launch_request object whose fields are used to construct
/// the reverse request object.
///
+/// \param[in] debug_adaptor_path
+/// Path to the current debug adaptor. It will be used to delegate the
+/// launch of the target.
+///
+/// \param[in] pid_file
+/// A file that will be used to communicate the pid of the debuggee.
+///
/// \return
/// A "runInTerminal" JSON object that follows the specification outlined by
/// Microsoft.
llvm::json::Object
-CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request);
+CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,
+ llvm::StringRef debug_adaptor_path,
+ llvm::StringRef pid_file);
} // namespace lldb_vscode
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===================================================================
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -1001,7 +1001,9 @@
/// See
/// https://microsoft.github.io/debug-adapter-protocol/specification#Reverse_Requests_RunInTerminal
llvm::json::Object
-CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request) {
+CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,
+ llvm::StringRef debug_adaptor_path,
+ llvm::StringRef pid_file) {
llvm::json::Object reverse_request;
reverse_request.try_emplace("type", "request");
reverse_request.try_emplace("command", "runInTerminal");
@@ -1012,10 +1014,13 @@
run_in_terminal_args.try_emplace("kind", "integrated");
auto launch_request_arguments = launch_request.getObject("arguments");
- std::vector<std::string> args = GetStrings(launch_request_arguments, "args");
// The program path must be the first entry in the "args" field
- args.insert(args.begin(),
- GetString(launch_request_arguments, "program").str());
+ std::vector<std::string> args = {
+ debug_adaptor_path.str(), "-f", pid_file.str(), "-t",
+ GetString(launch_request_arguments, "program").str()};
+ std::vector<std::string> target_args =
+ GetStrings(launch_request_arguments, "args");
+ args.insert(args.end(), target_args.begin(), target_args.end());
run_in_terminal_args.try_emplace("args", args);
const auto cwd = GetString(launch_request_arguments, "cwd");
Index: lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py
===================================================================
--- lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py
+++ lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py
@@ -17,7 +17,7 @@
mydir = TestBase.compute_mydir(__file__)
- @skipUnlessDarwin
+ @skipIfWindows
@skipIfRemote
def test_runInTerminal(self):
'''
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits