diff options
author | Jorge Gorbe Moya <jgorbe@google.com> | 2023-04-07 13:34:16 -0700 |
---|---|---|
committer | Jorge Gorbe Moya <jgorbe@google.com> | 2023-04-10 18:18:05 -0700 |
commit | 53aa22cd9ac4a779208cf9907354cc6d4211e783 (patch) | |
tree | 3133b154f19ad9784ff15f891dced8adab73908a /lldb/tools | |
parent | a0a141fcbe1dfd35032fa5c052e6906180a37fb1 (diff) | |
download | llvm-53aa22cd9ac4a779208cf9907354cc6d4211e783.tar.gz |
[lldb-vscode] Fix two issues with runInTerminal test.
With ptrace_scope = 1 the kernel only allows tracing descendants of a
process. When using runInTerminal, the target process is not launched
by the debugger, so we need to modify LaunchRunInTerminal to explicitly
allow tracing. This should fix a problem reported in
https://reviews.llvm.org/D84974#3903716
In order to allow only the main lldb-vscode process to attach to the
target, this change introduces a new `--debugger-pid` flag that needs
to be passed with `--launch-target` and `--comm-file`.
Also, remove a special case from the launch method in the
lldbvscode_testcase test harness. The existing test was using
stopOnEntry, so the first stop didn't happen at the expected breakpoint
unless the harness did configurationDone first.
Differential Revision: https://reviews.llvm.org/D147805
Diffstat (limited to 'lldb/tools')
-rw-r--r-- | lldb/tools/lldb-vscode/JSONUtils.cpp | 12 | ||||
-rw-r--r-- | lldb/tools/lldb-vscode/JSONUtils.h | 8 | ||||
-rw-r--r-- | lldb/tools/lldb-vscode/Options.td | 9 | ||||
-rw-r--r-- | lldb/tools/lldb-vscode/lldb-vscode.cpp | 34 |
4 files changed, 54 insertions, 9 deletions
diff --git a/lldb/tools/lldb-vscode/JSONUtils.cpp b/lldb/tools/lldb-vscode/JSONUtils.cpp index 8ec38a495777..67455abb9916 100644 --- a/lldb/tools/lldb-vscode/JSONUtils.cpp +++ b/lldb/tools/lldb-vscode/JSONUtils.cpp @@ -1102,7 +1102,8 @@ llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit unit) { llvm::json::Object CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request, llvm::StringRef debug_adaptor_path, - llvm::StringRef comm_file) { + llvm::StringRef comm_file, + lldb::pid_t debugger_pid) { llvm::json::Object reverse_request; reverse_request.try_emplace("type", "request"); reverse_request.try_emplace("command", "runInTerminal"); @@ -1115,8 +1116,13 @@ CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request, auto launch_request_arguments = launch_request.getObject("arguments"); // The program path must be the first entry in the "args" field std::vector<std::string> args = { - debug_adaptor_path.str(), "--comm-file", comm_file.str(), - "--launch-target", GetString(launch_request_arguments, "program").str()}; + debug_adaptor_path.str(), "--comm-file", comm_file.str()}; + if (debugger_pid != LLDB_INVALID_PROCESS_ID) { + args.push_back("--debugger-pid"); + args.push_back(std::to_string(debugger_pid)); + } + args.push_back("--launch-target"); + args.push_back(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()); diff --git a/lldb/tools/lldb-vscode/JSONUtils.h b/lldb/tools/lldb-vscode/JSONUtils.h index b67da7191cde..73cfb425ee29 100644 --- a/lldb/tools/lldb-vscode/JSONUtils.h +++ b/lldb/tools/lldb-vscode/JSONUtils.h @@ -479,13 +479,19 @@ llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit unit); /// \param[in] comm_file /// The fifo file used to communicate the with the target launcher. /// +/// \param[in] debugger_pid +/// The PID of the lldb-vscode instance that will attach to the target. The +/// launcher uses it on Linux tell the kernel that it should allow the +/// debugger process to attach. +/// /// \return /// A "runInTerminal" JSON object that follows the specification outlined by /// Microsoft. llvm::json::Object CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request, llvm::StringRef debug_adaptor_path, - llvm::StringRef comm_file); + llvm::StringRef comm_file, + lldb::pid_t debugger_pid); /// Create a "Terminated" JSON object that contains statistics /// diff --git a/lldb/tools/lldb-vscode/Options.td b/lldb/tools/lldb-vscode/Options.td index ff2ffd59de03..a73671ad749c 100644 --- a/lldb/tools/lldb-vscode/Options.td +++ b/lldb/tools/lldb-vscode/Options.td @@ -28,9 +28,14 @@ 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 " - "--comm-files-prefix must also be specified.">; + "--comm-file must also be specified.">; def comm_file: Separate<["--", "-"], "comm-file">, MetaVarName<"<file>">, - HelpText<"The fifo file used to communicate the with the debug adaptor" + HelpText<"The fifo file used to communicate the with the debug adaptor " "when using --launch-target.">; + +def debugger_pid: Separate<["--", "-"], "debugger-pid">, + MetaVarName<"<pid>">, + HelpText<"The PID of the lldb-vscode instance that sent the launchInTerminal " + "request when using --launch-target.">; diff --git a/lldb/tools/lldb-vscode/lldb-vscode.cpp b/lldb/tools/lldb-vscode/lldb-vscode.cpp index 51a72f2b03c9..8257a1ffbe9b 100644 --- a/lldb/tools/lldb-vscode/lldb-vscode.cpp +++ b/lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -32,6 +32,10 @@ #include <unistd.h> #endif +#if defined(__linux__) +#include <sys/prctl.h> +#endif + #include <algorithm> #include <chrono> #include <fstream> @@ -1562,8 +1566,12 @@ llvm::Error request_runInTerminal(const llvm::json::Object &launch_request) { RunInTerminalDebugAdapterCommChannel comm_channel(comm_file.m_path); + lldb::pid_t debugger_pid = LLDB_INVALID_PROCESS_ID; +#if !defined(_WIN32) + debugger_pid = getpid(); +#endif llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest( - launch_request, g_vsc.debug_adaptor_path, comm_file.m_path); + launch_request, g_vsc.debug_adaptor_path, comm_file.m_path, debugger_pid); llvm::json::Object reverse_response; lldb_vscode::PacketStatus status = g_vsc.SendReverseRequest(reverse_request, reverse_response); @@ -3141,11 +3149,21 @@ EXAMPLES: // In case of errors launching the target, a suitable error message will be // emitted to the debug adaptor. void LaunchRunInTerminalTarget(llvm::opt::Arg &target_arg, - llvm::StringRef comm_file, char *argv[]) { + llvm::StringRef comm_file, + lldb::pid_t debugger_pid, char *argv[]) { #if defined(_WIN32) llvm::errs() << "runInTerminal is only supported on POSIX systems\n"; exit(EXIT_FAILURE); #else + + // On Linux with the Yama security module enabled, a process can only attach + // to its descendants by default. In the runInTerminal case the target + // process is launched by the client so we need to allow tracing explicitly. +#if defined(__linux__) + if (debugger_pid != LLDB_INVALID_PROCESS_ID) + (void)prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0); +#endif + RunInTerminalLauncherCommChannel comm_channel(comm_file); if (llvm::Error err = comm_channel.NotifyPid()) { llvm::errs() << llvm::toString(std::move(err)) << "\n"; @@ -3238,13 +3256,23 @@ int main(int argc, char *argv[]) { if (llvm::opt::Arg *target_arg = input_args.getLastArg(OPT_launch_target)) { if (llvm::opt::Arg *comm_file = input_args.getLastArg(OPT_comm_file)) { + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + llvm::opt::Arg *debugger_pid = input_args.getLastArg(OPT_debugger_pid); + if (debugger_pid) { + llvm::StringRef debugger_pid_value = debugger_pid->getValue(); + if (debugger_pid_value.getAsInteger(10, pid)) { + llvm::errs() << "'" << debugger_pid_value << "' is not a valid " + "PID\n"; + return EXIT_FAILURE; + } + } int target_args_pos = argc; for (int i = 0; i < argc; i++) if (strcmp(argv[i], "--launch-target") == 0) { target_args_pos = i + 1; break; } - LaunchRunInTerminalTarget(*target_arg, comm_file->getValue(), + LaunchRunInTerminalTarget(*target_arg, comm_file->getValue(), pid, argv + target_args_pos); } else { llvm::errs() << "\"--launch-target\" requires \"--comm-file\" to be " |