aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Host/common/Host.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Host/common/Host.cpp')
-rw-r--r--contrib/llvm-project/lldb/source/Host/common/Host.cpp222
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);
+}