diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Host/common/Host.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Host/common/Host.cpp | 222 |
1 files changed, 70 insertions, 152 deletions
diff --git a/contrib/llvm-project/lldb/source/Host/common/Host.cpp b/contrib/llvm-project/lldb/source/Host/common/Host.cpp index 53a096c617df..f35eb47ff683 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Host.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Host.cpp @@ -56,8 +56,8 @@ #include "lldb/Host/ProcessLauncher.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Predicate.h" #include "lldb/Utility/ReproducerProvider.h" @@ -90,30 +90,24 @@ int __pthread_fchdir(int fildes); using namespace lldb; using namespace lldb_private; -#if !defined(__APPLE__) && !defined(_WIN32) -struct MonitorInfo { - lldb::pid_t pid; // The process ID to monitor - Host::MonitorChildProcessCallback - callback; // The callback function to call when "pid" exits or signals - bool monitor_signals; // If true, call the callback when "pid" gets signaled. -}; +#if !defined(__APPLE__) +void Host::SystemLog(llvm::StringRef message) { llvm::errs() << message; } +#endif -static thread_result_t MonitorChildProcessThreadFunction(void *arg); +#if !defined(__APPLE__) && !defined(_WIN32) +static thread_result_t +MonitorChildProcessThreadFunction(::pid_t pid, + Host::MonitorChildProcessCallback callback); llvm::Expected<HostThread> Host::StartMonitoringChildProcess( - const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid, - bool monitor_signals) { - MonitorInfo *info_ptr = new MonitorInfo(); - - info_ptr->pid = pid; - info_ptr->callback = callback; - info_ptr->monitor_signals = monitor_signals; - + const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid) { char thread_name[256]; ::snprintf(thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid); - return ThreadLauncher::LaunchThread( - thread_name, MonitorChildProcessThreadFunction, info_ptr, 0); + assert(pid <= UINT32_MAX); + return ThreadLauncher::LaunchThread(thread_name, [pid, callback] { + return MonitorChildProcessThreadFunction(pid, callback); + }); } #ifndef __linux__ @@ -162,26 +156,13 @@ static bool CheckForMonitorCancellation() { return false; } -static thread_result_t MonitorChildProcessThreadFunction(void *arg) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - const char *function = __FUNCTION__; - LLDB_LOGF(log, "%s (arg = %p) thread starting...", function, arg); - - MonitorInfo *info = (MonitorInfo *)arg; - - const Host::MonitorChildProcessCallback callback = info->callback; - const bool monitor_signals = info->monitor_signals; - - assert(info->pid <= UINT32_MAX); - const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid; - - delete info; +static thread_result_t +MonitorChildProcessThreadFunction(::pid_t pid, + Host::MonitorChildProcessCallback callback) { + Log *log = GetLog(LLDBLog::Process); + LLDB_LOG(log, "pid = {0}", pid); int status = -1; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) -#define __WALL 0 -#endif - const int options = __WALL; #ifdef __linux__ // This signal is only used to interrupt the thread from waitpid @@ -191,126 +172,57 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) { ::sigaction(SIGUSR1, &sigUsr1Action, nullptr); #endif // __linux__ - while (true) { - log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); - LLDB_LOGF(log, "%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", - function, pid, options); + while(1) { + log = GetLog(LLDBLog::Process); + LLDB_LOG(log, "::waitpid({0}, &status, 0)...", pid); if (CheckForMonitorCancellation()) - break; + return nullptr; + + const ::pid_t wait_pid = ::waitpid(pid, &status, 0); - // Get signals from all children with same process group of pid - const ::pid_t wait_pid = ::waitpid(pid, &status, options); + LLDB_LOG(log, "::waitpid({0}, &status, 0) => pid = {1}, status = {2:x}", pid, + wait_pid, status); if (CheckForMonitorCancellation()) + return nullptr; + + if (wait_pid != -1) break; + if (errno != EINTR) { + LLDB_LOG(log, "pid = {0}, thread exiting because waitpid failed ({1})...", + pid, llvm::sys::StrError()); + return nullptr; + } + } - if (wait_pid == -1) { - if (errno == EINTR) - continue; - else { - LLDB_LOG(log, - "arg = {0}, thread exiting because waitpid failed ({1})...", - arg, llvm::sys::StrError()); - break; - } - } else if (wait_pid > 0) { - bool exited = false; - int signal = 0; - int exit_status = 0; - const char *status_cstr = nullptr; - if (WIFSTOPPED(status)) { - signal = WSTOPSIG(status); - status_cstr = "STOPPED"; - } else if (WIFEXITED(status)) { - exit_status = WEXITSTATUS(status); - status_cstr = "EXITED"; - exited = true; - } else if (WIFSIGNALED(status)) { - signal = WTERMSIG(status); - status_cstr = "SIGNALED"; - if (wait_pid == abs(pid)) { - exited = true; - exit_status = -1; - } - } else { - status_cstr = "(\?\?\?)"; - } + int signal = 0; + int exit_status = 0; + if (WIFEXITED(status)) { + exit_status = WEXITSTATUS(status); + } else if (WIFSIGNALED(status)) { + signal = WTERMSIG(status); + exit_status = -1; + } else { + llvm_unreachable("Unknown status"); + } - // Scope for pthread_cancel_disabler - { + // Scope for pthread_cancel_disabler + { #ifndef __linux__ - ScopedPThreadCancelDisabler pthread_cancel_disabler; + ScopedPThreadCancelDisabler pthread_cancel_disabler; #endif - log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); - LLDB_LOGF(log, - "%s ::waitpid (pid = %" PRIi32 - ", &status, options = %i) => pid = %" PRIi32 - ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", - function, pid, options, wait_pid, status, status_cstr, signal, - exit_status); - - if (exited || (signal != 0 && monitor_signals)) { - bool callback_return = false; - if (callback) - callback_return = callback(wait_pid, exited, signal, exit_status); - - // If our process exited, then this thread should exit - if (exited && wait_pid == abs(pid)) { - LLDB_LOGF(log, - "%s (arg = %p) thread exiting because pid received " - "exit signal...", - __FUNCTION__, arg); - break; - } - // If the callback returns true, it means this process should exit - if (callback_return) { - LLDB_LOGF(log, - "%s (arg = %p) thread exiting because callback " - "returned true...", - __FUNCTION__, arg); - break; - } - } - } - } + if (callback) + callback(pid, signal, exit_status); } - log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); - LLDB_LOGF(log, "%s (arg = %p) thread exiting...", __FUNCTION__, arg); - + LLDB_LOG(GetLog(LLDBLog::Process), "pid = {0} thread exiting...", pid); return nullptr; } #endif // #if !defined (__APPLE__) && !defined (_WIN32) -#if !defined(__APPLE__) - -void Host::SystemLog(SystemLogType type, const char *format, va_list args) { - vfprintf(stderr, format, args); -} - -#endif - -void Host::SystemLog(SystemLogType type, const char *format, ...) { - { - va_list args; - va_start(args, format); - SystemLog(type, format, args); - va_end(args); - } - - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST)); - if (log && log->GetVerbose()) { - // Log to log channel. This allows testcases to grep for log output. - va_list args; - va_start(args, format); - log->VAPrintf(format, args); - va_end(args); - } -} - lldb::pid_t Host::GetCurrentProcessID() { return ::getpid(); } #ifndef _WIN32 @@ -450,11 +362,10 @@ struct ShellInfo { int status = -1; }; -static bool +static void MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid, - bool exited, // True if the process did exit - int signo, // Zero for no signal - int status) // Exit value of process if signal is zero + int signo, // Zero for no signal + int status) // Exit value of process if signal is zero { shell_info->pid = pid; shell_info->signo = signo; @@ -462,7 +373,6 @@ MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid, // Let the thread running Host::RunShellCommand() know that the process // exited and that ShellInfo has been filled in by broadcasting to it shell_info->process_reaped.SetValue(true, eBroadcastAlways); - return true; } Status Host::RunShellCommand(llvm::StringRef command, @@ -557,12 +467,9 @@ Status Host::RunShellCommand(llvm::StringRef shell_path, const Args &args, launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true); std::shared_ptr<ShellInfo> shell_info_sp(new ShellInfo()); - const bool monitor_signals = false; launch_info.SetMonitorProcessCallback( std::bind(MonitorShellCommand, shell_info_sp, std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3, - std::placeholders::_4), - monitor_signals); + std::placeholders::_2, std::placeholders::_3)); error = LaunchProcess(launch_info); const lldb::pid_t pid = launch_info.GetProcessID(); @@ -595,11 +502,13 @@ Status Host::RunShellCommand(llvm::StringRef shell_path, const Args &args, error.SetErrorStringWithFormat( "shell command output is too large to fit into a std::string"); } else { - auto Buffer = - FileSystem::Instance().CreateDataBuffer(output_file_spec); + WritableDataBufferSP Buffer = + FileSystem::Instance().CreateWritableDataBuffer( + output_file_spec); if (error.Success()) - command_output_ptr->assign(Buffer->GetChars(), - Buffer->GetByteSize()); + command_output_ptr->assign( + reinterpret_cast<char *>(Buffer->GetBytes()), + Buffer->GetByteSize()); } } } @@ -644,6 +553,7 @@ bool Host::OpenFileInExternalEditor(const FileSpec &file_spec, return false; } +bool Host::IsInteractiveGraphicSession() { return false; } #endif std::unique_ptr<Connection> Host::CreateDefaultConnection(llvm::StringRef url) { @@ -721,3 +631,11 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, return result; } + +char SystemLogHandler::ID; + +SystemLogHandler::SystemLogHandler() {} + +void SystemLogHandler::Emit(llvm::StringRef message) { + Host::SystemLog(message); +} |