void MemoryProtectionExceptionHandler::uninstall() { if (sExceptionHandlerInstalled) { MOZ_ASSERT(!sHandlingException); // Restore the previous exception handler. MOZ_ALWAYS_FALSE(sigaction(SIGSEGV, &sPrevSEGVHandler, nullptr)); sExceptionHandlerInstalled = false; } }
already_AddRefed<IDBTransaction> IDBDatabase::Transaction(const StringOrStringSequence& aStoreNames, IDBTransactionMode aMode, ErrorResult& aRv) { AssertIsOnOwningThread(); aRv.MightThrowJSException(); if (aMode == IDBTransactionMode::Readwriteflush && !IndexedDatabaseManager::ExperimentalFeaturesEnabled()) { // Pretend that this mode doesn't exist. We don't have a way to annotate // certain enum values as depending on preferences so we just duplicate the // normal exception generation here. ThreadsafeAutoJSContext cx; // Disable any automatic error reporting that might be set up so that we // can grab the exception object. AutoForceSetExceptionOnContext forceExn(cx); MOZ_ALWAYS_FALSE( ThrowErrorMessage(cx, MSG_INVALID_ENUM_VALUE, "Argument 2 of IDBDatabase.transaction", "readwriteflush", "IDBTransactionMode")); MOZ_ASSERT(JS_IsExceptionPending(cx)); JS::Rooted<JS::Value> exception(cx); MOZ_ALWAYS_TRUE(JS_GetPendingException(cx, &exception)); aRv.ThrowJSException(cx, exception); return nullptr; } RefPtr<IDBTransaction> transaction; aRv = Transaction(aStoreNames, aMode, getter_AddRefs(transaction)); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } return transaction.forget(); }
static void UnixExceptionHandler(int signum, siginfo_t* info, void* context) { // Make absolutely sure we can only get here once. if (sHandlingException.compareExchange(false, true)) { // Restore the previous handler. We're going to forward to it // anyway, and if we crash while doing so we don't want to hang. MOZ_ALWAYS_FALSE(sigaction(SIGSEGV, &sPrevSEGVHandler, nullptr)); MOZ_ASSERT(signum == SIGSEGV && info->si_signo == SIGSEGV); if (info->si_code == SEGV_ACCERR) { // Get the address that the offending code tried to access. uintptr_t address = uintptr_t(info->si_addr); // If the faulting address is in one of our protected regions, we // want to annotate the crash to make it stand out from the crowd. if (sProtectedRegions.isProtected(address)) { ReportCrashIfDebug("Hit MOZ_CRASH(Tried to access a protected region!)\n"); MOZ_CRASH_ANNOTATE("MOZ_CRASH(Tried to access a protected region!)"); } } } // Forward to the previous handler which may be a debugger, // the crash reporter or something else entirely. if (sPrevSEGVHandler.sa_flags & SA_SIGINFO) sPrevSEGVHandler.sa_sigaction(signum, info, context); else if (sPrevSEGVHandler.sa_handler == SIG_DFL || sPrevSEGVHandler.sa_handler == SIG_IGN) sigaction(SIGSEGV, &sPrevSEGVHandler, nullptr); else sPrevSEGVHandler.sa_handler(signum); // If we reach here, we're returning to let the default signal handler deal // with the exception. This is technically undefined behavior, but // everything seems to do it, and it removes us from the crash stack. }