Bug 912337 - Make a pref to toggle whether DebuggeeWouldRun is a warning or an error. (r=jimb)

This commit is contained in:
Shu-yu Guo 2016-02-19 13:46:07 -08:00
parent 77aec05078
commit c80afef075
4 changed files with 55 additions and 20 deletions

View File

@ -1113,6 +1113,8 @@ class JS_PUBLIC_API(RuntimeOptions) {
nativeRegExp_(true),
unboxedArrays_(false),
asyncStack_(true),
throwOnDebuggeeWouldRun_(true),
dumpStackOnDebuggeeWouldRun_(false),
werror_(false),
strictMode_(false),
extraWarnings_(false),
@ -1182,6 +1184,18 @@ class JS_PUBLIC_API(RuntimeOptions) {
return *this;
}
bool throwOnDebuggeeWouldRun() const { return throwOnDebuggeeWouldRun_; }
RuntimeOptions& setThrowOnDebuggeeWouldRun(bool flag) {
throwOnDebuggeeWouldRun_ = flag;
return *this;
}
bool dumpStackOnDebuggeeWouldRun() const { return dumpStackOnDebuggeeWouldRun_; }
RuntimeOptions& setDumpStackOnDebuggeeWouldRun(bool flag) {
dumpStackOnDebuggeeWouldRun_ = flag;
return *this;
}
bool werror() const { return werror_; }
RuntimeOptions& setWerror(bool flag) {
werror_ = flag;
@ -1226,6 +1240,8 @@ class JS_PUBLIC_API(RuntimeOptions) {
bool nativeRegExp_ : 1;
bool unboxedArrays_ : 1;
bool asyncStack_ : 1;
bool throwOnDebuggeeWouldRun_ : 1;
bool dumpStackOnDebuggeeWouldRun_ : 1;
bool werror_ : 1;
bool strictMode_ : 1;
bool extraWarnings_ : 1;

View File

@ -285,10 +285,15 @@ class MOZ_RAII js::EnterDebuggeeNoExecute
// Non-nullptr when unlocked temporarily by a LeaveDebuggeeNoExecute.
LeaveDebuggeeNoExecute* unlocked_;
// When DebuggeeWouldRun is a warning instead of an error, whether we've
// reported a warning already.
bool reported_;
public:
explicit EnterDebuggeeNoExecute(JSContext* cx, Debugger& dbg)
: dbg_(dbg),
unlocked_(nullptr)
unlocked_(nullptr),
reported_(false)
{
stack_ = &cx->runtime()->noExecuteDebuggerTop;
prev_ = *stack_;
@ -307,16 +312,12 @@ class MOZ_RAII js::EnterDebuggeeNoExecute
#ifdef DEBUG
static bool isUniqueLockedInStack(JSContext* cx, Debugger& dbg) {
JSRuntime* rt = cx->runtime();
// This invariant does not hold when DebuggeeWouldRun is only a
// warning.
if (!rt->options().throwOnDebuggeeWouldRun())
return true;
EnterDebuggeeNoExecute* found = nullptr;
for (EnterDebuggeeNoExecute* it = rt->noExecuteDebuggerTop; it; it = it->prev_) {
if (&it->debugger() == &dbg && !it->unlocked_) {
MOZ_ASSERT(!found);
// This invariant does not hold when DebuggeeWouldRun is only a
// warning.
MOZ_ASSERT_IF(rt->options().throwOnDebuggeeWouldRun(), !found);
found = it;
}
}
@ -337,11 +338,24 @@ class MOZ_RAII js::EnterDebuggeeNoExecute
return nullptr;
}
// As above, except for returning the Debugger instance.
static Debugger* findDebuggerInStack(JSContext* cx) {
if (EnterDebuggeeNoExecute* nx = findInStack(cx))
return &nx->debugger();
return nullptr;
// Given a JSContext entered into a debuggee compartment, reports a
// warning or an error if there is a lock that locks it.
static bool reportIfFoundInStack(JSContext* cx) {
if (EnterDebuggeeNoExecute* nx = findInStack(cx)) {
bool warning = !cx->runtime()->options().throwOnDebuggeeWouldRun();
if (!warning || !nx->reported_) {
AutoCompartment ac(cx, nx->debugger().toJSObject());
nx->reported_ = true;
if (cx->runtime()->options().dumpStackOnDebuggeeWouldRun()) {
fprintf(stdout, "Dumping stack for DebuggeeWouldRun:\n");
DumpBacktrace(cx);
}
unsigned flags = warning ? JSREPORT_WARNING : JSREPORT_ERROR;
return JS_ReportErrorFlagsAndNumber(cx, flags, GetErrorMessage, nullptr,
JSMSG_DEBUGGEE_WOULD_RUN);
}
}
return true;
}
};
@ -378,13 +392,7 @@ Debugger::slowPathCheckNoExecute(JSContext* cx)
{
MOZ_ASSERT(cx->compartment()->isDebuggee());
MOZ_ASSERT(cx->runtime()->noExecuteDebuggerTop);
if (Debugger* dbg = EnterDebuggeeNoExecute::findDebuggerInStack(cx)) {
AutoCompartment ac(cx, dbg->toJSObject());
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEBUGGEE_WOULD_RUN);
return false;
}
return true;
return EnterDebuggeeNoExecute::reportIfFoundInStack(cx);
}

View File

@ -1578,6 +1578,12 @@ ReloadPrefsCallback(const char* pref, void* data)
bool useAsyncStack = Preferences::GetBool(JS_OPTIONS_DOT_STR "asyncstack");
bool throwOnDebuggeeWouldRun = Preferences::GetBool(JS_OPTIONS_DOT_STR
"throw_on_debuggee_would_run");
bool dumpStackOnDebuggeeWouldRun = Preferences::GetBool(JS_OPTIONS_DOT_STR
"dump_stack_on_debuggee_would_run");
bool werror = Preferences::GetBool(JS_OPTIONS_DOT_STR "werror");
bool extraWarnings = Preferences::GetBool(JS_OPTIONS_DOT_STR "strict");
@ -1594,6 +1600,8 @@ ReloadPrefsCallback(const char* pref, void* data)
.setThrowOnAsmJSValidationFailure(throwOnAsmJSValidationFailure)
.setNativeRegExp(useNativeRegExp)
.setAsyncStack(useAsyncStack)
.setThrowOnDebuggeeWouldRun(throwOnDebuggeeWouldRun)
.setDumpStackOnDebuggeeWouldRun(dumpStackOnDebuggeeWouldRun)
.setWerror(werror)
.setExtraWarnings(extraWarnings);

View File

@ -1203,6 +1203,9 @@ pref("javascript.options.shared_memory", true);
pref("javascript.options.shared_memory", false);
#endif
pref("javascript.options.throw_on_debuggee_would_run", false);
pref("javascript.options.dump_stack_on_debuggee_would_run", false);
// advanced prefs
pref("advanced.mailftp", false);
pref("image.animation_mode", "normal");