mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound.
This commit is contained in:
commit
1b61fbb7ca
@ -3,7 +3,7 @@
|
||||
# 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/.
|
||||
|
||||
llvm_revision = "159409"
|
||||
llvm_revision = "160105"
|
||||
moz_version = "moz0"
|
||||
|
||||
##############################################
|
||||
|
@ -191,7 +191,7 @@ endif
|
||||
|
||||
profiledbuild::
|
||||
$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_GENERATE=1 MOZ_PGO_INSTRUMENTED=1
|
||||
$(MAKE) -C $(PGO_OBJDIR) stage-package MOZ_PGO_INSTRUMENTED=1
|
||||
$(MAKE) -C $(PGO_OBJDIR) package MOZ_PGO_INSTRUMENTED=1 MOZ_INTERNAL_SIGNING_FORMAT= MOZ_EXTERNAL_SIGNING_FORMAT=
|
||||
MOZ_PGO_INSTRUMENTED=1 OBJDIR=${PGO_OBJDIR} JARLOG_DIR=${PGO_OBJDIR}/jarlog/en-US $(PROFILE_GEN_SCRIPT)
|
||||
$(MAKE) -f $(TOPSRCDIR)/client.mk maybe_clobber_profiledbuild
|
||||
$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_USE=1
|
||||
|
@ -98,6 +98,15 @@ CrashReporterParent::GenerateHangCrashReport(const AnnotationTable* processNotes
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CrashReporterParent::GenerateCrashReportForMinidump(nsIFile* minidump,
|
||||
const AnnotationTable* processNotes)
|
||||
{
|
||||
if (!CrashReporter::GetIDFromMinidump(minidump, mChildDumpID))
|
||||
return false;
|
||||
return GenerateChildData(processNotes);
|
||||
}
|
||||
|
||||
bool
|
||||
CrashReporterParent::GenerateChildData(const AnnotationTable* processNotes)
|
||||
{
|
||||
|
@ -49,6 +49,10 @@ public:
|
||||
bool
|
||||
GenerateCrashReport(Toplevel* t, const AnnotationTable* processNotes);
|
||||
|
||||
bool
|
||||
GenerateCrashReportForMinidump(nsIFile* minidump,
|
||||
const AnnotationTable* processNotes);
|
||||
|
||||
/* Instantiate a new crash reporter actor from a given parent that manages
|
||||
the protocol.
|
||||
*/
|
||||
@ -135,7 +139,7 @@ CrashReporterParent::GenerateCrashReport(Toplevel* t,
|
||||
const AnnotationTable* processNotes)
|
||||
{
|
||||
nsCOMPtr<nsIFile> crashDump;
|
||||
if (t->TakeMinidump(getter_AddRefs(crashDump)) &&
|
||||
if (t->TakeMinidump(getter_AddRefs(crashDump), NULL) &&
|
||||
CrashReporter::GetIDFromMinidump(crashDump, mChildDumpID)) {
|
||||
return GenerateChildData(processNotes);
|
||||
}
|
||||
|
@ -27,9 +27,6 @@
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCRT.h"
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "mozilla/dom/CrashReporterParent.h"
|
||||
#endif
|
||||
#include "nsNPAPIPlugin.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
@ -49,6 +46,12 @@ using namespace mozilla;
|
||||
using namespace mozilla::plugins;
|
||||
using namespace mozilla::plugins::parent;
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "mozilla/dom/CrashReporterParent.h"
|
||||
|
||||
using namespace CrashReporter;
|
||||
#endif
|
||||
|
||||
static const char kChildTimeoutPref[] = "dom.ipc.plugins.timeoutSecs";
|
||||
static const char kParentTimeoutPref[] = "dom.ipc.plugins.parentTimeoutSecs";
|
||||
static const char kLaunchTimeoutPref[] = "dom.ipc.plugins.processLaunchTimeoutSecs";
|
||||
@ -133,9 +136,9 @@ PluginModuleParent::~PluginModuleParent()
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
if (mFlashProcess1)
|
||||
CrashReporter::UnregisterInjectorCallback(mFlashProcess1);
|
||||
UnregisterInjectorCallback(mFlashProcess1);
|
||||
if (mFlashProcess2)
|
||||
CrashReporter::UnregisterInjectorCallback(mFlashProcess2);
|
||||
UnregisterInjectorCallback(mFlashProcess2);
|
||||
#endif
|
||||
|
||||
Preferences::UnregisterCallback(TimeoutChanged, kChildTimeoutPref, this);
|
||||
@ -144,7 +147,7 @@ PluginModuleParent::~PluginModuleParent()
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
void
|
||||
PluginModuleParent::WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes)
|
||||
PluginModuleParent::WriteExtraDataForMinidump(AnnotationTable& notes)
|
||||
{
|
||||
typedef nsDependentCString CS;
|
||||
|
||||
@ -200,19 +203,17 @@ bool
|
||||
PluginModuleParent::ShouldContinueFromReplyTimeout()
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
if (mPluginDumpID.IsEmpty()) {
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
if (crashReporter->GeneratePairedMinidump(this)) {
|
||||
mBrowserDumpID = crashReporter->ParentDumpID();
|
||||
mPluginDumpID = crashReporter->ChildDumpID();
|
||||
PLUGIN_LOG_DEBUG(
|
||||
("generated paired browser/plugin minidumps: %s/%s (ID=%s)",
|
||||
NS_ConvertUTF16toUTF8(mBrowserDumpID).get(),
|
||||
NS_ConvertUTF16toUTF8(mPluginDumpID).get(),
|
||||
NS_ConvertUTF16toUTF8(crashReporter->HangID()).get()));
|
||||
} else {
|
||||
NS_WARNING("failed to capture paired minidumps from hang");
|
||||
}
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
if (crashReporter->GeneratePairedMinidump(this)) {
|
||||
mBrowserDumpID = crashReporter->ParentDumpID();
|
||||
mPluginDumpID = crashReporter->ChildDumpID();
|
||||
PLUGIN_LOG_DEBUG(
|
||||
("generated paired browser/plugin minidumps: %s/%s (ID=%s)",
|
||||
NS_ConvertUTF16toUTF8(mBrowserDumpID).get(),
|
||||
NS_ConvertUTF16toUTF8(mPluginDumpID).get(),
|
||||
NS_ConvertUTF16toUTF8(crashReporter->HangID()).get()));
|
||||
} else {
|
||||
NS_WARNING("failed to capture paired minidumps from hang");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -237,33 +238,99 @@ PluginModuleParent::CrashReporter()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
static void
|
||||
RemoveMinidump(nsIFile* minidump)
|
||||
{
|
||||
if (!minidump)
|
||||
return;
|
||||
|
||||
minidump->Remove(false);
|
||||
nsCOMPtr<nsIFile> extraFile;
|
||||
if (GetExtraFileForMinidump(minidump,
|
||||
getter_AddRefs(extraFile))) {
|
||||
extraFile->Remove(true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleParent::ProcessFirstMinidump()
|
||||
{
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
if (!crashReporter)
|
||||
return;
|
||||
|
||||
AnnotationTable notes;
|
||||
notes.Init(4);
|
||||
WriteExtraDataForMinidump(notes);
|
||||
|
||||
if (!mPluginDumpID.IsEmpty() && !mBrowserDumpID.IsEmpty()) {
|
||||
crashReporter->GenerateHangCrashReport(¬es);
|
||||
return;
|
||||
}
|
||||
|
||||
PRUint32 sequence = PR_UINT32_MAX;
|
||||
nsCOMPtr<nsIFile> dumpFile;
|
||||
nsCAutoString flashProcessType;
|
||||
TakeMinidump(getter_AddRefs(dumpFile), &sequence);
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
nsCOMPtr<nsIFile> childDumpFile;
|
||||
PRUint32 childSequence;
|
||||
|
||||
if (mFlashProcess1 &&
|
||||
TakeMinidumpForChild(mFlashProcess1,
|
||||
getter_AddRefs(childDumpFile),
|
||||
&childSequence)) {
|
||||
if (childSequence < sequence) {
|
||||
RemoveMinidump(dumpFile);
|
||||
dumpFile = childDumpFile;
|
||||
sequence = childSequence;
|
||||
flashProcessType.AssignLiteral("Broker");
|
||||
}
|
||||
else {
|
||||
RemoveMinidump(childDumpFile);
|
||||
}
|
||||
}
|
||||
if (mFlashProcess2 &&
|
||||
TakeMinidumpForChild(mFlashProcess2,
|
||||
getter_AddRefs(childDumpFile),
|
||||
&childSequence)) {
|
||||
if (childSequence < sequence) {
|
||||
RemoveMinidump(dumpFile);
|
||||
dumpFile = childDumpFile;
|
||||
sequence = childSequence;
|
||||
flashProcessType.AssignLiteral("Sandbox");
|
||||
}
|
||||
else {
|
||||
RemoveMinidump(childDumpFile);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!dumpFile) {
|
||||
NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!");
|
||||
return;
|
||||
}
|
||||
|
||||
PLUGIN_LOG_DEBUG(("got child minidump: %s",
|
||||
NS_ConvertUTF16toUTF8(mPluginDumpID).get()));
|
||||
|
||||
GetIDFromMinidump(dumpFile, mPluginDumpID);
|
||||
if (!flashProcessType.IsEmpty()) {
|
||||
notes.Put(NS_LITERAL_CSTRING("FlashProcessDump"), flashProcessType);
|
||||
}
|
||||
crashReporter->GenerateCrashReportForMinidump(dumpFile, ¬es);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
PluginModuleParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
switch (why) {
|
||||
case AbnormalShutdown: {
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
|
||||
CrashReporter::AnnotationTable notes;
|
||||
notes.Init(4);
|
||||
WriteExtraDataForMinidump(notes);
|
||||
|
||||
if (!mPluginDumpID.IsEmpty() && !mBrowserDumpID.IsEmpty()) {
|
||||
crashReporter->GenerateHangCrashReport(¬es);
|
||||
}
|
||||
else if (!mPluginDumpID.IsEmpty()) {
|
||||
// Nothing to do, we've already written this minidump in
|
||||
// PluginModuleParent::OnCrash
|
||||
}
|
||||
else if (crashReporter->GenerateCrashReport(this, ¬es)) {
|
||||
mPluginDumpID = crashReporter->ChildDumpID();
|
||||
PLUGIN_LOG_DEBUG(("got child minidump: %s",
|
||||
NS_ConvertUTF16toUTF8(mPluginDumpID).get()));
|
||||
}
|
||||
else {
|
||||
NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!");
|
||||
}
|
||||
ProcessFirstMinidump();
|
||||
#endif
|
||||
|
||||
mShutdown = true;
|
||||
@ -1248,33 +1315,8 @@ PluginModuleParent::InitializeInjector()
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleParent::OnCrash(DWORD processID, const nsAString& aDumpID)
|
||||
PluginModuleParent::OnCrash(DWORD processID)
|
||||
{
|
||||
if (!mPluginDumpID.IsEmpty()) {
|
||||
// One process has already crashed: we assume that the first-to-crash
|
||||
// is the interesting one
|
||||
return;
|
||||
}
|
||||
|
||||
mPluginDumpID = aDumpID;
|
||||
|
||||
CrashReporter::AnnotationTable notes;
|
||||
notes.Init(4);
|
||||
WriteExtraDataForMinidump(notes);
|
||||
notes.Put(NS_LITERAL_CSTRING("ProcessType"), NS_LITERAL_CSTRING("plugin"));
|
||||
if (processID == mFlashProcess1) {
|
||||
notes.Put(NS_LITERAL_CSTRING("FlashProcessDump"),
|
||||
NS_LITERAL_CSTRING("Broker"));
|
||||
}
|
||||
else if (processID == mFlashProcess2) {
|
||||
notes.Put(NS_LITERAL_CSTRING("FlashProcessDump"),
|
||||
NS_LITERAL_CSTRING("Sandbox"));
|
||||
}
|
||||
else {
|
||||
NS_ERROR("Got minidump for Flash process neither broker nor sandbox.");
|
||||
}
|
||||
CrashReporter::AppendExtraData(aDumpID, notes);
|
||||
|
||||
GetIPCChannel()->CloseWithError();
|
||||
KillProcess(OtherProcess(), 1, false);
|
||||
}
|
||||
|
@ -288,6 +288,7 @@ private:
|
||||
CrashReporterParent* CrashReporter();
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
void ProcessFirstMinidump();
|
||||
void WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes);
|
||||
#endif
|
||||
void CleanupFromTimeout();
|
||||
@ -319,7 +320,7 @@ private:
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
void InitializeInjector();
|
||||
|
||||
NS_OVERRIDE void OnCrash(DWORD processID, const nsAString& aDumpID);
|
||||
NS_OVERRIDE void OnCrash(DWORD processID);
|
||||
|
||||
DWORD mFlashProcess1;
|
||||
DWORD mFlashProcess2;
|
||||
|
@ -253,6 +253,10 @@ void GeckoChildProcessHost::InitWindowsGroupID()
|
||||
bool
|
||||
GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTimeoutMs, base::ProcessArchitecture arch)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
CrashReporter::OOPInit();
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
InitWindowsGroupID();
|
||||
#endif
|
||||
@ -294,6 +298,10 @@ GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTime
|
||||
bool
|
||||
GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
CrashReporter::OOPInit();
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
InitWindowsGroupID();
|
||||
#endif
|
||||
|
@ -330,6 +330,7 @@ Type.INT = Type('int')
|
||||
Type.INT32 = Type('int32')
|
||||
Type.INTPTR = Type('intptr_t')
|
||||
Type.UINT32 = Type('uint32')
|
||||
Type.UINT32PTR = Type('uint32', ptr=1)
|
||||
Type.SIZE = Type('size_t')
|
||||
Type.VOID = Type('void')
|
||||
Type.VOIDPTR = Type('void', ptr=1)
|
||||
|
@ -3089,16 +3089,18 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
])
|
||||
|
||||
dumpvar = ExprVar('aDump')
|
||||
seqvar = ExprVar('aSequence')
|
||||
getdump = MethodDefn(MethodDecl(
|
||||
'TakeMinidump',
|
||||
params=[ Decl(Type('nsIFile', ptrptr=1), dumpvar.name) ],
|
||||
params=[ Decl(Type('nsIFile', ptrptr=1), dumpvar.name),
|
||||
Decl(Type.UINT32PTR, seqvar.name)],
|
||||
ret=Type.BOOL,
|
||||
const=1))
|
||||
getdump.addstmts([
|
||||
CppDirective('ifdef', 'MOZ_CRASHREPORTER'),
|
||||
StmtReturn(ExprCall(
|
||||
ExprVar('XRE_TakeMinidumpForChild'),
|
||||
args=[ ExprCall(otherpidvar), dumpvar ])),
|
||||
args=[ ExprCall(otherpidvar), dumpvar, seqvar ])),
|
||||
CppDirective('else'),
|
||||
StmtReturn.FALSE,
|
||||
CppDirective('endif')
|
||||
|
@ -169,7 +169,7 @@ FENNEC_PP_XML_FILES = \
|
||||
res/menu/gecko_menu.xml \
|
||||
res/menu-v11/gecko_menu.xml \
|
||||
res/menu-v11/titlebar_contextmenu.xml \
|
||||
res/menu-large/gecko_menu.xml \
|
||||
res/menu-large-v11/gecko_menu.xml \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@ -941,7 +941,11 @@ RES_DIRS= \
|
||||
res/color \
|
||||
res/menu \
|
||||
res/menu-v11 \
|
||||
<<<<<<< local
|
||||
res/menu-large \
|
||||
=======
|
||||
res/menu-large-v11 \
|
||||
>>>>>>> other
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "client/windows/handler/exception_handler.h"
|
||||
#include <DbgHelp.h>
|
||||
#include <string.h>
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
|
||||
#include "nsWindowsDllInterceptor.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
@ -40,7 +41,6 @@
|
||||
#include <unistd.h>
|
||||
#include "mac_utils.h"
|
||||
#elif defined(XP_LINUX)
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsIINIParser.h"
|
||||
#include "common/linux/linux_libc_support.h"
|
||||
@ -152,6 +152,7 @@ static const XP_CHAR extraFileExtension[] = {'.', 'e', 'x', 't',
|
||||
|
||||
static google_breakpad::ExceptionHandler* gExceptionHandler = nsnull;
|
||||
|
||||
static XP_CHAR* pendingDirectory;
|
||||
static XP_CHAR* crashReporterPath;
|
||||
|
||||
// if this is false, we don't launch the crash reporter
|
||||
@ -221,13 +222,32 @@ static const int kMagicChildCrashReportFd = 4;
|
||||
|
||||
// |dumpMapLock| must protect all access to |pidToMinidump|.
|
||||
static Mutex* dumpMapLock;
|
||||
typedef nsInterfaceHashtable<nsUint32HashKey, nsIFile> ChildMinidumpMap;
|
||||
struct ChildProcessData : public nsUint32HashKey
|
||||
{
|
||||
ChildProcessData(KeyTypePointer aKey)
|
||||
: nsUint32HashKey(aKey)
|
||||
, sequence(0)
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
, callback(NULL)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
nsCOMPtr<nsIFile> minidump;
|
||||
// Each crashing process is assigned an increasing sequence number to
|
||||
// indicate which process crashed first.
|
||||
PRUint32 sequence;
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
InjectorCrashCallback* callback;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef nsTHashtable<ChildProcessData> ChildMinidumpMap;
|
||||
static ChildMinidumpMap* pidToMinidump;
|
||||
static PRUint32 crashSequence;
|
||||
static bool OOPInitialized();
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
static nsIThread* sInjectorThread;
|
||||
typedef nsDataHashtable<nsUint32HashKey, InjectorCrashCallback*> InjectorPIDMap;
|
||||
static InjectorPIDMap* pidToInjectorCallback;
|
||||
|
||||
class ReportInjectedCrash : public nsRunnable
|
||||
{
|
||||
@ -714,13 +734,13 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
||||
|
||||
#ifdef XP_WIN32
|
||||
nsString crashReporterPath_temp;
|
||||
exePath->GetPath(crashReporterPath_temp);
|
||||
|
||||
exePath->GetPath(crashReporterPath_temp);
|
||||
crashReporterPath = ToNewUnicode(crashReporterPath_temp);
|
||||
#elif !defined(__ANDROID__)
|
||||
nsCString crashReporterPath_temp;
|
||||
exePath->GetNativePath(crashReporterPath_temp);
|
||||
|
||||
exePath->GetNativePath(crashReporterPath_temp);
|
||||
crashReporterPath = ToNewCString(crashReporterPath_temp);
|
||||
#else
|
||||
// On Android, we launch using the application package name
|
||||
@ -1133,6 +1153,11 @@ nsresult UnsetExceptionHandler()
|
||||
delete notesField;
|
||||
notesField = nsnull;
|
||||
|
||||
if (pendingDirectory) {
|
||||
NS_Free(pendingDirectory);
|
||||
pendingDirectory = nsnull;
|
||||
}
|
||||
|
||||
if (crashReporterPath) {
|
||||
NS_Free(crashReporterPath);
|
||||
crashReporterPath = nsnull;
|
||||
@ -1671,23 +1696,23 @@ nsresult SetSubmitReports(bool aSubmitReports)
|
||||
}
|
||||
|
||||
// The "pending" dir is Crash Reports/pending, from which minidumps
|
||||
// can be submitted
|
||||
// can be submitted. Because this method may be called off the main thread,
|
||||
// we store the pending directory as a path.
|
||||
static bool
|
||||
GetPendingDir(nsIFile** dir)
|
||||
{
|
||||
nsCOMPtr<nsIProperties> dirSvc =
|
||||
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
|
||||
if (!dirSvc)
|
||||
MOZ_ASSERT(OOPInitialized());
|
||||
if (!pendingDirectory) {
|
||||
return false;
|
||||
nsCOMPtr<nsIFile> pendingDir;
|
||||
if (NS_FAILED(dirSvc->Get("UAppData",
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(pendingDir))) ||
|
||||
NS_FAILED(pendingDir->Append(NS_LITERAL_STRING("Crash Reports"))) ||
|
||||
NS_FAILED(pendingDir->Append(NS_LITERAL_STRING("pending"))))
|
||||
return false;
|
||||
*dir = NULL;
|
||||
pendingDir.swap(*dir);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> pending = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
|
||||
#ifdef XP_WIN
|
||||
pending->InitWithPath(nsDependentString(pendingDirectory));
|
||||
#else
|
||||
pending->InitWithNativePath(nsDependentCString(pendingDirectory));
|
||||
#endif
|
||||
pending.swap(*dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1952,12 +1977,22 @@ OnChildProcessDumpRequested(void* aContext,
|
||||
aClientInfo->pid();
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
bool runCallback;
|
||||
#endif
|
||||
{
|
||||
MutexAutoLock lock(*dumpMapLock);
|
||||
pidToMinidump->Put(pid, minidump);
|
||||
ChildProcessData* pd = pidToMinidump->PutEntry(pid);
|
||||
MOZ_ASSERT(!pd->minidump);
|
||||
pd->minidump = minidump;
|
||||
pd->sequence = ++crashSequence;
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
runCallback = NULL != pd->callback;
|
||||
#endif
|
||||
}
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
NS_DispatchToMainThread(new ReportInjectedCrash(pid));
|
||||
if (runCallback)
|
||||
NS_DispatchToMainThread(new ReportInjectedCrash(pid));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -1973,11 +2008,14 @@ static bool ChildFilter(void *context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
OOPInit()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!OOPInitialized(),
|
||||
"OOP crash reporter initialized more than once!");
|
||||
if (OOPInitialized())
|
||||
return;
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
NS_ABORT_IF_FALSE(gExceptionHandler != NULL,
|
||||
"attempt to initialize OOP crash reporter before in-process crashreporter!");
|
||||
|
||||
@ -2038,6 +2076,26 @@ OOPInit()
|
||||
pidToMinidump->Init();
|
||||
|
||||
dumpMapLock = new Mutex("CrashReporter::dumpMapLock");
|
||||
|
||||
nsCOMPtr<nsIFile> pendingDir;
|
||||
nsresult rv = NS_GetSpecialDirectory("UAppData", getter_AddRefs(pendingDir));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Couldn't get the user appdata directory, crash dumps will go in an unusual location");
|
||||
}
|
||||
else {
|
||||
pendingDir->Append(NS_LITERAL_STRING("Crash Reports"));
|
||||
pendingDir->Append(NS_LITERAL_STRING("pending"));
|
||||
|
||||
#ifdef XP_WIN
|
||||
nsString path;
|
||||
pendingDir->GetPath(path);
|
||||
pendingDirectory = ToNewUnicode(path);
|
||||
#else
|
||||
nsCString path;
|
||||
pendingDir->GetNativePath(path);
|
||||
pendingDirectory = ToNewCString(path);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2053,9 +2111,6 @@ OOPDeinit()
|
||||
sInjectorThread->Shutdown();
|
||||
NS_RELEASE(sInjectorThread);
|
||||
}
|
||||
|
||||
delete pidToInjectorCallback;
|
||||
pidToInjectorCallback = NULL;
|
||||
#endif
|
||||
|
||||
delete crashServer;
|
||||
@ -2081,8 +2136,7 @@ GetChildNotificationPipe()
|
||||
if (!GetEnabled())
|
||||
return kNullNotifyPipe;
|
||||
|
||||
if (!OOPInitialized())
|
||||
OOPInit();
|
||||
MOZ_ASSERT(OOPInitialized());
|
||||
|
||||
return childCrashNotifyPipe;
|
||||
}
|
||||
@ -2098,17 +2152,17 @@ InjectCrashReporterIntoProcess(DWORD processID, InjectorCrashCallback* cb)
|
||||
if (!OOPInitialized())
|
||||
OOPInit();
|
||||
|
||||
if (!pidToInjectorCallback) {
|
||||
pidToInjectorCallback = new InjectorPIDMap;
|
||||
pidToInjectorCallback->Init();
|
||||
}
|
||||
|
||||
if (!sInjectorThread) {
|
||||
if (NS_FAILED(NS_NewThread(&sInjectorThread)))
|
||||
return;
|
||||
}
|
||||
|
||||
pidToInjectorCallback->Put(processID, cb);
|
||||
{
|
||||
MutexAutoLock lock(*dumpMapLock);
|
||||
ChildProcessData* pd = pidToMinidump->PutEntry(processID);
|
||||
MOZ_ASSERT(!pd->minidump && !pd->callback);
|
||||
pd->callback = cb;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = new InjectCrashRunnable(processID);
|
||||
sInjectorThread->Dispatch(r, nsIEventTarget::DISPATCH_NORMAL);
|
||||
@ -2118,23 +2172,22 @@ NS_IMETHODIMP
|
||||
ReportInjectedCrash::Run()
|
||||
{
|
||||
// Crash reporting may have been disabled after this method was dispatched
|
||||
if (!pidToInjectorCallback)
|
||||
if (!OOPInitialized())
|
||||
return NS_OK;
|
||||
|
||||
InjectorCrashCallback* cb = pidToInjectorCallback->Get(mPID);
|
||||
if (!cb)
|
||||
return NS_OK;
|
||||
InjectorCrashCallback* cb;
|
||||
{
|
||||
MutexAutoLock lock(*dumpMapLock);
|
||||
ChildProcessData* pd = pidToMinidump->GetEntry(mPID);
|
||||
if (!pd || !pd->callback)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIFile> minidump;
|
||||
if (!TakeMinidumpForChild(mPID, getter_AddRefs(minidump))) {
|
||||
NS_WARNING("No minidump for crash notification.");
|
||||
return NS_OK;
|
||||
MOZ_ASSERT(pd->minidump);
|
||||
|
||||
cb = pd->callback;
|
||||
}
|
||||
|
||||
nsString id;
|
||||
GetIDFromMinidump(minidump, id);
|
||||
|
||||
cb->OnCrash(mPID, id);
|
||||
cb->OnCrash(mPID);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2144,7 +2197,8 @@ UnregisterInjectorCallback(DWORD processID)
|
||||
if (!OOPInitialized())
|
||||
return;
|
||||
|
||||
pidToInjectorCallback->Remove(processID);
|
||||
MutexAutoLock lock(*dumpMapLock);
|
||||
pidToMinidump->RemoveEntry(processID);
|
||||
}
|
||||
|
||||
#endif // MOZ_CRASHREPORTER_INJECTOR
|
||||
@ -2190,8 +2244,7 @@ CreateNotificationPipeForChild(int* childCrashFd, int* childCrashRemapFd)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!OOPInitialized())
|
||||
OOPInit();
|
||||
MOZ_ASSERT(OOPInitialized());
|
||||
|
||||
*childCrashFd = clientSocketFd;
|
||||
*childCrashRemapFd = kMagicChildCrashReportFd;
|
||||
@ -2251,22 +2304,25 @@ SetRemoteExceptionHandler(const nsACString& crashPipe)
|
||||
|
||||
|
||||
bool
|
||||
TakeMinidumpForChild(PRUint32 childPid, nsIFile** dump)
|
||||
TakeMinidumpForChild(PRUint32 childPid, nsIFile** dump, PRUint32* aSequence)
|
||||
{
|
||||
if (!GetEnabled())
|
||||
return false;
|
||||
|
||||
MutexAutoLock lock(*dumpMapLock);
|
||||
|
||||
nsCOMPtr<nsIFile> d;
|
||||
bool found = pidToMinidump->Get(childPid, getter_AddRefs(d));
|
||||
if (found)
|
||||
pidToMinidump->Remove(childPid);
|
||||
ChildProcessData* pd = pidToMinidump->GetEntry(childPid);
|
||||
if (!pd)
|
||||
return false;
|
||||
|
||||
*dump = NULL;
|
||||
d.swap(*dump);
|
||||
NS_IF_ADDREF(*dump = pd->minidump);
|
||||
if (aSequence) {
|
||||
*aSequence = pd->sequence;
|
||||
}
|
||||
|
||||
return found;
|
||||
pidToMinidump->RemoveEntry(childPid);
|
||||
|
||||
return !!*dump;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -69,11 +69,17 @@ nsresult SetSubmitReports(bool aSubmitReport);
|
||||
|
||||
// Out-of-process crash reporter API.
|
||||
|
||||
// Return true iff a dump was found for |childPid|, and return the
|
||||
// Initializes out-of-process crash reporting. This method must be called
|
||||
// before the platform-specifi notificationpipe APIs are called.
|
||||
void OOPInit();
|
||||
|
||||
// Return true if a dump was found for |childPid|, and return the
|
||||
// path in |dump|. The caller owns the last reference to |dump| if it
|
||||
// is non-NULL.
|
||||
// is non-NULL. The sequence parameter will be filled with an ordinal
|
||||
// indicating which remote process crashed first.
|
||||
bool TakeMinidumpForChild(PRUint32 childPid,
|
||||
nsIFile** dump NS_OUTPARAM);
|
||||
nsIFile** dump NS_OUTPARAM,
|
||||
PRUint32* aSequence = NULL);
|
||||
|
||||
#if defined(XP_WIN)
|
||||
typedef HANDLE ProcessHandle;
|
||||
@ -120,9 +126,17 @@ class InjectorCrashCallback
|
||||
public:
|
||||
InjectorCrashCallback() { }
|
||||
|
||||
virtual void OnCrash(DWORD processID, const nsAString& aDumpID) = 0;
|
||||
/**
|
||||
* Inform the callback of a crash. The client code should call
|
||||
* TakeMinidumpForChild to remove it from the PID mapping table.
|
||||
*
|
||||
* The callback will not be fired if the client has already called
|
||||
* TakeMinidumpForChild for this process ID.
|
||||
*/
|
||||
virtual void OnCrash(DWORD processID) = 0;
|
||||
};
|
||||
|
||||
// This method implies OOPInit
|
||||
void InjectCrashReporterIntoProcess(DWORD processID, InjectorCrashCallback* cb);
|
||||
void UnregisterInjectorCallback(DWORD processID);
|
||||
#endif
|
||||
|
@ -29,7 +29,7 @@ function run_test()
|
||||
if (is_windows) {
|
||||
['SystemMemoryUsePercentage', 'TotalVirtualMemory', 'AvailableVirtualMemory',
|
||||
'AvailablePageFile', 'AvailablePhysicalMemory'].forEach(function(prop) {
|
||||
do_check_true(extra[prop].toString().match(/^\d+$/));
|
||||
do_check_true(/^\d+$/.test(extra[prop].toString()));
|
||||
});
|
||||
}
|
||||
if (is_win7_or_newer)
|
||||
|
@ -226,9 +226,10 @@ GeckoProcessType sChildProcessType = GeckoProcessType_Default;
|
||||
// IPDL wants access to this crashreporter interface, and
|
||||
// crashreporter is built in such a way to make that awkward
|
||||
bool
|
||||
XRE_TakeMinidumpForChild(PRUint32 aChildPid, nsIFile** aDump)
|
||||
XRE_TakeMinidumpForChild(PRUint32 aChildPid, nsIFile** aDump,
|
||||
PRUint32* aSequence)
|
||||
{
|
||||
return CrashReporter::TakeMinidumpForChild(aChildPid, aDump);
|
||||
return CrashReporter::TakeMinidumpForChild(aChildPid, aDump, aSequence);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -367,7 +367,8 @@ XRE_API(GeckoProcessType,
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
// Used in the "master" parent process hosting the crash server
|
||||
XRE_API(bool,
|
||||
XRE_TakeMinidumpForChild, (PRUint32 aChildPid, nsIFile** aDump))
|
||||
XRE_TakeMinidumpForChild, (PRUint32 aChildPid, nsIFile** aDump,
|
||||
PRUint32* aSequence))
|
||||
|
||||
// Used in child processes.
|
||||
XRE_API(bool,
|
||||
|
Loading…
Reference in New Issue
Block a user