Changeset 216677 in webkit
- Timestamp:
- May 11, 2017, 8:26:03 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r216676 r216677 1 2017-05-11 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-11 Carlos Garcia Campos <cgarcia@igalia.com> 2 12 -
trunk/LayoutTests/TestExpectations
r216638 r216677 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
r216672 r216677 1 2017-05-11 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-11 JF Bastien <jfbastien@apple.com> 2 29 -
trunk/Source/JavaScriptCore/runtime/ExceptionScope.cpp
r216638 r216677 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
r216638 r216677 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
r216638 r216677 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
r216638 r216677 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
r216669 r216677 1 2017-05-11 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-11 Chris Dumez <cdumez@apple.com> 2 34 -
trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp
r216638 r216677 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
r216638 r216677 1 1 /* 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.2 * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 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); … … 263 260 264 261 } }); 262 263 // Prevent a while (1) { } loop from keeping the worker alive forever by requesting that the worker thread 264 // throw an uncatchable TerminatedExecutionException. 265 // 266 // We should only do this after terminating the runloop via the call to m_runLoop.postTaskAndTerminate() 267 // above. This ensures that when the worker bails out of JS code due to the TerminatedExecutionException, 268 // the m_runLoop.terminated() flag will already be set, and WorkerRunLoop::Task::performTask() won't try to 269 // re-enter the VM with the TerminatedExecutionException still pending thereafter. 270 m_workerGlobalScope->script()->scheduleExecutionTermination(); 265 271 return; 266 272 }
Note:
See TracChangeset
for help on using the changeset viewer.