summaryrefslogtreecommitdiff
path: root/xpcom/threads/ThreadStackHelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/threads/ThreadStackHelper.cpp')
-rw-r--r--xpcom/threads/ThreadStackHelper.cpp225
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