From 4d4097ae4b24bd08ec0bb3be83351a5c8ad0d3f7 Mon Sep 17 00:00:00 2001 From: "oliver@apple.com" Date: Mon, 16 Apr 2012 22:26:36 +0000 Subject: [PATCH] Exception stack traces aren't complete when the exception starts in native code https://bugs.webkit.org/show_bug.cgi?id=84073 Reviewed by Gavin Barraclough. Source/JavaScriptCore: Refactored building the stack trace to so that we can construct it earlier, and don't rely on any prior work performed in the exception handling machinery. Also updated LLInt and the DFG to completely initialise the callframes of host function calls. * bytecode/CodeBlock.h: (JSC::CodeBlock::codeOriginIndexForReturn): (CodeBlock): * dfg/DFGOperations.cpp: * interpreter/Interpreter.cpp: (JSC::Interpreter::getStackTrace): (JSC::Interpreter::addStackTraceIfNecessary): (JSC): (JSC::Interpreter::throwException): * interpreter/Interpreter.h: (Interpreter): * jit/JITStubs.cpp: (JSC::DEFINE_STUB_FUNCTION): * jsc.cpp: (functionJSCStack): * llint/LLIntSlowPaths.cpp: (JSC::LLInt::handleHostCall): * parser/Parser.h: (JSC::::parse): * runtime/Error.cpp: (JSC::addErrorInfo): (JSC::throwError): * runtime/Error.h: (JSC): LayoutTests: Update tests to include new exception property ordering, and new functions * fast/js/exception-properties-expected.txt: * fast/js/script-tests/exception-properties.js: * fast/js/script-tests/stack-trace.js: (selfRecursive1): Modified slightly so that we produce consistent traces * fast/js/stack-trace-expected.txt: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@114309 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- LayoutTests/ChangeLog | 15 + .../fast/js/exception-properties-expected.txt | 2 +- .../fast/js/script-tests/exception-properties.js | 2 +- LayoutTests/fast/js/script-tests/stack-trace.js | 4 +- LayoutTests/fast/js/stack-trace-expected.txt | 418 +++++++++++---------- Source/JavaScriptCore/ChangeLog | 37 ++ .../JavaScriptCore/JavaScriptCore.def | 2 +- Source/JavaScriptCore/bytecode/CodeBlock.h | 8 + Source/JavaScriptCore/dfg/DFGOperations.cpp | 2 + Source/JavaScriptCore/interpreter/Interpreter.cpp | 41 +- Source/JavaScriptCore/interpreter/Interpreter.h | 3 +- Source/JavaScriptCore/jit/JITStubs.cpp | 13 + Source/JavaScriptCore/jsc.cpp | 2 +- Source/JavaScriptCore/llint/LLIntSlowPaths.cpp | 2 + Source/JavaScriptCore/parser/Parser.h | 2 +- Source/JavaScriptCore/runtime/Error.cpp | 27 +- Source/JavaScriptCore/runtime/Error.h | 3 +- 17 files changed, 337 insertions(+), 246 deletions(-) diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index 1e1ff37..2a82d9d 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,18 @@ +2012-04-16 Oliver Hunt + + Exception stack traces aren't complete when the exception starts in native code + https://bugs.webkit.org/show_bug.cgi?id=84073 + + Reviewed by Gavin Barraclough. + + Update tests to include new exception property ordering, and new functions + + * fast/js/exception-properties-expected.txt: + * fast/js/script-tests/exception-properties.js: + * fast/js/script-tests/stack-trace.js: + (selfRecursive1): Modified slightly so that we produce consistent traces + * fast/js/stack-trace-expected.txt: + 2012-04-16 David Alcala Update test_expectations for chromium diff --git a/LayoutTests/fast/js/exception-properties-expected.txt b/LayoutTests/fast/js/exception-properties-expected.txt index 5363e04..5d9943a 100644 --- a/LayoutTests/fast/js/exception-properties-expected.txt +++ b/LayoutTests/fast/js/exception-properties-expected.txt @@ -4,7 +4,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE PASS enumerableProperties(error) is [] -PASS enumerableProperties(nativeError) is ["line", "sourceURL", "stack"] +PASS enumerableProperties(nativeError) is ["stack", "line", "sourceURL"] PASS Object.getPrototypeOf(nativeError).name is "RangeError" PASS Object.getPrototypeOf(nativeError).message is "" PASS successfullyParsed is true diff --git a/LayoutTests/fast/js/script-tests/exception-properties.js b/LayoutTests/fast/js/script-tests/exception-properties.js index 19eb345..43e1153 100644 --- a/LayoutTests/fast/js/script-tests/exception-properties.js +++ b/LayoutTests/fast/js/script-tests/exception-properties.js @@ -16,7 +16,7 @@ try { var error = new Error("message"); shouldBe('enumerableProperties(error)', '[]'); - shouldBe('enumerableProperties(nativeError)', '["line", "sourceURL", "stack"]'); + shouldBe('enumerableProperties(nativeError)', '["stack", "line", "sourceURL"]'); shouldBe('Object.getPrototypeOf(nativeError).name', '"RangeError"'); shouldBe('Object.getPrototypeOf(nativeError).message', '""'); diff --git a/LayoutTests/fast/js/script-tests/stack-trace.js b/LayoutTests/fast/js/script-tests/stack-trace.js index 04736bb..9abf997 100644 --- a/LayoutTests/fast/js/script-tests/stack-trace.js +++ b/LayoutTests/fast/js/script-tests/stack-trace.js @@ -49,10 +49,10 @@ try { hostThrower(); } catch (e) { printStack(e.stack); } // try { scripterInner(); } catch (e) { printStack(e.stack) } // program -> scripter -> inner try { scripterOuter(); } catch (e) { printStack(e.stack) } // program -> scripter -> outer -> inner -function selfRecursive1() { - selfRecursive1(); +function selfRecursive1() { selfRecursive1(); } + try { selfRecursive1(); } catch (e) { printStack(e.stack) } // selfRecursive1 -> selfRecursive1 -> selfRecursive1 -> selfRecursive1 ... function selfRecursive2() { diff --git a/LayoutTests/fast/js/stack-trace-expected.txt b/LayoutTests/fast/js/stack-trace-expected.txt index d562b06..f5bf2e7 100644 --- a/LayoutTests/fast/js/stack-trace-expected.txt +++ b/LayoutTests/fast/js/stack-trace-expected.txt @@ -33,8 +33,9 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE 2 global code at stack-trace.js:44 --> Stack Trace: - 0 hostThrower at stack-trace.js:25 - 1 global code at stack-trace.js:47 + 0 appendChild at [native code] + 1 hostThrower at stack-trace.js:25 + 2 global code at stack-trace.js:47 --> Stack Trace: 0 htmlInner at stack-trace.html:10 @@ -48,109 +49,109 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE 3 global code at stack-trace.js:50 --> Stack Trace: - 0 selfRecursive1 at stack-trace.js:53 - 1 selfRecursive1 at stack-trace.js:53 - 2 selfRecursive1 at stack-trace.js:53 - 3 selfRecursive1 at stack-trace.js:53 - 4 selfRecursive1 at stack-trace.js:53 - 5 selfRecursive1 at stack-trace.js:53 - 6 selfRecursive1 at stack-trace.js:53 - 7 selfRecursive1 at stack-trace.js:53 - 8 selfRecursive1 at stack-trace.js:53 - 9 selfRecursive1 at stack-trace.js:53 - 10 selfRecursive1 at stack-trace.js:53 - 11 selfRecursive1 at stack-trace.js:53 - 12 selfRecursive1 at stack-trace.js:53 - 13 selfRecursive1 at stack-trace.js:53 - 14 selfRecursive1 at stack-trace.js:53 - 15 selfRecursive1 at stack-trace.js:53 - 16 selfRecursive1 at stack-trace.js:53 - 17 selfRecursive1 at stack-trace.js:53 - 18 selfRecursive1 at stack-trace.js:53 - 19 selfRecursive1 at stack-trace.js:53 - 20 selfRecursive1 at stack-trace.js:53 - 21 selfRecursive1 at stack-trace.js:53 - 22 selfRecursive1 at stack-trace.js:53 - 23 selfRecursive1 at stack-trace.js:53 - 24 selfRecursive1 at stack-trace.js:53 - 25 selfRecursive1 at stack-trace.js:53 - 26 selfRecursive1 at stack-trace.js:53 - 27 selfRecursive1 at stack-trace.js:53 - 28 selfRecursive1 at stack-trace.js:53 - 29 selfRecursive1 at stack-trace.js:53 - 30 selfRecursive1 at stack-trace.js:53 - 31 selfRecursive1 at stack-trace.js:53 - 32 selfRecursive1 at stack-trace.js:53 - 33 selfRecursive1 at stack-trace.js:53 - 34 selfRecursive1 at stack-trace.js:53 - 35 selfRecursive1 at stack-trace.js:53 - 36 selfRecursive1 at stack-trace.js:53 - 37 selfRecursive1 at stack-trace.js:53 - 38 selfRecursive1 at stack-trace.js:53 - 39 selfRecursive1 at stack-trace.js:53 - 40 selfRecursive1 at stack-trace.js:53 - 41 selfRecursive1 at stack-trace.js:53 - 42 selfRecursive1 at stack-trace.js:53 - 43 selfRecursive1 at stack-trace.js:53 - 44 selfRecursive1 at stack-trace.js:53 - 45 selfRecursive1 at stack-trace.js:53 - 46 selfRecursive1 at stack-trace.js:53 - 47 selfRecursive1 at stack-trace.js:53 - 48 selfRecursive1 at stack-trace.js:53 - 49 selfRecursive1 at stack-trace.js:53 - 50 selfRecursive1 at stack-trace.js:53 - 51 selfRecursive1 at stack-trace.js:53 - 52 selfRecursive1 at stack-trace.js:53 - 53 selfRecursive1 at stack-trace.js:53 - 54 selfRecursive1 at stack-trace.js:53 - 55 selfRecursive1 at stack-trace.js:53 - 56 selfRecursive1 at stack-trace.js:53 - 57 selfRecursive1 at stack-trace.js:53 - 58 selfRecursive1 at stack-trace.js:53 - 59 selfRecursive1 at stack-trace.js:53 - 60 selfRecursive1 at stack-trace.js:53 - 61 selfRecursive1 at stack-trace.js:53 - 62 selfRecursive1 at stack-trace.js:53 - 63 selfRecursive1 at stack-trace.js:53 - 64 selfRecursive1 at stack-trace.js:53 - 65 selfRecursive1 at stack-trace.js:53 - 66 selfRecursive1 at stack-trace.js:53 - 67 selfRecursive1 at stack-trace.js:53 - 68 selfRecursive1 at stack-trace.js:53 - 69 selfRecursive1 at stack-trace.js:53 - 70 selfRecursive1 at stack-trace.js:53 - 71 selfRecursive1 at stack-trace.js:53 - 72 selfRecursive1 at stack-trace.js:53 - 73 selfRecursive1 at stack-trace.js:53 - 74 selfRecursive1 at stack-trace.js:53 - 75 selfRecursive1 at stack-trace.js:53 - 76 selfRecursive1 at stack-trace.js:53 - 77 selfRecursive1 at stack-trace.js:53 - 78 selfRecursive1 at stack-trace.js:53 - 79 selfRecursive1 at stack-trace.js:53 - 80 selfRecursive1 at stack-trace.js:53 - 81 selfRecursive1 at stack-trace.js:53 - 82 selfRecursive1 at stack-trace.js:53 - 83 selfRecursive1 at stack-trace.js:53 - 84 selfRecursive1 at stack-trace.js:53 - 85 selfRecursive1 at stack-trace.js:53 - 86 selfRecursive1 at stack-trace.js:53 - 87 selfRecursive1 at stack-trace.js:53 - 88 selfRecursive1 at stack-trace.js:53 - 89 selfRecursive1 at stack-trace.js:53 - 90 selfRecursive1 at stack-trace.js:53 - 91 selfRecursive1 at stack-trace.js:53 - 92 selfRecursive1 at stack-trace.js:53 - 93 selfRecursive1 at stack-trace.js:53 - 94 selfRecursive1 at stack-trace.js:53 - 95 selfRecursive1 at stack-trace.js:53 - 96 selfRecursive1 at stack-trace.js:53 - 97 selfRecursive1 at stack-trace.js:53 - 98 selfRecursive1 at stack-trace.js:53 - 99 selfRecursive1 at stack-trace.js:53 + 0 selfRecursive1 at stack-trace.js:52 + 1 selfRecursive1 at stack-trace.js:52 + 2 selfRecursive1 at stack-trace.js:52 + 3 selfRecursive1 at stack-trace.js:52 + 4 selfRecursive1 at stack-trace.js:52 + 5 selfRecursive1 at stack-trace.js:52 + 6 selfRecursive1 at stack-trace.js:52 + 7 selfRecursive1 at stack-trace.js:52 + 8 selfRecursive1 at stack-trace.js:52 + 9 selfRecursive1 at stack-trace.js:52 + 10 selfRecursive1 at stack-trace.js:52 + 11 selfRecursive1 at stack-trace.js:52 + 12 selfRecursive1 at stack-trace.js:52 + 13 selfRecursive1 at stack-trace.js:52 + 14 selfRecursive1 at stack-trace.js:52 + 15 selfRecursive1 at stack-trace.js:52 + 16 selfRecursive1 at stack-trace.js:52 + 17 selfRecursive1 at stack-trace.js:52 + 18 selfRecursive1 at stack-trace.js:52 + 19 selfRecursive1 at stack-trace.js:52 + 20 selfRecursive1 at stack-trace.js:52 + 21 selfRecursive1 at stack-trace.js:52 + 22 selfRecursive1 at stack-trace.js:52 + 23 selfRecursive1 at stack-trace.js:52 + 24 selfRecursive1 at stack-trace.js:52 + 25 selfRecursive1 at stack-trace.js:52 + 26 selfRecursive1 at stack-trace.js:52 + 27 selfRecursive1 at stack-trace.js:52 + 28 selfRecursive1 at stack-trace.js:52 + 29 selfRecursive1 at stack-trace.js:52 + 30 selfRecursive1 at stack-trace.js:52 + 31 selfRecursive1 at stack-trace.js:52 + 32 selfRecursive1 at stack-trace.js:52 + 33 selfRecursive1 at stack-trace.js:52 + 34 selfRecursive1 at stack-trace.js:52 + 35 selfRecursive1 at stack-trace.js:52 + 36 selfRecursive1 at stack-trace.js:52 + 37 selfRecursive1 at stack-trace.js:52 + 38 selfRecursive1 at stack-trace.js:52 + 39 selfRecursive1 at stack-trace.js:52 + 40 selfRecursive1 at stack-trace.js:52 + 41 selfRecursive1 at stack-trace.js:52 + 42 selfRecursive1 at stack-trace.js:52 + 43 selfRecursive1 at stack-trace.js:52 + 44 selfRecursive1 at stack-trace.js:52 + 45 selfRecursive1 at stack-trace.js:52 + 46 selfRecursive1 at stack-trace.js:52 + 47 selfRecursive1 at stack-trace.js:52 + 48 selfRecursive1 at stack-trace.js:52 + 49 selfRecursive1 at stack-trace.js:52 + 50 selfRecursive1 at stack-trace.js:52 + 51 selfRecursive1 at stack-trace.js:52 + 52 selfRecursive1 at stack-trace.js:52 + 53 selfRecursive1 at stack-trace.js:52 + 54 selfRecursive1 at stack-trace.js:52 + 55 selfRecursive1 at stack-trace.js:52 + 56 selfRecursive1 at stack-trace.js:52 + 57 selfRecursive1 at stack-trace.js:52 + 58 selfRecursive1 at stack-trace.js:52 + 59 selfRecursive1 at stack-trace.js:52 + 60 selfRecursive1 at stack-trace.js:52 + 61 selfRecursive1 at stack-trace.js:52 + 62 selfRecursive1 at stack-trace.js:52 + 63 selfRecursive1 at stack-trace.js:52 + 64 selfRecursive1 at stack-trace.js:52 + 65 selfRecursive1 at stack-trace.js:52 + 66 selfRecursive1 at stack-trace.js:52 + 67 selfRecursive1 at stack-trace.js:52 + 68 selfRecursive1 at stack-trace.js:52 + 69 selfRecursive1 at stack-trace.js:52 + 70 selfRecursive1 at stack-trace.js:52 + 71 selfRecursive1 at stack-trace.js:52 + 72 selfRecursive1 at stack-trace.js:52 + 73 selfRecursive1 at stack-trace.js:52 + 74 selfRecursive1 at stack-trace.js:52 + 75 selfRecursive1 at stack-trace.js:52 + 76 selfRecursive1 at stack-trace.js:52 + 77 selfRecursive1 at stack-trace.js:52 + 78 selfRecursive1 at stack-trace.js:52 + 79 selfRecursive1 at stack-trace.js:52 + 80 selfRecursive1 at stack-trace.js:52 + 81 selfRecursive1 at stack-trace.js:52 + 82 selfRecursive1 at stack-trace.js:52 + 83 selfRecursive1 at stack-trace.js:52 + 84 selfRecursive1 at stack-trace.js:52 + 85 selfRecursive1 at stack-trace.js:52 + 86 selfRecursive1 at stack-trace.js:52 + 87 selfRecursive1 at stack-trace.js:52 + 88 selfRecursive1 at stack-trace.js:52 + 89 selfRecursive1 at stack-trace.js:52 + 90 selfRecursive1 at stack-trace.js:52 + 91 selfRecursive1 at stack-trace.js:52 + 92 selfRecursive1 at stack-trace.js:52 + 93 selfRecursive1 at stack-trace.js:52 + 94 selfRecursive1 at stack-trace.js:52 + 95 selfRecursive1 at stack-trace.js:52 + 96 selfRecursive1 at stack-trace.js:52 + 97 selfRecursive1 at stack-trace.js:52 + 98 selfRecursive1 at stack-trace.js:52 + 99 selfRecursive1 at stack-trace.js:52 --> Stack Trace: - 0 selfRecursive2 at stack-trace.js:62 + 0 selfRecursive2 at stack-trace.js:58 1 selfRecursive2 at stack-trace.js:62 2 selfRecursive2 at stack-trace.js:62 3 selfRecursive2 at stack-trace.js:62 @@ -252,106 +253,106 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE 99 selfRecursive2 at stack-trace.js:62 --> Stack Trace: - 0 selfRecursive3 at stack-trace.js:69 - 1 at eval code - 2 eval at [native code] - 3 selfRecursive3 at stack-trace.js:69 - 4 at eval code - 5 eval at [native code] - 6 selfRecursive3 at stack-trace.js:69 - 7 at eval code - 8 eval at [native code] - 9 selfRecursive3 at stack-trace.js:69 - 10 at eval code - 11 eval at [native code] - 12 selfRecursive3 at stack-trace.js:69 - 13 at eval code - 14 eval at [native code] - 15 selfRecursive3 at stack-trace.js:69 - 16 at eval code - 17 eval at [native code] - 18 selfRecursive3 at stack-trace.js:69 - 19 at eval code - 20 eval at [native code] - 21 selfRecursive3 at stack-trace.js:69 - 22 at eval code - 23 eval at [native code] - 24 selfRecursive3 at stack-trace.js:69 - 25 at eval code - 26 eval at [native code] - 27 selfRecursive3 at stack-trace.js:69 - 28 at eval code - 29 eval at [native code] - 30 selfRecursive3 at stack-trace.js:69 - 31 at eval code - 32 eval at [native code] - 33 selfRecursive3 at stack-trace.js:69 - 34 at eval code - 35 eval at [native code] - 36 selfRecursive3 at stack-trace.js:69 - 37 at eval code - 38 eval at [native code] - 39 selfRecursive3 at stack-trace.js:69 - 40 at eval code - 41 eval at [native code] - 42 selfRecursive3 at stack-trace.js:69 - 43 at eval code - 44 eval at [native code] - 45 selfRecursive3 at stack-trace.js:69 - 46 at eval code - 47 eval at [native code] - 48 selfRecursive3 at stack-trace.js:69 - 49 at eval code - 50 eval at [native code] - 51 selfRecursive3 at stack-trace.js:69 - 52 at eval code - 53 eval at [native code] - 54 selfRecursive3 at stack-trace.js:69 - 55 at eval code - 56 eval at [native code] - 57 selfRecursive3 at stack-trace.js:69 - 58 at eval code - 59 eval at [native code] - 60 selfRecursive3 at stack-trace.js:69 - 61 at eval code - 62 eval at [native code] - 63 selfRecursive3 at stack-trace.js:69 - 64 at eval code - 65 eval at [native code] - 66 selfRecursive3 at stack-trace.js:69 - 67 at eval code - 68 eval at [native code] - 69 selfRecursive3 at stack-trace.js:69 - 70 at eval code - 71 eval at [native code] - 72 selfRecursive3 at stack-trace.js:69 - 73 at eval code - 74 eval at [native code] - 75 selfRecursive3 at stack-trace.js:69 - 76 at eval code - 77 eval at [native code] - 78 selfRecursive3 at stack-trace.js:69 - 79 at eval code - 80 eval at [native code] - 81 selfRecursive3 at stack-trace.js:69 - 82 at eval code - 83 eval at [native code] - 84 selfRecursive3 at stack-trace.js:69 - 85 at eval code - 86 eval at [native code] - 87 selfRecursive3 at stack-trace.js:69 - 88 at eval code - 89 eval at [native code] - 90 selfRecursive3 at stack-trace.js:69 - 91 at eval code - 92 eval at [native code] - 93 selfRecursive3 at stack-trace.js:69 - 94 at eval code - 95 eval at [native code] - 96 selfRecursive3 at stack-trace.js:69 - 97 at eval code - 98 eval at [native code] - 99 selfRecursive3 at stack-trace.js:69 + 0 eval at [native code] + 1 selfRecursive3 at stack-trace.js:69 + 2 at eval code + 3 eval at [native code] + 4 selfRecursive3 at stack-trace.js:69 + 5 at eval code + 6 eval at [native code] + 7 selfRecursive3 at stack-trace.js:69 + 8 at eval code + 9 eval at [native code] + 10 selfRecursive3 at stack-trace.js:69 + 11 at eval code + 12 eval at [native code] + 13 selfRecursive3 at stack-trace.js:69 + 14 at eval code + 15 eval at [native code] + 16 selfRecursive3 at stack-trace.js:69 + 17 at eval code + 18 eval at [native code] + 19 selfRecursive3 at stack-trace.js:69 + 20 at eval code + 21 eval at [native code] + 22 selfRecursive3 at stack-trace.js:69 + 23 at eval code + 24 eval at [native code] + 25 selfRecursive3 at stack-trace.js:69 + 26 at eval code + 27 eval at [native code] + 28 selfRecursive3 at stack-trace.js:69 + 29 at eval code + 30 eval at [native code] + 31 selfRecursive3 at stack-trace.js:69 + 32 at eval code + 33 eval at [native code] + 34 selfRecursive3 at stack-trace.js:69 + 35 at eval code + 36 eval at [native code] + 37 selfRecursive3 at stack-trace.js:69 + 38 at eval code + 39 eval at [native code] + 40 selfRecursive3 at stack-trace.js:69 + 41 at eval code + 42 eval at [native code] + 43 selfRecursive3 at stack-trace.js:69 + 44 at eval code + 45 eval at [native code] + 46 selfRecursive3 at stack-trace.js:69 + 47 at eval code + 48 eval at [native code] + 49 selfRecursive3 at stack-trace.js:69 + 50 at eval code + 51 eval at [native code] + 52 selfRecursive3 at stack-trace.js:69 + 53 at eval code + 54 eval at [native code] + 55 selfRecursive3 at stack-trace.js:69 + 56 at eval code + 57 eval at [native code] + 58 selfRecursive3 at stack-trace.js:69 + 59 at eval code + 60 eval at [native code] + 61 selfRecursive3 at stack-trace.js:69 + 62 at eval code + 63 eval at [native code] + 64 selfRecursive3 at stack-trace.js:69 + 65 at eval code + 66 eval at [native code] + 67 selfRecursive3 at stack-trace.js:69 + 68 at eval code + 69 eval at [native code] + 70 selfRecursive3 at stack-trace.js:69 + 71 at eval code + 72 eval at [native code] + 73 selfRecursive3 at stack-trace.js:69 + 74 at eval code + 75 eval at [native code] + 76 selfRecursive3 at stack-trace.js:69 + 77 at eval code + 78 eval at [native code] + 79 selfRecursive3 at stack-trace.js:69 + 80 at eval code + 81 eval at [native code] + 82 selfRecursive3 at stack-trace.js:69 + 83 at eval code + 84 eval at [native code] + 85 selfRecursive3 at stack-trace.js:69 + 86 at eval code + 87 eval at [native code] + 88 selfRecursive3 at stack-trace.js:69 + 89 at eval code + 90 eval at [native code] + 91 selfRecursive3 at stack-trace.js:69 + 92 at eval code + 93 eval at [native code] + 94 selfRecursive3 at stack-trace.js:69 + 95 at eval code + 96 eval at [native code] + 97 selfRecursive3 at stack-trace.js:69 + 98 at eval code + 99 eval at [native code] --> Stack Trace: 0 throwError at stack-trace.js:77 @@ -407,11 +408,12 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE 4 global code at stack-trace.js:169 --> Stack Trace: - 0 h at stack-trace.js:153 - 1 map at [native code] - 2 mapTest at stack-trace.js:158 - 3 mapTestDriver at stack-trace.js:164 - 4 global code at stack-trace.js:175 + 0 map at [native code] + 1 h at stack-trace.js:153 + 2 map at [native code] + 3 mapTest at stack-trace.js:158 + 4 mapTestDriver at stack-trace.js:164 + 5 global code at stack-trace.js:175 --> Stack Trace: 0 throwError at stack-trace.js:77 diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index 1ea1b2e..c4144a6 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -1,5 +1,42 @@ 2012-04-16 Oliver Hunt + Exception stack traces aren't complete when the exception starts in native code + https://bugs.webkit.org/show_bug.cgi?id=84073 + + Reviewed by Gavin Barraclough. + + Refactored building the stack trace to so that we can construct + it earlier, and don't rely on any prior work performed in the + exception handling machinery. Also updated LLInt and the DFG to + completely initialise the callframes of host function calls. + + * bytecode/CodeBlock.h: + (JSC::CodeBlock::codeOriginIndexForReturn): + (CodeBlock): + * dfg/DFGOperations.cpp: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::getStackTrace): + (JSC::Interpreter::addStackTraceIfNecessary): + (JSC): + (JSC::Interpreter::throwException): + * interpreter/Interpreter.h: + (Interpreter): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * jsc.cpp: + (functionJSCStack): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::handleHostCall): + * parser/Parser.h: + (JSC::::parse): + * runtime/Error.cpp: + (JSC::addErrorInfo): + (JSC::throwError): + * runtime/Error.h: + (JSC): + +2012-04-16 Oliver Hunt + Fix COMMANDLINE_TYPEDARRAYS build https://bugs.webkit.org/show_bug.cgi?id=84051 diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def index 8482f3f..590915c 100755 --- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def +++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def @@ -212,7 +212,7 @@ EXPORTS ?getPropertyDescriptor@JSObject@JSC@@QAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z ?getPropertyNames@JSObject@JSC@@SAXPAV12@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z ?getSlice@ArgList@JSC@@QBEXHAAV12@@Z - ?getStackTrace@Interpreter@JSC@@SAXPAVJSGlobalData@2@HAAV?$Vector@UStackFrame@JSC@@$0A@@WTF@@@Z + ?getStackTrace@Interpreter@JSC@@SAXPAVJSGlobalData@2@AAV?$Vector@UStackFrame@JSC@@$0A@@WTF@@@Z ?getString@JSCell@JSC@@QBE?AVUString@2@PAVExecState@2@@Z ?getString@JSCell@JSC@@QBE_NPAVExecState@2@AAVUString@2@@Z ?getter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h index 778376f..68db90f 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.h +++ b/Source/JavaScriptCore/bytecode/CodeBlock.h @@ -710,6 +710,14 @@ namespace JSC { return true; } + int codeOriginIndexForReturn(ReturnAddressPtr returnAddress) + { + ASSERT(hasCodeOrigins()); + unsigned offset = getJITCode().offsetOf(returnAddress.value()); + CodeOriginAtCallReturnOffset* entry = binarySearch(codeOrigins().begin(), codeOrigins().size(), offset, WTF::KeyMustNotBePresentInArray); + return entry - codeOrigins().begin(); + } + CodeOrigin codeOrigin(unsigned index) { ASSERT(m_rareData); diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp index 4cc2e86..ac8eb80 100644 --- a/Source/JavaScriptCore/dfg/DFGOperations.cpp +++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp @@ -792,6 +792,7 @@ static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializ ASSERT(callType != CallTypeJS); if (callType == CallTypeHost) { + execCallee->setCallee(asObject(callee)); globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee)); if (globalData->exception) return 0; @@ -812,6 +813,7 @@ static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializ ASSERT(constructType != ConstructTypeJS); if (constructType == ConstructTypeHost) { + execCallee->setCallee(asObject(callee)); globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee)); if (globalData->exception) return 0; diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp index 560146e..bdf8511 100644 --- a/Source/JavaScriptCore/interpreter/Interpreter.cpp +++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp @@ -65,6 +65,7 @@ #include #include #include +#include #if ENABLE(JIT) #include "JIT.h" @@ -952,14 +953,14 @@ static StackFrameCodeType getStackFrameCodeType(CallFrame* callFrame) return StackFrameGlobalCode; } -void Interpreter::getStackTrace(JSGlobalData* globalData, int line, Vector& results) +void Interpreter::getStackTrace(JSGlobalData* globalData, Vector& results) { - CallFrame* callFrame = globalData->topCallFrame->removeHostCallFrameFlag()->trueCallFrameFromVMCode(); + CallFrame* callFrame = globalData->topCallFrame->removeHostCallFrameFlag(); if (!callFrame || callFrame == CallFrame::noCaller()) return; + int line = getLineNumberForCallFrame(globalData, callFrame); - if (line == -1) - line = getLineNumberForCallFrame(globalData, callFrame); + callFrame = callFrame->trueCallFrameFromVMCode(); while (callFrame && callFrame != CallFrame::noCaller()) { UString sourceURL; @@ -975,6 +976,33 @@ void Interpreter::getStackTrace(JSGlobalData* globalData, int line, VectorglobalData(); + if (error->hasProperty(callFrame, globalData->propertyNames->stack)) + return; + + Vector stackTrace; + getStackTrace(&callFrame->globalData(), stackTrace); + + if (stackTrace.isEmpty()) + return; + + JSGlobalObject* globalObject = 0; + if (isTerminatedExecutionException(error) || isInterruptedExecutionException(error)) + globalObject = globalData->dynamicGlobalObject; + else + globalObject = error->globalObject(); + StringBuilder builder; + for (unsigned i = 0; i < stackTrace.size(); i++) { + builder.append(String(stackTrace[i].toString(globalObject->globalExec()).impl())); + if (i != stackTrace.size() - 1) + builder.append('\n'); + } + + error->putDirect(*globalData, globalData->propertyNames->stack, jsString(globalData, UString(builder.toString().impl())), ReadOnly | DontDelete); +} + NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset) { CodeBlock* codeBlock = callFrame->codeBlock(); @@ -990,12 +1018,9 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV // Using hasExpressionInfo to imply we are interested in rich exception info. if (codeBlock->hasExpressionInfo() && !hasErrorInfo(callFrame, exception)) { ASSERT(codeBlock->hasLineInfo()); - // FIXME: should only really be adding these properties to VM generated exceptions, // but the inspector currently requires these for all thrown objects. - Vector stackTrace; - getStackTrace(&callFrame->globalData(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), stackTrace); - addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source(), stackTrace); + addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source()); } isInterrupt = isInterruptedExecutionException(exception) || isTerminatedExecutionException(exception); diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h index 51881a5..adb23f2 100644 --- a/Source/JavaScriptCore/interpreter/Interpreter.h +++ b/Source/JavaScriptCore/interpreter/Interpreter.h @@ -222,7 +222,8 @@ namespace JSC { NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset); NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine); static const UString getTraceLine(CallFrame*, StackFrameCodeType, const UString&, int); - JS_EXPORT_PRIVATE static void getStackTrace(JSGlobalData*, int line, Vector& results); + JS_EXPORT_PRIVATE static void getStackTrace(JSGlobalData*, Vector& results); + static void addStackTraceIfNecessary(CallFrame*, JSObject* error); void dumpSampleData(ExecState* exec); void startSampling(); diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp index dbcd50e..0d291b3 100644 --- a/Source/JavaScriptCore/jit/JITStubs.cpp +++ b/Source/JavaScriptCore/jit/JITStubs.cpp @@ -3518,6 +3518,19 @@ DEFINE_STUB_FUNCTION(void*, vm_throw) { STUB_INIT_STACK_FRAME(stackFrame); JSGlobalData* globalData = stackFrame.globalData; + // It's possible for us to reach this point with incorrect origin metadata + // if a native function throws an exception after being planted in certain + // code paths as the native thunk doesn't can't unwind itself as if it were + // a JS function. So we redetermine the correct data here just to be safe. + if (CodeBlock* codeBlock = stackFrame.callFrame->codeBlock()) { +#if ENABLE(DFG_JIT) + if (codeBlock->hasCodeOrigins()) + stackFrame.callFrame->setBytecodeOffsetForNonDFGCode(codeBlock->codeOriginIndexForReturn(globalData->exceptionLocation)); + else +#endif + if (codeBlock->getJITType() == JITCode::BaselineJIT) + stackFrame.callFrame->setBytecodeOffsetForNonDFGCode(codeBlock->bytecodeOffset(stackFrame.callFrame, globalData->exceptionLocation)); + } ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception, globalData->exceptionLocation); STUB_SET_RETURN_ADDRESS(handler.catchRoutine); return handler.callFrame; diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp index 6cfc1e1..ac0ae2c 100644 --- a/Source/JavaScriptCore/jsc.cpp +++ b/Source/JavaScriptCore/jsc.cpp @@ -277,7 +277,7 @@ EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState* exec) { String trace = "--> Stack trace:\n"; Vector stackTrace; - Interpreter::getStackTrace(&exec->globalData(), -1, stackTrace); + Interpreter::getStackTrace(&exec->globalData(), stackTrace); int i = 0; for (Vector::iterator iter = stackTrace.begin(); iter < stackTrace.end(); iter++) { diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp index a1ec1ce..ff2b7c2 100644 --- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp +++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp @@ -1241,6 +1241,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, ASSERT(callType != CallTypeJS); if (callType == CallTypeHost) { + execCallee->setCallee(asObject(callee)); globalData.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee)); LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast(getHostCallReturnValue)); @@ -1262,6 +1263,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc, ASSERT(constructType != ConstructTypeJS); if (constructType == ConstructTypeHost) { + execCallee->setCallee(asObject(callee)); globalData.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee)); LLINT_CALL_RETURN(execCallee, pc, reinterpret_cast(getHostCallReturnValue)); diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h index 68a693a..aa0b91b 100644 --- a/Source/JavaScriptCore/parser/Parser.h +++ b/Source/JavaScriptCore/parser/Parser.h @@ -993,7 +993,7 @@ PassRefPtr Parser::parse(JSGlobalObject* lexicalGlobalObj else if (isEvalNode()) *exception = createSyntaxError(lexicalGlobalObject, errMsg); else - *exception = addErrorInfo(&lexicalGlobalObject->globalData(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, *m_source, Vector()); + *exception = addErrorInfo(lexicalGlobalObject->globalExec(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, *m_source); } if (debugger && !ParsedNode::scopeIsFunction) diff --git a/Source/JavaScriptCore/runtime/Error.cpp b/Source/JavaScriptCore/runtime/Error.cpp index 5266c1e..87eb23b 100644 --- a/Source/JavaScriptCore/runtime/Error.cpp +++ b/Source/JavaScriptCore/runtime/Error.cpp @@ -120,37 +120,21 @@ JSObject* createURIError(ExecState* exec, const UString& message) return createURIError(exec->lexicalGlobalObject(), message); } -JSObject* addErrorInfo(JSGlobalData* globalData, JSObject* error, int line, const SourceCode& source, const Vector& stackTrace) +JSObject* addErrorInfo(CallFrame* callFrame, JSObject* error, int line, const SourceCode& source) { + JSGlobalData* globalData = &callFrame->globalData(); const UString& sourceURL = source.provider()->url(); if (line != -1) error->putDirect(*globalData, Identifier(globalData, linePropertyName), jsNumber(line), ReadOnly | DontDelete); if (!sourceURL.isNull()) error->putDirect(*globalData, Identifier(globalData, sourceURLPropertyName), jsString(globalData, sourceURL), ReadOnly | DontDelete); - if (!stackTrace.isEmpty()) { - JSGlobalObject* globalObject = 0; - if (isTerminatedExecutionException(error) || isInterruptedExecutionException(error)) - globalObject = globalData->dynamicGlobalObject; - else - globalObject = error->globalObject(); - StringBuilder builder; - for (unsigned i = 0; i < stackTrace.size(); i++) { - builder.append(String(stackTrace[i].toString(globalObject->globalExec()).impl())); - if (i != stackTrace.size() - 1) - builder.append('\n'); - } - - error->putDirect(*globalData, globalData->propertyNames->stack, jsString(globalData, UString(builder.toString().impl())), ReadOnly | DontDelete); - } + + globalData->interpreter->addStackTraceIfNecessary(callFrame, error); return error; } -JSObject* addErrorInfo(ExecState* exec, JSObject* error, int line, const SourceCode& source, const Vector& stackTrace) -{ - return addErrorInfo(&exec->globalData(), error, line, source, stackTrace); -} bool hasErrorInfo(ExecState* exec, JSObject* error) { @@ -160,12 +144,15 @@ bool hasErrorInfo(ExecState* exec, JSObject* error) JSValue throwError(ExecState* exec, JSValue error) { + if (error.isObject()) + return throwError(exec, asObject(error)); exec->globalData().exception = error; return error; } JSObject* throwError(ExecState* exec, JSObject* error) { + Interpreter::addStackTraceIfNecessary(exec, error); exec->globalData().exception = error; return error; } diff --git a/Source/JavaScriptCore/runtime/Error.h b/Source/JavaScriptCore/runtime/Error.h index 59b3949..ad50542 100644 --- a/Source/JavaScriptCore/runtime/Error.h +++ b/Source/JavaScriptCore/runtime/Error.h @@ -57,9 +57,8 @@ namespace JSC { // Methods to add bool hasErrorInfo(ExecState*, JSObject* error); - JSObject* addErrorInfo(JSGlobalData*, JSObject* error, int line, const SourceCode&, const Vector&); // ExecState wrappers. - JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&, const Vector&); + JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&); // Methods to throw Errors. JS_EXPORT_PRIVATE JSValue throwError(ExecState*, JSValue); -- 2.7.4