Changeset 216635 in webkit
- Timestamp:
- May 10, 2017, 4:22:33 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r216634 r216635 1 2017-05-10 Mark Lam <mark.lam@apple.com> 2 3 WorkerThread::stop() should call scheduleExecutionTermination() last. 4 https://bugs.webkit.org/show_bug.cgi?id=171775 5 <rdar://problem/30975761> 6 7 Reviewed by Geoffrey Garen. 8 9 * TestExpectations: 10 1 11 2017-05-10 Tim Horton <timothy_horton@apple.com> 2 12 -
trunk/LayoutTests/TestExpectations
r216267 r216635 365 365 366 366 webkit.org/b/161312 imported/w3c/web-platform-tests/html/semantics/document-metadata/the-link-element/document-without-browsing-context.html [ Failure Pass ] 367 368 # rdar://problem/30975761369 [ Debug ] http/tests/fetch/fetch-in-worker-crash.html [ Skip ]370 367 371 368 imported/w3c/web-platform-tests/XMLHttpRequest/send-conditional-cors.htm [ Failure ] -
trunk/Source/JavaScriptCore/ChangeLog
r216608 r216635 1 2017-05-10 Mark Lam <mark.lam@apple.com> 2 3 WorkerThread::stop() should call scheduleExecutionTermination() last. 4 https://bugs.webkit.org/show_bug.cgi?id=171775 5 <rdar://problem/30975761> 6 7 Reviewed by Geoffrey Garen. 8 9 Increased the number of frames captured in VM::nativeStackTraceOfLastThrow() 10 from 25 to 100. From experience, I found that 25 is sometimes not sufficient 11 for our debugging needs. 12 13 Also added VM::throwingThread() to track which thread an exception was thrown in. 14 This may be useful if the client is entering the VM from different threads. 15 16 * runtime/ExceptionScope.cpp: 17 (JSC::ExceptionScope::unexpectedExceptionMessage): 18 (JSC::ExceptionScope::releaseAssertIsTerminatedExecutionException): 19 * runtime/ExceptionScope.h: 20 (JSC::ExceptionScope::exception): 21 (JSC::ExceptionScope::unexpectedExceptionMessage): 22 * runtime/VM.cpp: 23 (JSC::VM::throwException): 24 * runtime/VM.h: 25 (JSC::VM::throwingThread): 26 (JSC::VM::clearException): 27 1 28 2017-05-10 Mark Lam <mark.lam@apple.com> 2 29 -
trunk/Source/JavaScriptCore/runtime/ExceptionScope.cpp
r216428 r216635 1 1 /* 2 * Copyright (C) 2016 Apple Inc. All rights reserved.2 * Copyright (C) 2016-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 29 29 #include "Exception.h" 30 #include "ExceptionHelpers.h" 30 31 #include <wtf/StackTrace.h> 31 32 #include <wtf/StringPrintStream.h> 33 #include <wtf/Threading.h> 32 34 33 35 namespace JSC { … … 54 56 StringPrintStream out; 55 57 56 out.println("Unexpected exception observed at:");57 auto currentStack = std::unique_ptr<StackTrace>(StackTrace::captureStackTrace( 25, 1));58 out.println("Unexpected exception observed on thread ", currentThread(), " at:"); 59 auto currentStack = std::unique_ptr<StackTrace>(StackTrace::captureStackTrace(100, 1)); 58 60 currentStack->dump(out, " "); 59 61 … … 61 63 return CString(); 62 64 63 out.println("The exception was thrown from :");65 out.println("The exception was thrown from thread ", m_vm.throwingThread(), " at:"); 64 66 m_vm.nativeStackTraceOfLastThrow()->dump(out, " "); 65 67 … … 69 71 #endif // ENABLE(EXCEPTION_SCOPE_VERIFICATION) 70 72 73 void ExceptionScope::releaseAssertIsTerminatedExecutionException() 74 { 75 RELEASE_ASSERT_WITH_MESSAGE(isTerminatedExecutionException(m_vm, exception()), "%s", unexpectedExceptionMessage().data()); 76 } 77 71 78 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ExceptionScope.h
r216428 r216635 43 43 ALWAYS_INLINE void releaseAssertNoException() { RELEASE_ASSERT_WITH_MESSAGE(!exception(), "%s", unexpectedExceptionMessage().data()); } 44 44 45 void releaseAssertIsTerminatedExecutionException(); 46 45 47 protected: 46 48 ExceptionScope(VM&, ExceptionEventLocation); … … 63 65 ALWAYS_INLINE VM& vm() const { return m_vm; } 64 66 ALWAYS_INLINE Exception* exception() { return m_vm.exception(); } 65 ALWAYS_INLINE CString unexpectedExceptionMessage() { return { }; }66 67 67 68 ALWAYS_INLINE void assertNoException() { ASSERT(!exception()); } 68 69 ALWAYS_INLINE void releaseAssertNoException() { RELEASE_ASSERT(!exception()); } 70 71 void releaseAssertIsTerminatedExecutionException(); 69 72 70 73 protected: … … 74 77 ExceptionScope(const ExceptionScope&) = delete; 75 78 ExceptionScope(ExceptionScope&&) = default; 79 80 ALWAYS_INLINE CString unexpectedExceptionMessage() { return { }; } 76 81 77 82 VM& m_vm; -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r216481 r216635 620 620 621 621 #if ENABLE(EXCEPTION_SCOPE_VERIFICATION) 622 m_nativeStackTraceOfLastThrow = std::unique_ptr<StackTrace>(StackTrace::captureStackTrace(25)); 622 m_nativeStackTraceOfLastThrow = std::unique_ptr<StackTrace>(StackTrace::captureStackTrace(100)); 623 m_throwingThread = currentThread(); 623 624 #endif 624 625 } -
trunk/Source/JavaScriptCore/runtime/VM.h
r216481 r216635 685 685 #if ENABLE(EXCEPTION_SCOPE_VERIFICATION) 686 686 StackTrace* nativeStackTraceOfLastThrow() const { return m_nativeStackTraceOfLastThrow.get(); } 687 ThreadIdentifier throwingThread() const { return m_throwingThread; } 687 688 #endif 688 689 … … 720 721 m_needExceptionCheck = false; 721 722 m_nativeStackTraceOfLastThrow = nullptr; 723 m_throwingThread = 0; 722 724 #endif 723 725 m_exception = nullptr; … … 767 769 mutable bool m_needExceptionCheck { false }; 768 770 std::unique_ptr<StackTrace> m_nativeStackTraceOfLastThrow; 771 ThreadIdentifier m_throwingThread; 769 772 #endif 770 773 -
trunk/Source/WebCore/ChangeLog
r216634 r216635 1 2017-05-10 Mark Lam <mark.lam@apple.com> 2 3 WorkerThread::stop() should call scheduleExecutionTermination() last. 4 https://bugs.webkit.org/show_bug.cgi?id=171775 5 <rdar://problem/30975761> 6 7 Reviewed by Geoffrey Garen. 8 9 Currently, WorkerThread::stop() calls scheduleExecutionTermination() to terminate 10 JS execution first, followed by posting a cleanup task to the worker, and lastly, 11 it invokes terminate() on the WorkerRunLoop. 12 13 As a result, before run loop is terminate, the worker thread may observe the 14 TerminatedExecutionException in JS code, bail out, see another JS task to run, 15 re-enters the VM to run said JS code, and fails with an assertion due to the 16 TerminatedExecutionException still being pending on VM entry. 17 18 WorkerRunLoop::Task::performTask() already has a check to only allow a task to 19 run if and only if !runLoop.terminated() and the task is not a clean up task. 20 We'll fix the above race by ensuring that having WorkerThread::stop() terminate 21 the run loop before it scheduleExecutionTermination() which throws the 22 TerminatedExecutionException. This way, by the time JS code unwinds out of the 23 VM due to the TerminatedExecutionException, runLoop.terminated() is guaranteed 24 to be true and thereby prevents re-entry into the VM. 25 26 This issue is covered by an existing test that I just unskipped in TestExpectations. 27 28 * bindings/js/JSDOMPromiseDeferred.cpp: 29 (WebCore::DeferredPromise::callFunction): 30 * workers/WorkerThread.cpp: 31 (WebCore::WorkerThread::stop): 32 1 33 2017-05-10 Tim Horton <timothy_horton@apple.com> 2 34 -
trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp
r216501 r216635 1 1 /* 2 * Copyright (C) 2013 , 2016Apple Inc. All rights reserved.2 * Copyright (C) 2013-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 50 50 return; 51 51 52 VM& vm = exec.vm(); 53 auto scope = DECLARE_THROW_SCOPE(vm); 54 52 55 CallData callData; 53 56 CallType callType = getCallData(function, callData); … … 58 61 59 62 call(&exec, function, callType, callData, jsUndefined(), arguments); 63 64 // DeferredPromise should only be used by internal implementations that are well behaved. 65 // In practice, the only exception we should ever see here is the TerminatedExecutionException. 66 ASSERT_UNUSED(scope, !scope.exception() || isTerminatedExecutionException(vm, scope.exception())); 60 67 61 68 clear(); -
trunk/Source/WebCore/workers/WorkerThread.cpp
r215265 r216635 235 235 LockHolder lock(m_threadCreationMutex); 236 236 237 // Ensure that tasks are being handled by thread event loop. If script execution weren't forbidden, a while(1) loop in JS could keep the thread alive forever.238 237 if (m_workerGlobalScope) { 239 m_workerGlobalScope->script()->scheduleExecutionTermination();240 241 238 m_runLoop.postTaskAndTerminate({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext& context ) { 242 239 WorkerGlobalScope& workerGlobalScope = downcast<WorkerGlobalScope>(context); … … 266 263 } 267 264 m_runLoop.terminate(); 265 266 // Ensure that tasks are being handled by thread event loop. If script execution weren't forbidden, a while(1) loop in JS could keep the thread alive forever. 267 if (m_workerGlobalScope) 268 m_workerGlobalScope->script()->scheduleExecutionTermination(); 268 269 } 269 270
Note:
See TracChangeset
for help on using the changeset viewer.