https://bugs.webkit.org/show_bug.cgi?id=193246
Patch by Joseph Pecoraro <pecoraro@apple.com> on 2019-01-08
Reviewed by Mark Lam.
Source/JavaScriptCore:
* runtime/VM.cpp:
(JSC::VM::throwException):
Improve assertion to allow for the debugger's evaluate on call frame condition.
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::callFrameAtDebuggerEntry const):
(JSC::JSGlobalObject::setCallFrameAtDebuggerEntry):
Debugger call frame only used by assertions.
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::evaluateWithScopeExtension):
* debugger/DebuggerEvalEnabler.h:
(JSC::DebuggerEvalEnabler::DebuggerEvalEnabler):
(JSC::DebuggerEvalEnabler::~DebuggerEvalEnabler):
When evaluating on a call frame, set a debug GlobalObject state.
LayoutTests:
* inspector/debugger/evaluateOnCallFrame-CommandLineAPI.html:
Correct a typo.
* inspector/debugger/evaluateOnCallFrame-exception-expected.txt: Added.
* inspector/debugger/evaluateOnCallFrame-exception.html: Added.
New test that would have asserted before.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239753
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2019-01-08 Joseph Pecoraro <pecoraro@apple.com>
+
+ ASSERT when paused in debugger and console evaluation causes exception
+ https://bugs.webkit.org/show_bug.cgi?id=193246
+
+ Reviewed by Mark Lam.
+
+ * inspector/debugger/evaluateOnCallFrame-CommandLineAPI.html:
+ Correct a typo.
+
+ * inspector/debugger/evaluateOnCallFrame-exception-expected.txt: Added.
+ * inspector/debugger/evaluateOnCallFrame-exception.html: Added.
+ New test that would have asserted before.
+
2019-01-08 Jiewen Tan <jiewen_tan@apple.com>
[WebAuthN] Support U2F HID Authenticators on macOS
suite.addTestCase({
name: "ValidateCallFrames",
- description: "Test6 evaluate can access CommandLineAPI methods.",
+ description: "Test evaluate can access CommandLineAPI methods.",
test(resolve, reject) {
let targetData = WI.debuggerManager.dataForTarget(WI.debuggerManager.activeCallFrame.target);
InspectorTest.expectThat(WI.debuggerManager.activeCallFrame.functionName === "bar", "Strict call frame is `bar`.");
--- /dev/null
+Tests exceptions with Debugger.evaluateOnCallFrame.
+
+
+== Running test suite: Debugger.evaluateOnCallFrame.Exception
+-- Running test case: Debugger.evaluateOnCallFrame.Exception
+PASS: Should be a runtime error.
+
+-- Running test case: Complete
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
+<script>
+function triggerPause() {
+ debugger;
+}
+
+function test()
+{
+ const objectGroup = "test";
+ const includeCommandLineAPI = true;
+ const returnByValue = true;
+
+ InspectorTest.debug();
+ let suite = InspectorTest.createAsyncSuite("Debugger.evaluateOnCallFrame.Exception");
+
+ suite.addTestCase({
+ name: "Debugger.evaluateOnCallFrame.Exception",
+ description: "Test exception from evaluateOnCallFrame.",
+ test(resolve, reject) {
+ let callFrame = WI.debuggerManager.activeCallFrame;
+ let targetData = WI.debuggerManager.dataForTarget(callFrame.target);
+ let callFrameId = callFrame.id;
+ let expression = "{}.x";
+ DebuggerAgent.evaluateOnCallFrame.invoke({callFrameId, expression, objectGroup, includeCommandLineAPI, returnByValue}, (error, resultValue, wasThrown) => {
+ InspectorTest.assert(!error, "Should not be a protocol error.");
+ InspectorTest.expectTrue(wasThrown, "Should be a runtime error.");
+ resolve();
+ });
+ }
+ });
+
+ suite.addTestCase({
+ name: "Complete",
+ test(resolve, reject) {
+ WI.debuggerManager.resume();
+ resolve();
+ }
+ })
+
+ InspectorTest.evaluateInPage("triggerPause()");
+ WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Paused, (event) => {
+ suite.runTestCasesAndFinish();
+ });
+}
+</script>
+</head>
+<body onload="runTest()">
+<p>Tests exceptions with Debugger.evaluateOnCallFrame.</p>
+</body>
+</html>
+2019-01-08 Joseph Pecoraro <pecoraro@apple.com>
+
+ ASSERT when paused in debugger and console evaluation causes exception
+ https://bugs.webkit.org/show_bug.cgi?id=193246
+
+ Reviewed by Mark Lam.
+
+ * runtime/VM.cpp:
+ (JSC::VM::throwException):
+ Improve assertion to allow for the debugger's evaluate on call frame condition.
+
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::callFrameAtDebuggerEntry const):
+ (JSC::JSGlobalObject::setCallFrameAtDebuggerEntry):
+ Debugger call frame only used by assertions.
+
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::evaluateWithScopeExtension):
+ * debugger/DebuggerEvalEnabler.h:
+ (JSC::DebuggerEvalEnabler::DebuggerEvalEnabler):
+ (JSC::DebuggerEvalEnabler::~DebuggerEvalEnabler):
+ When evaluating on a call frame, set a debug GlobalObject state.
+
2019-01-08 Keith Miller <keith_miller@apple.com>
Move JSValueMakeSymbol to private header
if (!codeBlock)
return jsUndefined();
- DebuggerEvalEnabler evalEnabler(callFrame);
+ DebuggerEvalEnabler evalEnabler(callFrame, DebuggerEvalEnabler::Mode::EvalOnCallFrameAtDebuggerEntry);
EvalContextType evalContextType;
class DebuggerEvalEnabler {
public:
- explicit DebuggerEvalEnabler(const ExecState* exec)
+ enum class Mode {
+ EvalOnCurrentCallFrame,
+ EvalOnCallFrameAtDebuggerEntry,
+ };
+
+ DebuggerEvalEnabler(const ExecState* exec, Mode mode = Mode::EvalOnCurrentCallFrame)
: m_exec(exec)
- , m_evalWasDisabled(false)
+#if !ASSERT_DISABLED
+ , m_mode(mode)
+#endif
+
{
+ UNUSED_PARAM(mode);
if (exec) {
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
m_evalWasDisabled = !globalObject->evalEnabled();
if (m_evalWasDisabled)
globalObject->setEvalEnabled(true, globalObject->evalDisabledErrorMessage());
+#if !ASSERT_DISABLED
+ if (m_mode == Mode::EvalOnCallFrameAtDebuggerEntry)
+ globalObject->setCallFrameAtDebuggerEntry(exec);
+#endif
}
}
~DebuggerEvalEnabler()
{
- if (m_evalWasDisabled) {
+ if (m_exec) {
JSGlobalObject* globalObject = m_exec->lexicalGlobalObject();
- globalObject->setEvalEnabled(false, globalObject->evalDisabledErrorMessage());
+ if (m_evalWasDisabled)
+ globalObject->setEvalEnabled(false, globalObject->evalDisabledErrorMessage());
+#if !ASSERT_DISABLED
+ if (m_mode == Mode::EvalOnCallFrameAtDebuggerEntry)
+ globalObject->setCallFrameAtDebuggerEntry(nullptr);
+#endif
}
}
private:
const ExecState* m_exec;
- bool m_evalWasDisabled;
+ bool m_evalWasDisabled { false };
+#if !ASSERT_DISABLED
+ DebuggerEvalEnabler::Mode m_mode;
+#endif
};
} // namespace JSC
RuntimeFlags m_runtimeFlags;
ConsoleClient* m_consoleClient { nullptr };
+#if !ASSERT_DISABLED
+ const ExecState* m_callFrameAtDebuggerEntry { nullptr };
+#endif
+
static JS_EXPORT_PRIVATE const GlobalObjectMethodTable s_globalObjectMethodTable;
const GlobalObjectMethodTable* m_globalObjectMethodTable;
m_webAssemblyDisabledErrorMessage = errorMessage;
}
+#if !ASSERT_DISABLED
+ const ExecState* callFrameAtDebuggerEntry() const { return m_callFrameAtDebuggerEntry; }
+ void setCallFrameAtDebuggerEntry(const ExecState* callFrame) { m_callFrameAtDebuggerEntry = callFrame; }
+#endif
+
void resetPrototype(VM&, JSValue prototype);
VM& vm() const { return m_vm; }
void VM::throwException(ExecState* exec, Exception* exception)
{
- ASSERT(exec == topCallFrame || exec->isGlobalExec());
+ ASSERT(exec == topCallFrame || exec->isGlobalExec() || exec == exec->lexicalGlobalObject()->callFrameAtDebuggerEntry());
CallFrame* throwOriginFrame = exec->isGlobalExec() ? exec : topJSCallFrame();
if (Options::breakOnThrow()) {