mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 961959: fix profiler breakage for the Nuwa process. r=khuey,benwa
This commit is contained in:
parent
1de28836a9
commit
9556ddc7f7
@ -7031,7 +7031,7 @@ if test "$OS_TARGET" = Android; then
|
||||
WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=memccpy,--wrap=memchr,--wrap=memrchr,--wrap=memcmp,--wrap=memcpy,--wrap=memmove,--wrap=memset,--wrap=memmem,--wrap=memswap,--wrap=index,--wrap=strchr,--wrap=strrchr,--wrap=strlen,--wrap=strcmp,--wrap=strcpy,--wrap=strcat,--wrap=strcasecmp,--wrap=strncasecmp,--wrap=strstr,--wrap=strcasestr,--wrap=strtok,--wrap=strtok_r,--wrap=strerror,--wrap=strerror_r,--wrap=strnlen,--wrap=strncat,--wrap=strncmp,--wrap=strncpy,--wrap=strlcat,--wrap=strlcpy,--wrap=strcspn,--wrap=strpbrk,--wrap=strsep,--wrap=strspn,--wrap=strcoll,--wrap=strxfrm"
|
||||
fi
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = gonk -a -n "$MOZ_NUWA_PROCESS"; then
|
||||
WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=pthread_create,--wrap=epoll_wait,--wrap=poll,--wrap=pthread_cond_timedwait,--wrap=__pthread_cond_timedwait,--wrap=pthread_cond_wait,--wrap=epoll_create,--wrap=epoll_ctl,--wrap=close,--wrap=pthread_key_create,--wrap=pthread_key_delete,--wrap=socketpair,--wrap=pthread_self,--wrap=pthread_mutex_lock,--wrap=pthread_join,--wrap=pipe,--wrap=pipe2"
|
||||
WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=pthread_create,--wrap=epoll_wait,--wrap=poll,--wrap=pthread_cond_timedwait,--wrap=__pthread_cond_timedwait,--wrap=pthread_cond_wait,--wrap=epoll_create,--wrap=epoll_ctl,--wrap=close,--wrap=pthread_key_create,--wrap=pthread_key_delete,--wrap=socketpair,--wrap=pthread_self,--wrap=pthread_mutex_lock,--wrap=pthread_join,--wrap=pipe,--wrap=pipe2,--wrap=tgkill"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -15,9 +15,11 @@
|
||||
#include <pthread.h>
|
||||
#include <alloca.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <vector>
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
@ -25,6 +27,10 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
extern "C" MFBT_API int tgkill(pid_t tgid, pid_t tid, int signalno) {
|
||||
return syscall(__NR_tgkill, tgid, tid, signalno);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the wrappers to a selected set of pthread and system-level functions
|
||||
* as the basis for implementing Zygote-like preforking mechanism.
|
||||
@ -62,7 +68,6 @@ int __real_pipe2(int __pipedes[2], int flags);
|
||||
int __real_pipe(int __pipedes[2]);
|
||||
int __real_epoll_ctl(int aEpollFd, int aOp, int aFd, struct epoll_event *aEvent);
|
||||
int __real_close(int aFd);
|
||||
|
||||
}
|
||||
|
||||
#define REAL(s) __real_##s
|
||||
@ -139,6 +144,8 @@ TLSInfoList;
|
||||
#define NUWA_STACK_SIZE (1024 * 32)
|
||||
#endif
|
||||
|
||||
#define NATIVE_THREAD_NAME_LENGTH 16
|
||||
|
||||
struct thread_info : public mozilla::LinkedListElement<thread_info> {
|
||||
pthread_t origThreadID;
|
||||
pthread_t recreatedThreadID;
|
||||
@ -160,6 +167,10 @@ struct thread_info : public mozilla::LinkedListElement<thread_info> {
|
||||
|
||||
pthread_mutex_t *reacquireMutex;
|
||||
void *stk;
|
||||
|
||||
pid_t origNativeThreadID;
|
||||
pid_t recreatedNativeThreadID;
|
||||
char nativeThreadName[NATIVE_THREAD_NAME_LENGTH];
|
||||
};
|
||||
|
||||
typedef struct thread_info thread_info_t;
|
||||
@ -212,6 +223,7 @@ static TLSKeySet sTLSKeys;
|
||||
*/
|
||||
static pthread_mutex_t sThreadFreezeLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static thread_info_t sMainThread;
|
||||
static LinkedList<thread_info_t> sAllThreads;
|
||||
static int sThreadCount = 0;
|
||||
static int sThreadFreezeCount = 0;
|
||||
@ -277,6 +289,32 @@ GetThreadInfo(pthread_t threadID) {
|
||||
return tinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get thread info using the specified native thread ID.
|
||||
*
|
||||
* @return thread_info_t with nativeThreadID == specified threadID
|
||||
*/
|
||||
static thread_info_t*
|
||||
GetThreadInfo(pid_t threadID) {
|
||||
if (sIsNuwaProcess) {
|
||||
REAL(pthread_mutex_lock)(&sThreadCountLock);
|
||||
}
|
||||
thread_info_t *thrinfo = nullptr;
|
||||
for (thread_info_t *tinfo = sAllThreads.getFirst();
|
||||
tinfo;
|
||||
tinfo = tinfo->getNext()) {
|
||||
if (tinfo->origNativeThreadID == threadID) {
|
||||
thrinfo = tinfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sIsNuwaProcess) {
|
||||
pthread_mutex_unlock(&sThreadCountLock);
|
||||
}
|
||||
|
||||
return thrinfo;
|
||||
}
|
||||
|
||||
#if !defined(HAVE_THREAD_TLS_KEYWORD)
|
||||
/**
|
||||
* Get thread info of the current thread.
|
||||
@ -449,6 +487,7 @@ thread_info_new(void) {
|
||||
tinfo->recrFunc = nullptr;
|
||||
tinfo->recrArg = nullptr;
|
||||
tinfo->recreatedThreadID = 0;
|
||||
tinfo->recreatedNativeThreadID = 0;
|
||||
tinfo->reacquireMutex = nullptr;
|
||||
tinfo->stk = malloc(NUWA_STACK_SIZE);
|
||||
pthread_attr_init(&tinfo->threadAttr);
|
||||
@ -497,6 +536,7 @@ _thread_create_startup(void *arg) {
|
||||
|
||||
SET_THREAD_INFO(tinfo);
|
||||
tinfo->origThreadID = REAL(pthread_self)();
|
||||
tinfo->origNativeThreadID = gettid();
|
||||
|
||||
pthread_cleanup_push(thread_info_cleanup, tinfo);
|
||||
|
||||
@ -619,6 +659,7 @@ RestoreTLSInfo(thread_info_t *tinfo) {
|
||||
|
||||
SET_THREAD_INFO(tinfo);
|
||||
tinfo->recreatedThreadID = REAL(pthread_self)();
|
||||
tinfo->recreatedNativeThreadID = gettid();
|
||||
}
|
||||
|
||||
extern "C" MFBT_API int
|
||||
@ -1215,6 +1256,27 @@ __wrap_close(int aFd) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
extern "C" MFBT_API int
|
||||
__wrap_tgkill(pid_t tgid, pid_t tid, int signalno)
|
||||
{
|
||||
if (sIsNuwaProcess) {
|
||||
return tgkill(tgid, tid, signalno);
|
||||
}
|
||||
|
||||
if (tid == sMainThread.origNativeThreadID) {
|
||||
return tgkill(tgid, sMainThread.recreatedNativeThreadID, signalno);
|
||||
}
|
||||
|
||||
thread_info_t *tinfo = (tid == sMainThread.origNativeThreadID ?
|
||||
&sMainThread :
|
||||
GetThreadInfo(tid));
|
||||
if (!tinfo) {
|
||||
return tgkill(tgid, tid, signalno);
|
||||
}
|
||||
|
||||
return tgkill(tgid, tinfo->recreatedNativeThreadID, signalno);
|
||||
}
|
||||
|
||||
static void *
|
||||
thread_recreate_startup(void *arg) {
|
||||
/*
|
||||
@ -1232,6 +1294,7 @@ thread_recreate_startup(void *arg) {
|
||||
*/
|
||||
thread_info_t *tinfo = (thread_info_t *)arg;
|
||||
|
||||
prctl(PR_SET_NAME, (unsigned long)&tinfo->nativeThreadName, 0, 0, 0);
|
||||
RestoreTLSInfo(tinfo);
|
||||
|
||||
if (setjmp(tinfo->retEnv) != 0) {
|
||||
@ -1267,6 +1330,9 @@ RecreateThreads() {
|
||||
sIsNuwaProcess = false;
|
||||
sIsFreezing = false;
|
||||
|
||||
sMainThread.recreatedThreadID = pthread_self();
|
||||
sMainThread.recreatedNativeThreadID = gettid();
|
||||
|
||||
// Run registered constructors.
|
||||
for (std::vector<nuwa_construct_t>::iterator ctr = sConstructors.begin();
|
||||
ctr != sConstructors.end();
|
||||
@ -1556,6 +1622,10 @@ PrepareNuwaProcess() {
|
||||
|
||||
// Make marked threads block in one freeze point.
|
||||
REAL(pthread_mutex_lock)(&sThreadFreezeLock);
|
||||
|
||||
// Populate sMainThread for mapping of tgkill.
|
||||
sMainThread.origThreadID = pthread_self();
|
||||
sMainThread.origNativeThreadID = gettid();
|
||||
}
|
||||
|
||||
// Make current process as a Nuwa process.
|
||||
@ -1607,6 +1677,10 @@ NuwaMarkCurrentThread(void (*recreate)(void *), void *arg) {
|
||||
tinfo->flags |= TINFO_FLAG_NUWA_SUPPORT;
|
||||
tinfo->recrFunc = recreate;
|
||||
tinfo->recrArg = arg;
|
||||
|
||||
// XXX Thread name might be set later than this call. If this is the case, we
|
||||
// might need to delay getting the thread name.
|
||||
prctl(PR_GET_NAME, (unsigned long)&tinfo->nativeThreadName, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,6 +83,10 @@
|
||||
#include <stdio.h>
|
||||
#include <list>
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#include "ipc/Nuwa.h"
|
||||
#endif
|
||||
|
||||
#define SIGNAL_SAVE_PROFILE SIGUSR2
|
||||
|
||||
#if defined(__GLIBC__)
|
||||
@ -229,9 +233,15 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
|
||||
sem_post(&sSignalHandlingDone);
|
||||
}
|
||||
|
||||
// If the Nuwa process is enabled, we need to use the wrapper of tgkill() to
|
||||
// perform the mapping of thread ID.
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
extern "C" MFBT_API int tgkill(pid_t tgid, pid_t tid, int signalno);
|
||||
#else
|
||||
int tgkill(pid_t tgid, pid_t tid, int signalno) {
|
||||
return syscall(SYS_tgkill, tgid, tid, signalno);
|
||||
}
|
||||
#endif
|
||||
|
||||
class PlatformData : public Malloced {
|
||||
public:
|
||||
@ -263,6 +273,18 @@ static void* SignalSender(void* arg) {
|
||||
static void* initialize_atfork = setup_atfork();
|
||||
# endif
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
// If the Nuwa process is enabled, we need to mark and freeze the sampler
|
||||
// thread in the Nuwa process and have this thread recreated in the spawned
|
||||
// child.
|
||||
if(IsNuwaProcess()) {
|
||||
NuwaMarkCurrentThread(nullptr, nullptr);
|
||||
// Freeze the thread here so the spawned child will get the correct tgid
|
||||
// from the getpid() call below.
|
||||
NuwaFreezeCurrentThread();
|
||||
}
|
||||
#endif
|
||||
|
||||
int vm_tgid_ = getpid();
|
||||
|
||||
while (SamplerRegistry::sampler->IsActive()) {
|
||||
|
Loading…
Reference in New Issue
Block a user