зеркало из https://github.com/mozilla/gecko-dev.git
Bug 581335 - Hook up crash reporting for content process by attaching a property bag to the global observer-service notification for them. r=mfinkle
--HG-- extra : rebase_source : 880e536710b8c02995a36fa08c49d098fb05f50f
This commit is contained in:
Родитель
eaad6195a8
Коммит
b7b7f07536
|
@ -98,6 +98,12 @@ interface nsIContentFrameMessageManager : nsISyncMessageSender
|
|||
* Print a string to stdout.
|
||||
*/
|
||||
void dump(in DOMString aStr);
|
||||
|
||||
/**
|
||||
* If leak detection is enabled, print a note to the leak log that this
|
||||
* process will intentionally crash.
|
||||
*/
|
||||
void privateNoteIntentionalCrash();
|
||||
};
|
||||
|
||||
[uuid(9c48d557-92fe-4edb-95fc-bfe97e77bdc3)]
|
||||
|
|
|
@ -307,6 +307,12 @@ nsFrameMessageManager::Dump(const nsAString& aStr)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::PrivateNoteIntentionalCrash()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameMessageManager::GetContent(nsIDOMWindow** aContent)
|
||||
{
|
||||
|
|
|
@ -180,6 +180,12 @@ nsInProcessTabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsInProcessTabChildGlobal::PrivateNoteIntentionalCrash()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void
|
||||
nsInProcessTabChildGlobal::Disconnect()
|
||||
{
|
||||
|
|
|
@ -77,6 +77,7 @@ public:
|
|||
{
|
||||
return mMessageManager ? mMessageManager->Dump(aStr) : NS_OK;
|
||||
}
|
||||
NS_IMETHOD PrivateNoteIntentionalCrash();
|
||||
NS_DECL_NSIINPROCESSCONTENTFRAMEMESSAGEMANAGER
|
||||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "History.h"
|
||||
#include "mozilla/ipc/TestShellParent.h"
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "nsHashPropertyBag.h"
|
||||
#include "nsIFilePicker.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
@ -72,6 +73,10 @@
|
|||
#include "nsPermissionManager.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "nsExceptionHandler.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/dom/ExternalHelperAppParent.h"
|
||||
#include "mozilla/dom/StorageParent.h"
|
||||
#include "nsAccelerometer.h"
|
||||
|
@ -123,6 +128,28 @@ ContentParent::GetSingleton(PRBool aForceNew)
|
|||
return gSingleton;
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::OnChannelConnected(int32 pid)
|
||||
{
|
||||
ProcessHandle handle;
|
||||
if (!base::OpenPrivilegedProcessHandle(pid, &handle)) {
|
||||
NS_WARNING("Can't open handle to child process.");
|
||||
}
|
||||
else {
|
||||
SetOtherProcess(handle);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
void
|
||||
DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
|
||||
{
|
||||
XRE_GetIOMessageLoop()
|
||||
->PostTask(FROM_HERE,
|
||||
new DeleteTask<GeckoChildProcessHost>(aSubprocess));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
|
@ -142,11 +169,32 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
|||
mIsAlive = false;
|
||||
|
||||
if (obs) {
|
||||
nsString context = NS_LITERAL_STRING("");
|
||||
if (AbnormalShutdown == why)
|
||||
context.AssignLiteral("abnormal");
|
||||
obs->NotifyObservers(nsnull, "ipc:content-shutdown", context.get());
|
||||
nsRefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
|
||||
props->Init();
|
||||
|
||||
if (AbnormalShutdown == why) {
|
||||
props->SetPropertyAsBool(NS_LITERAL_STRING("abnormal"), PR_TRUE);
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
nsAutoString dumpID;
|
||||
|
||||
nsCOMPtr<nsILocalFile> crashDump;
|
||||
TakeMinidump(getter_AddRefs(crashDump)) &&
|
||||
CrashReporter::GetIDFromMinidump(crashDump, dumpID);
|
||||
|
||||
if (!dumpID.IsEmpty())
|
||||
props->SetPropertyAsAString(NS_LITERAL_STRING("dumpID"),
|
||||
dumpID);
|
||||
#endif
|
||||
|
||||
obs->NotifyObservers((nsIPropertyBag2*) props, "ipc:content-shutdown", nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
MessageLoop::current()->
|
||||
PostTask(FROM_HERE,
|
||||
NewRunnableFunction(DelayedDeleteSubprocess, mSubprocess));
|
||||
mSubprocess = NULL;
|
||||
}
|
||||
|
||||
TabParent*
|
||||
|
@ -187,6 +235,9 @@ ContentParent::ContentParent()
|
|||
|
||||
ContentParent::~ContentParent()
|
||||
{
|
||||
if (OtherProcess())
|
||||
base::CloseProcessHandle(OtherProcess());
|
||||
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
//If the previous content process has died, a new one could have
|
||||
//been started since.
|
||||
|
@ -268,14 +319,6 @@ NS_IMPL_THREADSAFE_ISUPPORTS3(ContentParent,
|
|||
nsIThreadObserver,
|
||||
nsIDOMGeoPositionCallback)
|
||||
|
||||
namespace {
|
||||
void
|
||||
DeleteSubprocess(GeckoChildProcessHost* aSubprocess)
|
||||
{
|
||||
delete aSubprocess;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentParent::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
|
@ -294,10 +337,7 @@ ContentParent::Observe(nsISupports* aSubject,
|
|||
RecvRemoveGeolocationListener();
|
||||
|
||||
Close();
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(DeleteSubprocess, mSubprocess));
|
||||
mSubprocess = nsnull;
|
||||
NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
|
||||
}
|
||||
|
||||
if (!mIsAlive || !mSubprocess)
|
||||
|
|
|
@ -99,6 +99,7 @@ public:
|
|||
bool IsAlive();
|
||||
|
||||
protected:
|
||||
void OnChannelConnected(int32 pid);
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
|
||||
private:
|
||||
|
|
|
@ -47,6 +47,8 @@ LIBXUL_LIBRARY = 1
|
|||
FORCE_STATIC_LIB = 1
|
||||
EXPORT_LIBRARY = 1
|
||||
|
||||
DIRS = tests
|
||||
|
||||
EXPORTS = TabMessageUtils.h PCOMContentPermissionRequestChild.h
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla/dom
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "TabChild.h"
|
||||
#include "mozilla/IntentionalCrash.h"
|
||||
#include "mozilla/dom/PContentChild.h"
|
||||
#include "mozilla/dom/PContentDialogChild.h"
|
||||
#include "mozilla/layers/PLayersChild.h"
|
||||
|
@ -997,6 +998,13 @@ TabChildGlobal::GetContent(nsIDOMWindow** aContent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChildGlobal::PrivateNoteIntentionalCrash()
|
||||
{
|
||||
mozilla::NoteIntentionalCrash("tab");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
|
||||
{
|
||||
|
|
|
@ -108,6 +108,7 @@ public:
|
|||
{
|
||||
return mMessageManager ? mMessageManager->Dump(aStr) : NS_OK;
|
||||
}
|
||||
NS_IMETHOD PrivateNoteIntentionalCrash();
|
||||
|
||||
NS_IMETHOD AddEventListener(const nsAString& aType,
|
||||
nsIDOMEventListener* aListener,
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# ***** 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 Firefox testing code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Founation <http://www.mozilla.org/>.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2010
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# 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 *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = dom/ipc/tests
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
MOCHICHROME_FILES = \
|
||||
test_process_error.xul \
|
||||
process_error.xul \
|
||||
process_error_contentscript.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(MOCHICHROME_FILES)
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
orient="vertical">
|
||||
|
||||
<browser id="thebrowser" type="content" remote="true" />
|
||||
<script type="application/javascript"><![CDATA[
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const ok = window.opener.wrappedJSObject.ok;
|
||||
const is = window.opener.wrappedJSObject.is;
|
||||
const done = window.opener.wrappedJSObject.done;
|
||||
const SimpleTest = window.opener.wrappedJSObject.SimpleTest;
|
||||
|
||||
function crashObserver(subject, topic, data) {
|
||||
is(topic, 'ipc:content-shutdown', 'Received correct observer topic.');
|
||||
ok(subject instanceof Components.interfaces.nsIPropertyBag2,
|
||||
'Subject implements nsIPropertyBag2.');
|
||||
|
||||
if ('nsICrashReporter' in Components.interfaces) {
|
||||
ok(subject.getPropertyAsAString('dumpID'), "dumpID is present");
|
||||
}
|
||||
|
||||
Services.obs.removeObserver(crashObserver, 'ipc:content-shutdown');
|
||||
done();
|
||||
}
|
||||
Services.obs.addObserver(crashObserver, 'ipc:content-shutdown', false);
|
||||
|
||||
document.getElementById('thebrowser').
|
||||
QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.
|
||||
messageManager.loadFrameScript('chrome://mochitests/content/chrome/dom/ipc/tests/process_error_contentscript.js', true);
|
||||
]]></script>
|
||||
|
||||
</window>
|
|
@ -0,0 +1,7 @@
|
|||
Components.utils.import("resource://gre/modules/ctypes.jsm");
|
||||
|
||||
privateNoteIntentionalCrash();
|
||||
|
||||
var zero = new ctypes.intptr_t(8);
|
||||
var badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
|
||||
var crash = badptr.contents;
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var w = window.open('process_error.xul', '_blank', 'chrome,resizable=yes,width=400,height=600');
|
||||
|
||||
function done()
|
||||
{
|
||||
w.close();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;" />
|
||||
</window>
|
Загрузка…
Ссылка в новой задаче