Bug 1286802 - Part 3: Add empty set_include_context_heap() implementation to ExceptionHandler and CrashGenerationServer. r?ted
MozReview-Commit-ID: 5GBzvyvNPDa
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5713,8 +5713,16 @@ pref("fuzzing.enabled", false);
// to do that.
pref("layers.advanced.border-layers", 2);
pref("layers.advanced.boxshadow-inset-layers", 2);
pref("layers.advanced.boxshadow-outer-layers", 2);
pref("layers.advanced.caret-layers", 2);
pref("layers.advanced.displaybuttonborder-layers", 2);
pref("layers.advanced.outline-layers", 2);
pref("layers.advanced.solid-color-layers", 2);
+
+// When a crash happens, whether to include heap regions of the crash context
+// in the minidump. Enabled by default on nightly and aurora.
+#ifdef RELEASE_OR_BETA
+pref("toolkit.crashreporter.include_context_heap", false);
+#else
+pref("toolkit.crashreporter.include_context_heap", true);
+#endif
--- a/toolkit/crashreporter/breakpad-client/windows/crash_generation/crash_generation_server.cc
+++ b/toolkit/crashreporter/breakpad-client/windows/crash_generation/crash_generation_server.cc
@@ -121,17 +121,18 @@ CrashGenerationServer::CrashGenerationSe
upload_request_callback_(upload_request_callback),
upload_context_(upload_context),
generate_dumps_(generate_dumps),
pre_fetch_custom_info_(true),
dump_path_(dump_path ? *dump_path : L""),
server_state_(IPC_SERVER_STATE_UNINITIALIZED),
shutting_down_(false),
overlapped_(),
- client_info_(NULL) {
+ client_info_(NULL),
+ include_context_heap_(false) {
InitializeCriticalSection(&sync_);
}
// This should never be called from the OnPipeConnected callback.
// Otherwise the UnregisterWaitEx call below will cause a deadlock.
CrashGenerationServer::~CrashGenerationServer() {
// New scope to release the lock automatically.
{
@@ -891,16 +892,21 @@ void CrashGenerationServer::HandleDumpRe
if (dump_callback_ && execute_callback) {
std::wstring* ptr_dump_path = (dump_path == L"") ? NULL : &dump_path;
dump_callback_(dump_context_, &client_info, ptr_dump_path);
}
SetEvent(client_info.dump_generated_handle());
}
+void CrashGenerationServer::set_include_context_heap(bool enabled) {
+
+ include_context_heap_ = enabled;
+}
+
bool CrashGenerationServer::GenerateDump(const ClientInfo& client,
std::wstring* dump_path) {
assert(client.pid() != 0);
assert(client.process_handle());
// We have to get the address of EXCEPTION_INFORMATION from
// the client process address space.
EXCEPTION_POINTERS* client_ex_info = NULL;
--- a/toolkit/crashreporter/breakpad-client/windows/crash_generation/crash_generation_server.h
+++ b/toolkit/crashreporter/breakpad-client/windows/crash_generation/crash_generation_server.h
@@ -101,16 +101,21 @@ class CrashGenerationServer {
//
// Returns true if initialization is successful; false otherwise.
bool Start();
void pre_fetch_custom_info(bool do_pre_fetch) {
pre_fetch_custom_info_ = do_pre_fetch;
}
+ // Calling set_include_context_heap(true) causes heap regions to be included
+ // in the minidump when a crash happens. The heap regions are from the
+ // register values of the client crashing context.
+ void set_include_context_heap(bool enabled);
+
private:
// Various states the client can be in during the handshake with
// the server.
enum IPCServerState {
// Server starts in this state.
IPC_SERVER_STATE_UNINITIALIZED,
// Server is in error state and it cannot serve any clients.
@@ -284,16 +289,19 @@ class CrashGenerationServer {
OVERLAPPED overlapped_;
// Message object used in IPC with the client.
ProtocolMessage msg_;
// Client Info for the client that's connecting to the server.
ClientInfo* client_info_;
+ // Whether to include heap regions of the crashing context.
+ bool include_context_heap_;
+
// Disable copy ctor and operator=.
CrashGenerationServer(const CrashGenerationServer& crash_server);
CrashGenerationServer& operator=(const CrashGenerationServer& crash_server);
};
} // namespace google_breakpad
#endif // CLIENT_WINDOWS_CRASH_GENERATION_CRASH_GENERATION_SERVER_H__
--- a/toolkit/crashreporter/breakpad-client/windows/handler/exception_handler.cc
+++ b/toolkit/crashreporter/breakpad-client/windows/handler/exception_handler.cc
@@ -274,16 +274,18 @@ void ExceptionHandler::Initialize(
previous_iph_ = _set_invalid_parameter_handler(HandleInvalidParameter);
#endif // _MSC_VER >= 1400
if (handler_types & HANDLER_PURECALL)
previous_pch_ = _set_purecall_handler(HandlePureVirtualCall);
LeaveCriticalSection(&handler_stack_critical_section_);
}
+
+ include_context_heap_ = false;
}
ExceptionHandler::~ExceptionHandler() {
if (dbghelp_module_) {
FreeLibrary(dbghelp_module_);
}
if (rpcrt4_module_) {
@@ -1021,9 +1023,13 @@ void ExceptionHandler::RegisterAppMemory
void ExceptionHandler::UnregisterAppMemory(void* ptr) {
AppMemoryList::iterator iter =
std::find(app_memory_info_.begin(), app_memory_info_.end(), ptr);
if (iter != app_memory_info_.end()) {
app_memory_info_.erase(iter);
}
}
+void ExceptionHandler::set_include_context_heap(bool enabled) {
+ include_context_heap_ = enabled;
+}
+
} // namespace google_breakpad
--- a/toolkit/crashreporter/breakpad-client/windows/handler/exception_handler.h
+++ b/toolkit/crashreporter/breakpad-client/windows/handler/exception_handler.h
@@ -262,16 +262,21 @@ class ExceptionHandler {
// Returns whether out-of-process dump generation is used or not.
bool IsOutOfProcess() const { return crash_generation_client_.get() != NULL; }
// Calling RegisterAppMemory(p, len) causes len bytes starting
// at address p to be copied to the minidump when a crash happens.
void RegisterAppMemory(void* ptr, size_t length);
void UnregisterAppMemory(void* ptr);
+ // Calling set_include_context_heap(true) causes heap regions to be included
+ // in the minidump when a crash happens. The heap regions are from the
+ // register values of the crashing context.
+ void set_include_context_heap(bool enabled);
+
private:
friend class AutoExceptionHandler;
// Initializes the instance with given values.
void Initialize(const wstring& dump_path,
FilterCallback filter,
MinidumpCallback callback,
void* callback_context,
@@ -485,16 +490,18 @@ class ExceptionHandler {
// handler_stack_critical_section_ guards operations on handler_stack_ and
// handler_stack_index_. The critical section is initialized by the
// first instance of the class and destroyed by the last instance of it.
static CRITICAL_SECTION handler_stack_critical_section_;
// The number of instances of this class.
static volatile LONG instance_count_;
+ bool include_context_heap_;
+
// disallow copy ctor and operator=
explicit ExceptionHandler(const ExceptionHandler &);
void operator=(const ExceptionHandler &);
};
} // namespace google_breakpad
#pragma warning(pop)
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -255,16 +255,19 @@ static nsCString* crashEventAPIData = nu
static nsCString* notesField = nullptr;
static bool isGarbageCollecting;
static uint32_t eventloopNestingLevel = 0;
// Avoid a race during application termination.
static Mutex* dumpSafetyLock;
static bool isSafeToDump = false;
+// Whether to include heap regions of the crash context.
+static bool sIncludeContextHeap = false;
+
// OOP crash reporting
static CrashGenerationServer* crashServer; // chrome process has this
static std::terminate_handler oldTerminateHandler = nullptr;
#if (defined(XP_MACOSX) || defined(XP_WIN))
// This field is valid in both chrome and content processes.
static xpstring* childProcessTmpDir = nullptr;
@@ -1803,16 +1806,19 @@ nsresult SetExceptionHandler(nsIFile* aX
#endif // XP_WIN32
if (!gExceptionHandler)
return NS_ERROR_OUT_OF_MEMORY;
#ifdef XP_WIN
gExceptionHandler->set_handle_debug_exceptions(true);
+ // Initially set sIncludeContextHeap to true for debugging startup crashes
+ // even if the controlling pref value is false.
+ SetIncludeContextHeap(true);
#ifdef _WIN64
// Tell JS about the new filter before we disable SetUnhandledExceptionFilter
SetJitExceptionHandler();
#endif
// protect the crash reporter from being unloaded
gBlockUnhandledExceptionFilter = true;
gKernel32Intercept.Init("kernel32.dll");
@@ -2470,16 +2476,27 @@ nsresult UnregisterAppMemory(void* ptr)
#if defined(XP_LINUX) || defined(XP_WIN32)
gExceptionHandler->UnregisterAppMemory(ptr);
return NS_OK;
#else
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}
+void SetIncludeContextHeap(bool aValue)
+{
+ sIncludeContextHeap = aValue;
+
+#ifdef XP_WIN
+ if (gExceptionHandler) {
+ gExceptionHandler->set_include_context_heap(sIncludeContextHeap);
+ }
+#endif
+}
+
bool GetServerURL(nsACString& aServerURL)
{
if (!gExceptionHandler)
return false;
return GetAnnotation(NS_LITERAL_CSTRING("ServerURL"), aServerURL);
}
@@ -3548,16 +3565,20 @@ OOPInit()
nullptr, // default security attributes
nullptr, nullptr, // we don't care about process connect here
OnChildProcessDumpRequested, nullptr,
nullptr, nullptr, // we don't care about process exit here
nullptr, nullptr, // we don't care about upload request here
true, // automatically generate dumps
&dumpPath);
+ if (sIncludeContextHeap) {
+ crashServer->set_include_context_heap(sIncludeContextHeap);
+ }
+
#elif defined(XP_LINUX)
if (!CrashGenerationServer::CreateReportChannel(&serverSocketFd,
&clientSocketFd))
MOZ_CRASH("can't create crash reporter socketpair()");
const std::string dumpPath =
gExceptionHandler->minidump_descriptor().directory();
crashServer = new CrashGenerationServer(
--- a/toolkit/crashreporter/nsExceptionHandler.h
+++ b/toolkit/crashreporter/nsExceptionHandler.h
@@ -88,16 +88,19 @@ nsresult SetRestartArgs(int argc, char**
nsresult SetupExtraData(nsIFile* aAppDataDirectory,
const nsACString& aBuildID);
bool GetLastRunCrashID(nsAString& id);
// Registers an additional memory region to be included in the minidump
nsresult RegisterAppMemory(void* ptr, size_t length);
nsresult UnregisterAppMemory(void* ptr);
+// Include heap regions of the crash context.
+void SetIncludeContextHeap(bool aValue);
+
// Functions for working with minidumps and .extras
typedef nsDataHashtable<nsCStringHashKey, nsCString> AnnotationTable;
void DeleteMinidumpFilesForID(const nsAString& id);
bool GetMinidumpForID(const nsAString& id, nsIFile** minidump);
bool GetIDFromMinidump(nsIFile* minidump, nsAString& id);
bool GetExtraFileForID(const nsAString& id, nsIFile** extraFile);
bool GetExtraFileForMinidump(nsIFile* minidump, nsIFile** extraFile);
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -4257,16 +4257,20 @@ XREMain::XRE_mainRun()
}
}
// Needs to be set after xpcom initialization.
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonBase"),
nsPrintfCString("%.16" PRIu64, uint64_t(gMozillaPoisonBase)));
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonSize"),
nsPrintfCString("%" PRIu32, uint32_t(gMozillaPoisonSize)));
+ bool includeContextHeap =
+ Preferences::GetBool("toolkit.crashreporter.include_context_heap", false);
+ CrashReporter::SetIncludeContextHeap(includeContextHeap);
+
#ifdef XP_WIN
PR_CreateThread(PR_USER_THREAD, AnnotateSystemManufacturer_ThreadStart, 0,
PR_PRIORITY_LOW, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
#endif
#if defined(XP_LINUX) && !defined(ANDROID)
PR_CreateThread(PR_USER_THREAD, AnnotateLSBRelease, 0, PR_PRIORITY_LOW,
PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);