Bug 1440816: Part 2 - Clone stacks when sending console messages to the parent process. r?baku
MozReview-Commit-ID: FqK2eZ3JoB2
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -447,16 +447,47 @@ ConsoleListener::Observe(nsIConsoleMessa
NS_ENSURE_SUCCESS(rv, rv);
rv = scriptError->GetLineNumber(&lineNum);
NS_ENSURE_SUCCESS(rv, rv);
rv = scriptError->GetColumnNumber(&colNum);
NS_ENSURE_SUCCESS(rv, rv);
rv = scriptError->GetFlags(&flags);
NS_ENSURE_SUCCESS(rv, rv);
+ {
+ AutoJSAPI jsapi;
+ jsapi.Init();
+ JSContext* cx = jsapi.cx();
+
+ JS::RootedValue stack(cx);
+ rv = scriptError->GetStack(&stack);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (stack.isObject()) {
+ JSAutoCompartment ac(cx, &stack.toObject());
+
+ StructuredCloneData data;
+ ErrorResult err;
+ data.Write(cx, stack, err);
+ if (err.Failed()) {
+ return err.StealNSResult();
+ }
+
+ ClonedMessageData cloned;
+ if (!data.BuildClonedMessageDataForChild(mChild, cloned)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ mChild->SendScriptErrorWithStack(msg, sourceName, sourceLine,
+ lineNum, colNum, flags, category,
+ cloned);
+ }
+ }
+
+
mChild->SendScriptError(msg, sourceName, sourceLine,
lineNum, colNum, flags, category);
return NS_OK;
}
nsString msg;
nsresult rv = aMessage->GetMessageMoz(getter_Copies(msg));
NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -154,16 +154,17 @@
#include "nsIWindowWatcher.h"
#include "nsPIWindowWatcher.h"
#include "nsThread.h"
#include "nsWindowWatcher.h"
#include "nsIXULRuntime.h"
#include "mozilla/dom/nsMixedContentBlocker.h"
#include "nsMemoryInfoDumper.h"
#include "nsMemoryReporterManager.h"
+#include "nsScriptError.h"
#include "nsServiceManagerUtils.h"
#include "nsStyleSheetService.h"
#include "nsThreadUtils.h"
#include "nsToolkitCompsCID.h"
#include "nsWidgetsCID.h"
#include "PreallocatedProcessManager.h"
#include "ProcessPriorityManager.h"
#include "SandboxHal.h"
@@ -3888,24 +3889,79 @@ mozilla::ipc::IPCResult
ContentParent::RecvScriptError(const nsString& aMessage,
const nsString& aSourceName,
const nsString& aSourceLine,
const uint32_t& aLineNumber,
const uint32_t& aColNumber,
const uint32_t& aFlags,
const nsCString& aCategory)
{
+ return RecvScriptErrorInternal(aMessage, aSourceName, aSourceLine,
+ aLineNumber, aColNumber, aFlags,
+ aCategory);
+}
+
+mozilla::ipc::IPCResult
+ContentParent::RecvScriptErrorWithStack(const nsString& aMessage,
+ const nsString& aSourceName,
+ const nsString& aSourceLine,
+ const uint32_t& aLineNumber,
+ const uint32_t& aColNumber,
+ const uint32_t& aFlags,
+ const nsCString& aCategory,
+ const ClonedMessageData& aFrame)
+{
+ return RecvScriptErrorInternal(aMessage, aSourceName, aSourceLine,
+ aLineNumber, aColNumber, aFlags,
+ aCategory, &aFrame);
+}
+
+mozilla::ipc::IPCResult
+ContentParent::RecvScriptErrorInternal(const nsString& aMessage,
+ const nsString& aSourceName,
+ const nsString& aSourceLine,
+ const uint32_t& aLineNumber,
+ const uint32_t& aColNumber,
+ const uint32_t& aFlags,
+ const nsCString& aCategory,
+ const ClonedMessageData* aStack)
+{
RefPtr<nsConsoleService> consoleService = GetConsoleService();
if (!consoleService) {
return IPC_OK();
}
- nsCOMPtr<nsIScriptError> msg(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
- nsresult rv = msg->Init(aMessage, aSourceName, aSourceLine,
- aLineNumber, aColNumber, aFlags, aCategory.get());
+ nsCOMPtr<nsIScriptError> msg;
+
+ if (aStack) {
+ StructuredCloneData data;
+ UnpackClonedMessageDataForParent(*aStack, data);
+
+ AutoJSAPI jsapi;
+ if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
+ MOZ_CRASH();
+ }
+ JSContext* cx = jsapi.cx();
+
+ JS::RootedValue stack(cx);
+ ErrorResult rv;
+ data.Read(cx, &stack, rv);
+ if (rv.Failed() || !stack.isObject()) {
+ return IPC_OK();
+ }
+
+ JS::RootedObject stackObj(cx, &stack.toObject());
+ msg = new nsScriptErrorWithStack(stackObj);
+ } else {
+ msg = new nsScriptError();
+ }
+
+ nsresult rv = msg->InitWithWindowID(aMessage, aSourceName, aSourceLine,
+ aLineNumber, aColNumber, aFlags,
+ aCategory, 0);
if (NS_FAILED(rv))
return IPC_OK();
consoleService->LogMessageWithMode(msg, nsConsoleService::SuppressLog);
return IPC_OK();
}
mozilla::ipc::IPCResult
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -1053,16 +1053,34 @@ private:
virtual mozilla::ipc::IPCResult RecvScriptError(const nsString& aMessage,
const nsString& aSourceName,
const nsString& aSourceLine,
const uint32_t& aLineNumber,
const uint32_t& aColNumber,
const uint32_t& aFlags,
const nsCString& aCategory) override;
+ virtual mozilla::ipc::IPCResult RecvScriptErrorWithStack(const nsString& aMessage,
+ const nsString& aSourceName,
+ const nsString& aSourceLine,
+ const uint32_t& aLineNumber,
+ const uint32_t& aColNumber,
+ const uint32_t& aFlags,
+ const nsCString& aCategory,
+ const ClonedMessageData& aStack) override;
+
+ mozilla::ipc::IPCResult RecvScriptErrorInternal(const nsString& aMessage,
+ const nsString& aSourceName,
+ const nsString& aSourceLine,
+ const uint32_t& aLineNumber,
+ const uint32_t& aColNumber,
+ const uint32_t& aFlags,
+ const nsCString& aCategory,
+ const ClonedMessageData* aStack = nullptr);
+
virtual mozilla::ipc::IPCResult RecvPrivateDocShellsExist(const bool& aExist) override;
virtual mozilla::ipc::IPCResult RecvFirstIdle() override;
virtual mozilla::ipc::IPCResult RecvDeviceReset() override;
virtual mozilla::ipc::IPCResult RecvKeywordToURI(const nsCString& aKeyword,
nsString* aProviderName,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -824,16 +824,19 @@ parent:
async AddGeolocationListener(Principal principal, bool highAccuracy);
async RemoveGeolocationListener();
async SetGeolocationHigherAccuracy(bool enable);
async ConsoleMessage(nsString message);
async ScriptError(nsString message, nsString sourceName, nsString sourceLine,
uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
nsCString category);
+ async ScriptErrorWithStack(nsString message, nsString sourceName, nsString sourceLine,
+ uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
+ nsCString category, ClonedMessageData stack);
// Places the items within dataTransfer on the clipboard.
async SetClipboard(IPCDataTransfer aDataTransfer,
bool aIsPrivateData,
Principal aRequestingPrincipal,
int32_t aWhichClipboard);
// Given a list of supported types, returns the clipboard data for the
--- a/dom/ipc/moz.build
+++ b/dom/ipc/moz.build
@@ -119,16 +119,17 @@ if CONFIG['MOZ_CONTENT_SANDBOX'] and CON
'mozsandbox',
]
LOCAL_INCLUDES += [
'/caps',
'/chrome',
'/docshell/base',
'/dom/base',
+ '/dom/bindings',
'/dom/events',
'/dom/filesystem',
'/dom/geolocation',
'/dom/media/webspeech/synth/ipc',
'/dom/security',
'/extensions/cookie',
'/extensions/spellcheck/src',
'/gfx/2d',