Bug 578773 - Jetpack processes should send messages about uncaught exceptions to the parent, r=bent

This commit is contained in:
Benjamin Smedberg 2010-07-23 17:11:33 -04:00
Родитель dc487751c4
Коммит 56a11e40a6
4 изменённых файлов: 62 добавлений и 15 удалений

Просмотреть файл

@ -85,20 +85,6 @@ JetpackChild::sGlobalClass = {
JSCLASS_NO_OPTIONAL_MEMBERS
};
static void
ReportJetpackErrors(JSContext* cx, const char* message, JSErrorReport* report)
{
const char* filename = "<unknown>";
if (report && report->filename)
filename = report->filename;
int lineno = -1;
if (report)
lineno = report->lineno;
fprintf(stderr, "Jetpack JavaScript Error: %s:%i, %s\n",
filename, lineno, message);
}
bool
JetpackChild::Init(base::ProcessHandle aParentProcessHandle,
MessageLoop* aIOLoop,
@ -111,7 +97,12 @@ JetpackChild::Init(base::ProcessHandle aParentProcessHandle,
!(mCx = JS_NewContext(mRuntime, 8192)))
return false;
JS_SetErrorReporter(mCx, ReportJetpackErrors);
JS_SetVersion(mCx, JSVERSION_LATEST);
JS_SetOptions(mCx, JS_GetOptions(mCx) |
JSOPTION_DONT_REPORT_UNCAUGHT |
JSOPTION_ATLINE |
JSOPTION_JIT);
JS_SetErrorReporter(mCx, ReportError);
{
JSAutoRequest request(mCx);
@ -445,5 +436,45 @@ JetpackChild::EvalInSandbox(JSContext* cx, uintN argc, jsval* vp)
ignored.addr());
}
bool JetpackChild::sReportingError;
/* static */ void
JetpackChild::ReportError(JSContext* cx, const char* message,
JSErrorReport* report)
{
if (sReportingError) {
NS_WARNING("Recursive error reported.");
return;
}
sReportingError = true;
js::AutoObjectRooter obj(cx, JS_NewObject(cx, NULL, NULL, NULL));
if (report && report->filename) {
jsval filename = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, report->filename));
JS_SetProperty(cx, obj.object(), "fileName", &filename);
}
if (report) {
jsval lineno = INT_TO_JSVAL(report->lineno);
JS_SetProperty(cx, obj.object(), "lineNumber", &lineno);
}
jsval msgstr = JSVAL_NULL;
if (report && report->ucmessage)
msgstr = STRING_TO_JSVAL(JS_NewUCStringCopyZ(cx, report->ucmessage));
else
msgstr = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, message));
JS_SetProperty(cx, obj.object(), "message", &msgstr);
MessageResult smr;
Variant* vp = smr.data.AppendElement();
JetpackActorCommon::jsval_to_Variant(cx, OBJECT_TO_JSVAL(obj.object()), vp);
GetThis(cx)->SendSendMessage(NS_LITERAL_STRING("core:exception"), smr.data);
sReportingError = false;
}
} // namespace jetpack
} // namespace mozilla

Просмотреть файл

@ -91,7 +91,11 @@ private:
static JSBool CreateSandbox(JSContext* cx, uintN argc, jsval *vp);
static JSBool EvalInSandbox(JSContext* cx, uintN argc, jsval *vp);
static void ReportError(JSContext* cx, const char* message,
JSErrorReport* report);
static const JSClass sGlobalClass;
static bool sReportingError;
DISALLOW_EVIL_CONSTRUCTORS(JetpackChild);
};

Просмотреть файл

@ -81,3 +81,7 @@ registerReceiver("test sandbox", function() {
sendMessage("sandbox done");
});
registerReceiver("throw", function(msgName) {
throw new Error("throwing on request");
});

Просмотреть файл

@ -192,6 +192,13 @@ function run_test() {
});
jetpack.registerReceiver("sandbox done", do_test_finished);
jetpack.registerReceiver("core:exception",
function(msgName, e) {
do_check_true(/throwing on request/.test(e.message));
do_test_finished();
});
do_test_pending();
do_test_pending();
do_test_pending();
do_test_pending();
@ -218,6 +225,7 @@ function run_test() {
jetpack.sendMessage("duplicate receivers");
jetpack.sendMessage("test sandbox");
jetpack.sendMessage("throw");
do_register_cleanup(function() {
jetpack.destroy();