зеркало из https://github.com/mozilla/gecko-dev.git
Extensions/libraries/plugins might enable FPU/SSE2 exceptions, causing floating-point operations to crash (533035, r=robarnold,bsmedberg).
This commit is contained in:
Родитель
a60cdc09ba
Коммит
ff3f6da8fa
|
@ -67,6 +67,7 @@ CPPSRCS = \
|
|||
nsXREDirProvider.cpp \
|
||||
nsNativeAppSupportBase.cpp \
|
||||
nsAppData.cpp \
|
||||
nsSigHandlers.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_SPLASHSCREEN
|
||||
|
@ -120,10 +121,6 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
|||
CMMSRCS += MacApplicationDelegate.mm
|
||||
endif
|
||||
|
||||
ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
|
||||
CPPSRCS += nsSigHandlers.cpp
|
||||
endif
|
||||
|
||||
SHARED_LIBRARY_LIBS += ../profile/src/$(LIB_PREFIX)profile_s.$(LIB_SUFFIX)
|
||||
|
||||
ifdef MOZ_ENABLE_XREMOTE
|
||||
|
|
|
@ -239,9 +239,7 @@ protected:
|
|||
};
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_BEOS)
|
||||
extern void InstallUnixSignalHandlers(const char *ProgramName);
|
||||
#endif
|
||||
extern void InstallSignalHandlers(const char *ProgramName);
|
||||
|
||||
#define FILE_COMPATIBILITY_INFO NS_LITERAL_CSTRING("compatibility.ini")
|
||||
|
||||
|
@ -2678,9 +2676,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_BEOS)
|
||||
InstallUnixSignalHandlers(argv[0]);
|
||||
#endif
|
||||
InstallSignalHandlers(argv[0]);
|
||||
|
||||
#ifdef MOZ_ACCESSIBILITY_ATK
|
||||
// Reset GTK_MODULES, strip atk-bridge if exists
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
* platforms that do not support it.
|
||||
*/
|
||||
|
||||
#include "nsSigHandlers.h"
|
||||
|
||||
#ifdef XP_UNIX
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -55,6 +59,7 @@
|
|||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h> // atoi
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
|
||||
#if defined(SOLARIS)
|
||||
|
@ -204,7 +209,53 @@ my_glib_log_func(const gchar *log_domain, GLogLevelFlags log_level,
|
|||
|
||||
#endif
|
||||
|
||||
void InstallUnixSignalHandlers(const char *ProgramName)
|
||||
static void fpehandler(int signum, siginfo_t *si, void *context)
|
||||
{
|
||||
#ifdef XP_MACOSX
|
||||
ucontext_t *uc = (ucontext_t *)context;
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
_STRUCT_FP_CONTROL *ctrl = &uc->uc_mcontext->__fs.__fpu_fcw;
|
||||
ctrl->__invalid = ctrl->__denorm = ctrl->__zdiv = ctrl->__ovrfl = ctrl->__undfl = ctrl->__precis = 1;
|
||||
|
||||
_STRUCT_FP_STATUS *status = &uc->uc_mcontext->__fs.__fpu_fsw;
|
||||
status->__invalid = status->__denorm = status->__zdiv = status->__ovrfl = status->__undfl =
|
||||
status->__precis = status->__stkflt = status->__errsumm = 0;
|
||||
|
||||
__uint32_t *mxcsr = &uc->uc_mcontext->__fs.__fpu_mxcsr;
|
||||
*mxcsr |= SSE_EXCEPTION_MASK; /* disable all SSE exceptions */
|
||||
*mxcsr &= ~SSE_STATUS_FLAGS; /* clear all pending SSE exceptions */
|
||||
#endif
|
||||
#endif
|
||||
#ifdef LINUX
|
||||
ucontext_t *uc = (ucontext_t *)context;
|
||||
|
||||
#if defined(__i386__)
|
||||
/*
|
||||
* It seems that we have no access to mxcsr on Linux. libc
|
||||
* seems to be translating cw/sw to mxcsr.
|
||||
*/
|
||||
unsigned long int *cw = &uc->uc_mcontext.fpregs->cw;
|
||||
*cw |= FPU_EXCEPTION_MASK;
|
||||
|
||||
unsigned long int *sw = &uc->uc_mcontext.fpregs->sw;
|
||||
*sw &= ~FPU_STATUS_FLAGS;
|
||||
#endif
|
||||
#if defined(__amd64__)
|
||||
uint16_t *cw = &uc->uc_mcontext.fpregs->cwd;
|
||||
*cwd |= FPU_EXCEPTION_MASK;
|
||||
|
||||
uint16_t *sw = &uc->uc_mcontext.fpregs->swd;
|
||||
*swd &= ~FPU_STATUS_FLAGS;
|
||||
|
||||
__uint32_t *mxcsr = &uc->uc_mcontext->fpregs->mxcsr;
|
||||
*mxcsr |= SSE_EXCEPTION_MASK; /* disable all SSE exceptions */
|
||||
*mxcsr &= ~SSE_STATUS_FLAGS; /* clear all pending SSE exceptions */
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void InstallSignalHandlers(const char *ProgramName)
|
||||
{
|
||||
PL_strncpy(_progname,ProgramName, (sizeof(_progname)-1) );
|
||||
|
||||
|
@ -226,15 +277,19 @@ void InstallUnixSignalHandlers(const char *ProgramName)
|
|||
signal(SIGSEGV, abnormal_exit_handler);
|
||||
signal(SIGILL, abnormal_exit_handler);
|
||||
signal(SIGABRT, abnormal_exit_handler);
|
||||
signal(SIGFPE, abnormal_exit_handler);
|
||||
|
||||
#elif defined(CRAWL_STACK_ON_SIGSEGV)
|
||||
signal(SIGSEGV, ah_crap_handler);
|
||||
signal(SIGILL, ah_crap_handler);
|
||||
signal(SIGABRT, ah_crap_handler);
|
||||
signal(SIGFPE, ah_crap_handler);
|
||||
#endif // CRAWL_STACK_ON_SIGSEGV
|
||||
|
||||
/* Install a handler for floating point exceptions and disable them if they occur. */
|
||||
struct sigaction sa, osa;
|
||||
sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
|
||||
sa.sa_sigaction = fpehandler;
|
||||
sigaction(SIGFPE, &sa, &osa);
|
||||
|
||||
#if defined(DEBUG) && defined(LINUX)
|
||||
const char *memLimit = PR_GetEnv("MOZ_MEM_LIMIT");
|
||||
if (memLimit && *memLimit)
|
||||
|
@ -289,3 +344,78 @@ void InstallUnixSignalHandlers(const char *ProgramName)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif XP_WIN
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef _M_IX86
|
||||
/*
|
||||
* WinNT.h prior to SDK7 does not expose the structure of the ExtendedRegisters for ia86.
|
||||
* We known that MxCsr is at offset 0x18 and is a DWORD.
|
||||
*/
|
||||
#define MXCSR(ctx) (*(DWORD *)(((BYTE *)(ctx)->ExtendedRegisters) + 0x18))
|
||||
#endif
|
||||
|
||||
#ifdef _M_X64
|
||||
#define MXCSR(ctx) (ctx)->MxCsr
|
||||
#endif
|
||||
|
||||
#if defined(_M_IA32) || define(_M_X64)
|
||||
|
||||
#define X87CW(ctx) (ctx)->FloatSave.ControlWord
|
||||
#define X87SW(ctx) (ctx)->FloatSave.StatusWord
|
||||
|
||||
/*
|
||||
* SSE traps raise these exception codes, which are defined in internal NT headers
|
||||
* but not winbase.h
|
||||
*/
|
||||
#define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4
|
||||
#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5
|
||||
|
||||
LONG __stdcall FpeHandler(PEXCEPTION_POINTERS pe)
|
||||
{
|
||||
PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord;
|
||||
CONTEXT *c = (CONTEXT*)pe->ContextRecord;
|
||||
|
||||
switch (e->ExceptionCode) {
|
||||
case STATUS_FLOAT_DENORMAL_OPERAND:
|
||||
case STATUS_FLOAT_DIVIDE_BY_ZERO:
|
||||
case STATUS_FLOAT_INEXACT_RESULT:
|
||||
case STATUS_FLOAT_INVALID_OPERATION:
|
||||
case STATUS_FLOAT_OVERFLOW:
|
||||
case STATUS_FLOAT_STACK_CHECK:
|
||||
case STATUS_FLOAT_UNDERFLOW:
|
||||
case STATUS_FLOAT_MULTIPLE_FAULTS:
|
||||
case STATUS_FLOAT_MULTIPLE_TRAPS:
|
||||
X87CW(c) |= FPU_EXCEPTION_MASK; /* disable all FPU exceptions */
|
||||
X86SW(c) &= ~FPU_STATUS_FLAGS; /* clear all pending FPU exceptions */
|
||||
#ifdef _M_IA32
|
||||
if (c->ContextFlags & CONTEXT_EXTENDED_REGISTERS) {
|
||||
#endif
|
||||
MXCSR(c) |= SSE_EXCEPTION_MASK; /* disable all SSE exceptions */
|
||||
MXCSR(c) &= ~SSE_STATUS_FLAGS; /* clear all pending SSE exceptions */
|
||||
#ifdef _M_IA32
|
||||
}
|
||||
#endif
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void InstallSignalHandlers(const char *ProgramName)
|
||||
{
|
||||
SetUnhandledExceptionFilter(FpeHandler);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void InstallSignalHandlers(const char *ProgramName)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error No signal handling implementation for this platform.
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corp
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Andreas Gal <gal@uci.edu>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#if defined(_M_IA32) || defined(_M_X86) || defined(__i386__) || defined(__amd64__)
|
||||
|
||||
/*
|
||||
* x87 FPU Control Word:
|
||||
*
|
||||
* 0 -> IM Invalid Operation
|
||||
* 1 -> DM Denormalized Operand
|
||||
* 2 -> ZM Zero Divide
|
||||
* 3 -> OM Overflow
|
||||
* 4 -> UM Underflow
|
||||
* 5 -> PM Precision
|
||||
*/
|
||||
#define FPU_EXCEPTION_MASK 0x3f
|
||||
|
||||
/*
|
||||
* x86 FPU Status Word:
|
||||
*
|
||||
* 0..5 -> Exception flags (see x86 FPU Control Word)
|
||||
* 6 -> SF Stack Fault
|
||||
* 7 -> ES Error Summary Status
|
||||
*/
|
||||
#define FPU_STATUS_FLAGS 0xff
|
||||
|
||||
/*
|
||||
* MXCSR Control and Status Register:
|
||||
*
|
||||
* 0..5 -> Exception flags (see x86 FPU Control Word)
|
||||
* 6 -> DAZ Denormals Are Zero
|
||||
* 7..12 -> Exception mask (see x86 FPU Control Word)
|
||||
*/
|
||||
#define SSE_STATUS_FLAGS FPU_EXCEPTION_MASK
|
||||
#define SSE_EXCEPTION_MASK (FPU_EXCEPTION_MASK << 7)
|
||||
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче