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 @@ -55,7 +55,7 @@ return false; llvm::StringRef Rest = BufferOrError.get()->getBuffer(); - while(!Rest.empty()) { + while (!Rest.empty()) { llvm::StringRef Line; std::tie(Line, Rest) = Rest.split('\n'); @@ -144,68 +144,102 @@ } } -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 bool GetExePathArchAndProcessArgs(::pid_t pid, + ProcessInstanceInfo &process_info) { + GetProcessArgs(pid, 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); +#if defined(__ANDROID__) + // On android we fallback to Arg0, which commonly is an apk package name. + if (!process_info.GetArg0().empty()) { + ExePath = process_info.GetArg0(); + } +#endif } - ExePath.resize(len); - + if (ExePath.empty()) + return false; // If the binary has been deleted, the link name has " (deleted)" appended. // Remove if there. - llvm::StringRef PathRef = ExePath; + llvm::StringRef PathRef(ExePath); PathRef.consume_back(" (deleted)"); + process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native); process_info.SetArchitecture(GetELFProcessCPUType(PathRef)); + return true; +} +static bool GetProcessEnviron(::pid_t pid, ProcessInstanceInfo &process_info) { // Get the process environment. auto BufferOrError = getProcFile(pid, "environ"); - if (!BufferOrError) + if (BufferOrError) { + std::unique_ptr Environ = std::move(*BufferOrError); + llvm::StringRef Rest = Environ->getBuffer(); + while (!Rest.empty()) { + llvm::StringRef Var; + std::tie(Var, Rest) = Rest.split('\0'); + process_info.GetEnvironment().insert(Var); + } + return true; + } +#if defined(__ANDROID__) + // It's okay if we can't get the environment on android + return true; +#else + return false; +#endif +} + +static bool GetProcessAndStatInfo(::pid_t pid, + ProcessInstanceInfo &process_info, + ProcessState &State, ::pid_t &tracerpid) { + tracerpid = 0; + process_info.Clear(); + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + + process_info.SetProcessID(pid); + + if (!GetExePathArchAndProcessArgs(pid, process_info)) return false; - std::unique_ptr Environ = std::move(*BufferOrError); + printf("%d: passed 1\n", pid); - // Get the command line used to start the process. - BufferOrError = getProcFile(pid, "cmdline"); - if (!BufferOrError) + if (!GetProcessEnviron(pid, process_info)) return false; - std::unique_ptr Cmdline = std::move(*BufferOrError); + printf("%d: passed 2\n", pid); // 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); - } + printf("%d: passed 3\n", pid); return true; } @@ -219,7 +253,14 @@ struct dirent *direntry = nullptr; const uid_t our_uid = getuid(); const lldb::pid_t our_pid = getpid(); - bool all_users = match_info.GetMatchAllUsers(); + bool all_users = +#if defined(__ANDROID__) + // On android each apk has its own user, so it's better to display all + // users instead of the current one. + true; +#else + match_info.GetMatchAllUsers(); +#endif while ((direntry = readdir(dirproc)) != nullptr) { if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name)) @@ -237,6 +278,7 @@ if (!GetProcessAndStatInfo(pid, process_info, State, tracerpid)) continue; + printf("%d: passed main function\n", pid); // Skip if process is being debugged. if (tracerpid != 0) diff --git a/lldb/source/Utility/FileSpec.cpp b/lldb/source/Utility/FileSpec.cpp --- a/lldb/source/Utility/FileSpec.cpp +++ b/lldb/source/Utility/FileSpec.cpp @@ -127,53 +127,55 @@ return true; for (auto i = path.find_first_of("\\/"); i != llvm::StringRef::npos; i = path.find_first_of("\\/", i + 1)) { - const auto next = safeCharAtIndex(path, i+1); + const auto next = safeCharAtIndex(path, i + 1); switch (next) { + case 0: + // path separator char at the end of the string which should be + // stripped unless it is the one and only character + return i > 0; + case '/': + case '\\': + // two path separator chars in the middle of a path needs to be + // normalized + if (i > 0) + return true; + ++i; + break; + + case '.': { + const auto next_next = safeCharAtIndex(path, i + 2); + switch (next_next) { + default: + break; case 0: - // path separator char at the end of the string which should be - // stripped unless it is the one and only character - return i > 0; + return true; // ends with "/." case '/': case '\\': - // two path separator chars in the middle of a path needs to be - // normalized - if (i > 0) - return true; - ++i; - break; - + return true; // contains "/./" case '.': { - const auto next_next = safeCharAtIndex(path, i+2); - switch (next_next) { - default: break; - case 0: return true; // ends with "/." - case '/': - case '\\': - return true; // contains "/./" - case '.': { - const auto next_next_next = safeCharAtIndex(path, i+3); - switch (next_next_next) { - default: break; - case 0: return true; // ends with "/.." - case '/': - case '\\': - return true; // contains "/../" - } - break; - } - } + const auto next_next_next = safeCharAtIndex(path, i + 3); + switch (next_next_next) { + default: + break; + case 0: + return true; // ends with "/.." + case '/': + case '\\': + return true; // contains "/../" } break; + } + } + } break; - default: - break; + default: + break; } } return false; } - -} +} // namespace // Assignment operator. const FileSpec &FileSpec::operator=(const FileSpec &rhs) { if (this != &rhs) { @@ -220,11 +222,11 @@ // Split path into filename and directory. We rely on the underlying char // pointer to be nullptr when the components are empty. llvm::StringRef filename = llvm::sys::path::filename(resolved, m_style); - if(!filename.empty()) + if (!filename.empty()) m_filename.SetString(filename); llvm::StringRef directory = llvm::sys::path::parent_path(resolved, m_style); - if(!directory.empty()) + if (!directory.empty()) m_directory.SetString(directory); } @@ -315,9 +317,8 @@ // case sensitivity of equality test const bool case_sensitive = a.IsCaseSensitive() || b.IsCaseSensitive(); - const bool filenames_equal = ConstString::Equals(a.m_filename, - b.m_filename, - case_sensitive); + const bool filenames_equal = + ConstString::Equals(a.m_filename, b.m_filename, case_sensitive); if (!filenames_equal) return false; @@ -328,7 +329,8 @@ return a == b; } -llvm::Optional FileSpec::GuessPathStyle(llvm::StringRef absolute_path) { +llvm::Optional +FileSpec::GuessPathStyle(llvm::StringRef absolute_path) { if (absolute_path.startswith("/")) return Style::posix; if (absolute_path.startswith(R"(\\)")) @@ -495,9 +497,7 @@ return g_source_file_regex.Execute(extension.GetStringRef()); } -bool FileSpec::IsRelative() const { - return !IsAbsolute(); -} +bool FileSpec::IsRelative() const { return !IsAbsolute(); } bool FileSpec::IsAbsolute() const { llvm::SmallString<64> current_path;