mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-13 07:24:47 +00:00
c5939cab4c
Please double check that I am using this correctly. I believe we are seeing the crash in the linked bug because we are not handling hardware faults when reading from the memory mapped file. This patch just wraps all accesses in the MMAP_FAULT_HANDLER_ macros. Depends on D53042 Differential Revision: https://phabricator.services.mozilla.com/D53043 --HG-- rename : modules/libjar/MmapFaultHandler.cpp => mozglue/misc/MmapFaultHandler.cpp rename : modules/libjar/MmapFaultHandler.h => mozglue/misc/MmapFaultHandler.h extra : moz-landing-system : lando
105 lines
3.8 KiB
C++
105 lines
3.8 KiB
C++
/* -*- Mode: C++; tab-width: 2; 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/. */
|
|
|
|
#ifndef MmapFaultHandler_h_
|
|
#define MmapFaultHandler_h_
|
|
|
|
#if defined(XP_WIN)
|
|
// Windows
|
|
|
|
# ifdef HAVE_SEH_EXCEPTIONS
|
|
# define MMAP_FAULT_HANDLER_BEGIN_HANDLE(fd) __try {
|
|
# define MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, bufLen) __try {
|
|
# define MMAP_FAULT_HANDLER_CATCH(retval) \
|
|
} \
|
|
__except (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR \
|
|
? EXCEPTION_EXECUTE_HANDLER \
|
|
: EXCEPTION_CONTINUE_SEARCH) { \
|
|
NS_WARNING("unexpected EXCEPTION_IN_PAGE_ERROR"); \
|
|
return retval; \
|
|
}
|
|
# else
|
|
# define MMAP_FAULT_HANDLER_BEGIN_HANDLE(fd) {
|
|
# define MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, bufLen) {
|
|
# define MMAP_FAULT_HANDLER_CATCH(retval) }
|
|
# endif
|
|
|
|
#elif defined(XP_DARWIN)
|
|
// MacOS
|
|
|
|
# define MMAP_FAULT_HANDLER_BEGIN_HANDLE(fd) {
|
|
# define MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, bufLen) {
|
|
# define MMAP_FAULT_HANDLER_CATCH(retval) }
|
|
|
|
#else
|
|
// Linux
|
|
|
|
# include "mozilla/GuardObjects.h"
|
|
# include <stdint.h>
|
|
# include <setjmp.h>
|
|
|
|
class MOZ_RAII MmapAccessScope {
|
|
public:
|
|
MFBT_API MmapAccessScope(void* aBuf, uint32_t aBufLen,
|
|
const char* aFilename = nullptr);
|
|
MFBT_API ~MmapAccessScope();
|
|
|
|
MmapAccessScope(const MmapAccessScope&) = delete;
|
|
MmapAccessScope& operator=(const MmapAccessScope&) = delete;
|
|
|
|
void SetThreadLocalScope();
|
|
bool IsInsideBuffer(void* aPtr);
|
|
void CrashWithInfo(void* aPtr);
|
|
|
|
// sigsetjmp cannot be called from a method that returns before calling
|
|
// siglongjmp, so the macro must call sigsetjmp directly and mJmpBuf must be
|
|
// public.
|
|
sigjmp_buf mJmpBuf;
|
|
|
|
private:
|
|
void* mBuf;
|
|
const char* mFilename;
|
|
uint32_t mBufLen;
|
|
MmapAccessScope* mPreviousScope;
|
|
};
|
|
|
|
// Gets around warnings for null-checking in a macro.
|
|
template <typename T>
|
|
inline bool ValidFD(T fd) {
|
|
return !!fd;
|
|
}
|
|
|
|
# define MMAP_FAULT_HANDLER_BEGIN_HANDLE(fd) \
|
|
{ \
|
|
void* mmapScopeBuf = nullptr; \
|
|
nsCString mmapScopeFilename; \
|
|
uint32_t mmapScopeBufLen = 0; \
|
|
if (ValidFD(fd) && fd->mMap) { \
|
|
mmapScopeBuf = (void*)fd->mFileStart; \
|
|
mmapScopeBufLen = fd->mTotalLen; \
|
|
} \
|
|
if (ValidFD(fd) && fd->mFile) { \
|
|
nsCOMPtr<nsIFile> file = fd->mFile.GetBaseFile(); \
|
|
file->GetNativeLeafName(mmapScopeFilename); \
|
|
} \
|
|
MmapAccessScope mmapScope(mmapScopeBuf, mmapScopeBufLen, \
|
|
mmapScopeFilename.get()); \
|
|
if (sigsetjmp(mmapScope.mJmpBuf, 0) == 0) {
|
|
# define MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, bufLen) \
|
|
{ \
|
|
MmapAccessScope mmapScope((void*)(buf), (bufLen)); \
|
|
if (sigsetjmp(mmapScope.mJmpBuf, 0) == 0) {
|
|
# define MMAP_FAULT_HANDLER_CATCH(retval) \
|
|
} \
|
|
else { \
|
|
NS_WARNING("SIGBUS received when accessing mmapped file"); \
|
|
return retval; \
|
|
} \
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|