gecko-dev/mozglue/misc/MmapFaultHandler.h
Doug Thayer c5939cab4c Bug 1595596 - Use MMAP_FAULT_HANDLER in StartupCache r=aklotz
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
2020-04-10 21:16:15 +00:00

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