Add code to exit the NativeProcessLinux Monitor thread on android

This CL change the logic used to terminate the monitor thread of
NativeProcessLinux to use a signal instead of pthread_cancel as
pthread_cancel is not supported on android.

Differential revision: http://reviews.llvm.org/D8205

llvm-svn: 232155
This commit is contained in:
Tamas Berghammer 2015-03-13 11:16:03 +00:00
parent 21212e4198
commit 0cbf0b13e7
4 changed files with 55 additions and 18 deletions

View File

@ -113,7 +113,7 @@ Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, vo
return ThreadLauncher::LaunchThread(thread_name, MonitorChildProcessThreadFunction, info_ptr, NULL);
}
#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
#ifndef __linux__
//------------------------------------------------------------------
// Scoped class that will disable thread canceling when it is
// constructed, and exception safely restore the previous value it
@ -140,7 +140,32 @@ public:
private:
int m_old_state; // Save the old cancelability state.
};
#endif // __ANDROID_NDK__
#endif // __linux__
#ifdef __linux__
static thread_local volatile sig_atomic_t g_usr1_called;
static void
SigUsr1Handler (int)
{
g_usr1_called = 1;
}
#endif // __linux__
static bool
CheckForMonitorCancellation()
{
#ifdef __linux__
if (g_usr1_called)
{
g_usr1_called = 0;
return true;
}
#else
::pthread_testcancel ();
#endif
return false;
}
static thread_result_t
MonitorChildProcessThreadFunction (void *arg)
@ -167,21 +192,29 @@ MonitorChildProcessThreadFunction (void *arg)
#endif
const int options = __WALL;
#ifdef __linux__
// This signal is only used to interrupt the thread from waitpid
struct sigaction sigUsr1Action;
memset(&sigUsr1Action, 0, sizeof(sigUsr1Action));
sigUsr1Action.sa_handler = SigUsr1Handler;
::sigaction(SIGUSR1, &sigUsr1Action, nullptr);
#endif // __linux__
while (1)
{
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
if (log)
log->Printf("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", function, pid, options);
// Wait for all child processes
#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
::pthread_testcancel ();
#endif
if (CheckForMonitorCancellation ())
break;
// Get signals from all children with same process group of pid
const ::pid_t wait_pid = ::waitpid (pid, &status, options);
#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
::pthread_testcancel ();
#endif
if (CheckForMonitorCancellation ())
break;
if (wait_pid == -1)
{
if (errno == EINTR)
@ -226,7 +259,7 @@ MonitorChildProcessThreadFunction (void *arg)
// Scope for pthread_cancel_disabler
{
#if !defined(__ANDROID__) && !defined(__ANDROID_NDK__)
#ifndef __linux__
ScopedPThreadCancelDisabler pthread_cancel_disabler;
#endif

View File

@ -35,11 +35,12 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/State.h"
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostNativeThread.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Utility/PseudoTerminal.h"
@ -3557,11 +3558,11 @@ NativeProcessLinux::DupDescriptor(const char *path, int fd, int flags)
}
void
NativeProcessLinux::StopMonitoringChildProcess()
NativeProcessLinux::StopMonitorThread()
{
if (m_monitor_thread.IsJoinable())
{
m_monitor_thread.Cancel();
::pthread_kill(m_monitor_thread.GetNativeThread().GetSystemHandle(), SIGUSR1);
m_monitor_thread.Join(nullptr);
}
}
@ -3569,7 +3570,7 @@ NativeProcessLinux::StopMonitoringChildProcess()
void
NativeProcessLinux::StopMonitor()
{
StopMonitoringChildProcess();
StopMonitorThread();
StopCoordinatorThread ();
StopOpThread();
sem_destroy(&m_operation_pending);

View File

@ -257,7 +257,7 @@ namespace lldb_private
Error &error);
/// Attaches to an existing process. Forms the
/// implementation of Process::DoLaunch.
/// implementation of Process::DoAttach
void
AttachToInferior (lldb::pid_t pid, Error &error);
@ -317,7 +317,7 @@ namespace lldb_private
/// Stops the child monitor thread.
void
StopMonitoringChildProcess();
StopMonitorThread();
/// Stops the operation thread used to attach/launch a process.
void

View File

@ -24,6 +24,7 @@
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostNativeThread.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Target/Thread.h"
@ -94,6 +95,8 @@
using namespace lldb_private;
static Operation* EXIT_OPERATION = nullptr;
// FIXME: this code is host-dependent with respect to types and
// endianness and needs to be fixed. For example, lldb::addr_t is
// hard-coded to uint64_t, but on a 32-bit Linux host, ptrace requires
@ -2335,7 +2338,7 @@ ProcessMonitor::StopMonitoringChildProcess()
{
if (m_monitor_thread.IsJoinable())
{
m_monitor_thread.Cancel();
::pthread_kill(m_monitor_thread.GetNativeThread().GetSystemHandle(), SIGUSR1);
m_monitor_thread.Join(nullptr);
}
}
@ -2359,6 +2362,6 @@ ProcessMonitor::StopOpThread()
if (!m_operation_thread.IsJoinable())
return;
m_operation_thread.Cancel();
DoOperation(EXIT_OPERATION);
m_operation_thread.Join(nullptr);
}