summaryrefslogtreecommitdiff
path: root/lldb/tools
diff options
context:
space:
mode:
authorJorge Gorbe Moya <jgorbe@google.com>2023-04-07 13:34:16 -0700
committerJorge Gorbe Moya <jgorbe@google.com>2023-04-10 18:18:05 -0700
commit53aa22cd9ac4a779208cf9907354cc6d4211e783 (patch)
tree3133b154f19ad9784ff15f891dced8adab73908a /lldb/tools
parenta0a141fcbe1dfd35032fa5c052e6906180a37fb1 (diff)
downloadllvm-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.cpp12
-rw-r--r--lldb/tools/lldb-vscode/JSONUtils.h8
-rw-r--r--lldb/tools/lldb-vscode/Options.td9
-rw-r--r--lldb/tools/lldb-vscode/lldb-vscode.cpp34
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 "