diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp --- a/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/lldb/source/Commands/CommandObjectPlatform.cpp @@ -6,7 +6,6 @@ // //===----------------------------------------------------------------------===// -#include #include "CommandObjectPlatform.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -23,6 +22,7 @@ #include "lldb/Target/Process.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/DataExtractor.h" +#include #include "llvm/ADT/SmallString.h" #include "llvm/Support/Threading.h" @@ -1152,8 +1152,7 @@ class CommandOptions : public Options { public: CommandOptions() - : Options(), match_info(), show_args(false), verbose(false) { - } + : Options(), match_info(), show_args(false), verbose(false) {} ~CommandOptions() override = default; @@ -1264,6 +1263,10 @@ verbose = true; break; + case 'x': + match_info.SetMatchAllUsers(true); + break; + default: llvm_unreachable("Unimplemented option"); } @@ -1603,7 +1606,6 @@ ExecutionContext exe_ctx = GetCommandInterpreter().GetExecutionContext(); m_options.NotifyOptionParsingStarting(&exe_ctx); - // Print out an usage syntax on an empty command line. if (raw_command_line.empty()) { result.GetOutputStream().Printf("%s\n", this->GetSyntax().str().c_str()); diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -602,6 +602,9 @@ def platform_process_list_show_args : Option<"show-args", "A">, GroupRange<1, 6>, Desc<"Show process arguments instead of the process executable basename.">; + def platform_process_list_all_users: Option<"all-users", "x">, + GroupRange<1,6>, + Desc<"Show processes matching all user IDs.">; def platform_process_list_verbose : Option<"verbose", "v">, GroupRange<1, 6>, Desc<"Enable verbose output.">; } diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -144,68 +144,80 @@ } } -static bool GetProcessAndStatInfo(::pid_t pid, - ProcessInstanceInfo &process_info, - ProcessState &State, ::pid_t &tracerpid) { - tracerpid = 0; - process_info.Clear(); +static bool GetProcessArgs(::pid_t pid, ProcessInstanceInfo &process_info) { + auto BufferOrError = getProcFile(pid, "cmdline"); + if (!BufferOrError) + return false; + std::unique_ptr Cmdline = std::move(*BufferOrError); + llvm::StringRef Arg0, Rest; + std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0'); + process_info.SetArg0(Arg0); + while (!Rest.empty()) { + llvm::StringRef Arg; + std::tie(Arg, Rest) = Rest.split('\0'); + process_info.GetArguments().AppendArgument(Arg); + } + return true; +} + +static void GetExePathAndArch(::pid_t pid, ProcessInstanceInfo &process_info) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + std::string ExePath(PATH_MAX, '\0'); // We can't use getProcFile here because proc/[pid]/exe is a symbolic link. llvm::SmallString<64> ProcExe; (llvm::Twine("/proc/") + llvm::Twine(pid) + "/exe").toVector(ProcExe); - std::string ExePath(PATH_MAX, '\0'); ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX); - if (len <= 0) { + if (len > 0) { + ExePath.resize(len); + } else { LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid, Status(errno, eErrorTypePOSIX)); - return false; + ExePath.resize(0); } - ExePath.resize(len); - // If the binary has been deleted, the link name has " (deleted)" appended. // Remove if there. llvm::StringRef PathRef = ExePath; PathRef.consume_back(" (deleted)"); - process_info.SetArchitecture(GetELFProcessCPUType(PathRef)); + if (!PathRef.empty()) { + process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native); + process_info.SetArchitecture(GetELFProcessCPUType(PathRef)); + } +} +static void GetProcessEnviron(::pid_t pid, ProcessInstanceInfo &process_info) { // Get the process environment. auto BufferOrError = getProcFile(pid, "environ"); - if (!BufferOrError) - return false; + if (!BufferOrError) { + return; + } std::unique_ptr Environ = std::move(*BufferOrError); - - // Get the command line used to start the process. - BufferOrError = getProcFile(pid, "cmdline"); - if (!BufferOrError) - return false; - std::unique_ptr Cmdline = std::move(*BufferOrError); - - // Get User and Group IDs and get tracer pid. - if (!GetStatusInfo(pid, process_info, State, tracerpid)) - return false; - - process_info.SetProcessID(pid); - process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native); - llvm::StringRef Rest = Environ->getBuffer(); while (!Rest.empty()) { llvm::StringRef Var; std::tie(Var, Rest) = Rest.split('\0'); process_info.GetEnvironment().insert(Var); } +} - llvm::StringRef Arg0; - std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0'); - process_info.SetArg0(Arg0); - while (!Rest.empty()) { - llvm::StringRef Arg; - std::tie(Arg, Rest) = Rest.split('\0'); - process_info.GetArguments().AppendArgument(Arg); - } +static bool GetProcessAndStatInfo(::pid_t pid, + ProcessInstanceInfo &process_info, + ProcessState &State, ::pid_t &tracerpid) { + tracerpid = 0; + process_info.Clear(); + + process_info.SetProcessID(pid); + + GetExePathAndArch(pid, process_info); + GetProcessArgs(pid, process_info); + GetProcessEnviron(pid, process_info); + + // Get User and Group IDs and get tracer pid. + if (!GetStatusInfo(pid, process_info, State, tracerpid)) + return false; return true; } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2176,8 +2176,7 @@ if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) packet.Printf("egid:%u;", match_info.GetProcessInfo().GetEffectiveGroupID()); - if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) - packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0); + packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0); if (match_info.GetProcessInfo().GetArchitecture().IsValid()) { const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture();