diff options
Diffstat (limited to 'xpcom/threads/ThreadStackHelper.cpp')
-rw-r--r-- | xpcom/threads/ThreadStackHelper.cpp | 225 |
1 files changed, 0 insertions, 225 deletions
diff --git a/xpcom/threads/ThreadStackHelper.cpp b/xpcom/threads/ThreadStackHelper.cpp deleted file mode 100644 index 72d82e4daa..0000000000 --- a/xpcom/threads/ThreadStackHelper.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ThreadStackHelper.h" -#include "MainThreadUtils.h" -#include "nsJSPrincipals.h" -#include "nsScriptSecurityManager.h" -#include "jsfriendapi.h" - -#include "mozilla/Assertions.h" -#include "mozilla/Attributes.h" -#include "mozilla/IntegerPrintfMacros.h" -#include "mozilla/Move.h" -#include "mozilla/Scoped.h" -#include "mozilla/UniquePtr.h" -#include "mozilla/MemoryChecking.h" -#include "mozilla/Sprintf.h" - -#ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wshadow" -#endif - -#if defined(MOZ_VALGRIND) -# include <valgrind/valgrind.h> -#endif - -#include <string.h> -#include <vector> -#include <cstdlib> - -#ifdef XP_LINUX -#include <ucontext.h> -#include <unistd.h> -#include <sys/syscall.h> -#endif - -#ifdef __GNUC__ -# pragma GCC diagnostic pop // -Wshadow -#endif - -#if defined(XP_LINUX) -#include <pthread.h> -#endif - -namespace mozilla { - -void -ThreadStackHelper::Startup() -{ -#if defined(XP_LINUX) - MOZ_ASSERT(NS_IsMainThread()); - if (!sInitialized) { - // TODO: centralize signal number allocation - sFillStackSignum = SIGRTMIN + 4; - if (sFillStackSignum > SIGRTMAX) { - // Leave uninitialized - MOZ_ASSERT(false); - return; - } - struct sigaction sigact = {}; - sigact.sa_sigaction = FillStackHandler; - sigemptyset(&sigact.sa_mask); - sigact.sa_flags = SA_SIGINFO | SA_RESTART; - MOZ_ALWAYS_TRUE(!::sigaction(sFillStackSignum, &sigact, nullptr)); - } - sInitialized++; -#endif -} - -void -ThreadStackHelper::Shutdown() -{ -#if defined(XP_LINUX) - MOZ_ASSERT(NS_IsMainThread()); - if (sInitialized == 1) { - struct sigaction sigact = {}; - sigact.sa_handler = SIG_DFL; - MOZ_ALWAYS_TRUE(!::sigaction(sFillStackSignum, &sigact, nullptr)); - } - sInitialized--; -#endif -} - -ThreadStackHelper::ThreadStackHelper() - : mStackToFill(nullptr) -{ -#if defined(XP_LINUX) - MOZ_ALWAYS_TRUE(!::sem_init(&mSem, 0, 0)); - mThreadID = ::syscall(SYS_gettid); -#elif defined(XP_WIN) - mInitialized = !!::DuplicateHandle( - ::GetCurrentProcess(), ::GetCurrentThread(), - ::GetCurrentProcess(), &mThreadID, - THREAD_SUSPEND_RESUME - , FALSE, 0); - MOZ_ASSERT(mInitialized); -#endif -} - -ThreadStackHelper::~ThreadStackHelper() -{ -#if defined(XP_LINUX) - MOZ_ALWAYS_TRUE(!::sem_destroy(&mSem)); -#elif defined(XP_WIN) - if (mInitialized) { - MOZ_ALWAYS_TRUE(!!::CloseHandle(mThreadID)); - } -#endif -} - -namespace { -template<typename T> -class ScopedSetPtr -{ -private: - T*& mPtr; -public: - ScopedSetPtr(T*& p, T* val) : mPtr(p) { mPtr = val; } - ~ScopedSetPtr() { mPtr = nullptr; } -}; -} // namespace - -void -ThreadStackHelper::GetStack(Stack& aStack) -{ - // Always run PrepareStackBuffer first to clear aStack - if (!PrepareStackBuffer(aStack)) { - // Skip and return empty aStack - return; - } - - ScopedSetPtr<Stack> stackPtr(mStackToFill, &aStack); - -#if defined(XP_LINUX) - if (!sInitialized) { - MOZ_ASSERT(false); - return; - } - siginfo_t uinfo = {}; - uinfo.si_signo = sFillStackSignum; - uinfo.si_code = SI_QUEUE; - uinfo.si_pid = getpid(); - uinfo.si_uid = getuid(); - uinfo.si_value.sival_ptr = this; - if (::syscall(SYS_rt_tgsigqueueinfo, uinfo.si_pid, - mThreadID, sFillStackSignum, &uinfo)) { - // rt_tgsigqueueinfo was added in Linux 2.6.31. - // Could have failed because the syscall did not exist. - return; - } - MOZ_ALWAYS_TRUE(!::sem_wait(&mSem)); - -#elif defined(XP_WIN) - if (!mInitialized) { - MOZ_ASSERT(false); - return; - } - if (::SuspendThread(mThreadID) == DWORD(-1)) { - MOZ_ASSERT(false); - return; - } - - // SuspendThread is asynchronous, so the thread may still be running. Use - // GetThreadContext to ensure it's really suspended. - // See https://blogs.msdn.microsoft.com/oldnewthing/20150205-00/?p=44743. - CONTEXT context; - context.ContextFlags = CONTEXT_CONTROL; - if (::GetThreadContext(mThreadID, &context)) { - FillStackBuffer(); - FillThreadContext(); - } - - MOZ_ALWAYS_TRUE(::ResumeThread(mThreadID) != DWORD(-1)); -#endif -} - -void -ThreadStackHelper::GetNativeStack(Stack& aStack) -{ - /*** STUB ***/ -} - -#ifdef XP_LINUX - -int ThreadStackHelper::sInitialized; -int ThreadStackHelper::sFillStackSignum; - -void -ThreadStackHelper::FillStackHandler(int aSignal, siginfo_t* aInfo, - void* aContext) -{ - ThreadStackHelper* const helper = - reinterpret_cast<ThreadStackHelper*>(aInfo->si_value.sival_ptr); - helper->FillStackBuffer(); - helper->FillThreadContext(aContext); - ::sem_post(&helper->mSem); -} - -#endif // XP_LINUX - -bool -ThreadStackHelper::PrepareStackBuffer(Stack& aStack) -{ - // Return false to skip getting the stack and return an empty stack - aStack.clear(); - return false; -} - -void -ThreadStackHelper::FillStackBuffer() -{ - MOZ_ASSERT(mStackToFill->empty()); - /*** STUB ***/ -} - -MOZ_ASAN_BLACKLIST void -ThreadStackHelper::FillThreadContext(void* aContext) -{ - /*** STUB ***/ -} - -} // namespace mozilla |