Bug 210955 - [Win] Deadlock in WTF::Thread::didExit() while WebKitNetworkProcess.exe is exiting
Summary: [Win] Deadlock in WTF::Thread::didExit() while WebKitNetworkProcess.exe is ex...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Template Framework (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Fujii Hironori
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-04-24 00:04 PDT by Fujii Hironori
Modified: 2021-03-03 13:26 PST (History)
11 users (show)

See Also:


Attachments
Patch to do quick_exit (471 bytes, patch)
2020-04-26 16:27 PDT, Fujii Hironori
no flags Details | Formatted Diff | Diff
Patch to TerminateProcess (559 bytes, patch)
2020-04-26 22:01 PDT, Fujii Hironori
no flags Details | Formatted Diff | Diff
a test program to exit while other thread is locking a Lock (856 bytes, patch)
2020-04-27 00:25 PDT, Fujii Hironori
no flags Details | Formatted Diff | Diff
Patch (1.78 KB, patch)
2020-04-27 23:17 PDT, Fujii Hironori
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Fujii Hironori 2020-04-24 00:04:48 PDT
[WinCairo] Dead lock in WTF::Thread::didExit() while WebKitNetworkProcess.exe is exiting

By running run-webkit-tests, sometimes WebKitNetworkProcess.exe process doesn't exit.

> python ./Tools/Scripts/run-webkit-tests --wincairo --debug --no-new-test-results --no-retry-failures --no-show-results -f fast

There is only the main thread, and here is its callstack.

Callstack:

> ntdll.dll!NtWaitForAlertByThreadId()	Unknown
> ntdll.dll!RtlSleepConditionVariableSRW()	Unknown
> KernelBase.dll!SleepConditionVariableSRW()	Unknown
> WTF.dll!WTF::ThreadCondition::timedWait(WTF::Mutex & mutex={...}, WTF::WallTime absoluteTime={...}) Line 383	C++
> WTF.dll!WTF::ParkingLot::parkConditionallyImpl(const void * address=0x00007ffc1ec325ac, const WTF::ScopedLambda<bool __cdecl(void)> & validation={...}, const WTF::ScopedLambda<void __cdecl(void)> & beforeSleep={...}, const WTF::TimeWithDynamicClockType & timeout={...}) Line 604	C++
> WTF.dll!WTF::ParkingLot::parkConditionally<bool <lambda>(void),void <lambda>(void)>(const void * address=0x00007ffc1ec325ac, const WTF::ParkingLot::compareAndPark::__l2::bool <lambda>(void) & validation=bool <lambda>(void){...}, const WTF::ParkingLot::compareAndPark::__l2::void <lambda>(void) & beforeSleep=void <lambda>(void){...}, const WTF::TimeWithDynamicClockType & timeout={...}) Line 82	C++
> WTF.dll!WTF::ParkingLot::compareAndPark<unsigned char,unsigned char>(const WTF::Atomic<unsigned char> * address=0x00007ffc1ec325ac, unsigned char expected='\x3') Line 94	C++
> WTF.dll!WTF::LockAlgorithm<unsigned char,1,2,WTF::EmptyLockHooks<unsigned char>>::lockSlow(WTF::Atomic<unsigned char> & lock={...}) Line 83	C++
> WTF.dll!WTF::Lock::lockSlow() Line 41	C++
> WTF.dll!WTF::Lock::lock() Line 60	C++
> WTF.dll!WTF::Locker<WTF::Lock>::lock() Line 114	C++
> WTF.dll!WTF::Locker<WTF::Lock>::Locker<WTF::Lock>(WTF::Lock & lockable={...}) Line 55	C++
> WTF.dll!WTF::Thread::didExit() Line 226	C++
> WTF.dll!WTF::Thread::ThreadHolder::~ThreadHolder() Line 274	C++
> WTF.dll!WTF::`dynamic atexit destructor for 's_threadHolder''()	C++
> WTF.dll!__dyn_tls_dtor(void * __formal=0x000000007ffe0385, const unsigned long dwReason, void * __formal) Line 119	C++
> ntdll.dll!LdrpCallInitRoutine()	Unknown
> ntdll.dll!LdrpCallTlsInitializers()	Unknown
> ntdll.dll!LdrShutdownProcess()	Unknown
> ntdll.dll!RtlExitUserProcess()	Unknown
> kernel32.dll!ExitProcessImplementation()	Unknown
> ucrtbase.dll!exit_or_terminate_process()	Unknown
> ucrtbase.dll!common_exit()	Unknown
> WebKitNetworkProcess.exe!__scrt_common_main_seh() Line 295	C++
> kernel32.dll!BaseThreadInitThunk()	Unknown
> ntdll.dll!RtlUserThreadStart()	Unknown

I don't know when this issue started to happen, but not so long time ago.
I fixed very similar issue in 5 months ago.

  Bug 204192 – [WinCairo] dead lock in Thread::destructTLS
Comment 1 Fujii Hironori 2020-04-26 16:27:22 PDT
Created attachment 397633 [details]
Patch to do quick_exit
Comment 2 Fujii Hironori 2020-04-26 16:28:13 PDT
Using std::quick_exit doesn't solve the issue.
The callstack looks almost same.

> ntdll.dll!NtWaitForAlertByThreadId()	Unknown
> ntdll.dll!RtlSleepConditionVariableSRW()	Unknown
> KernelBase.dll!SleepConditionVariableSRW()	Unknown
> WTF.dll!WTF::ThreadCondition::timedWait(WTF::Mutex & mutex={...}, WTF::WallTime absoluteTime={...}) Line 383	C++
> WTF.dll!WTF::ParkingLot::parkConditionallyImpl(const void * address=0x00007ffc230755ac, const WTF::ScopedLambda<bool __cdecl(void)> & validation={...}, const WTF::ScopedLambda<void __cdecl(void)> & beforeSleep={...}, const WTF::TimeWithDynamicClockType & timeout={...}) Line 604	C++
> WTF.dll!WTF::ParkingLot::parkConditionally<bool <lambda>(void),void <lambda>(void)>(const void * address=0x00007ffc230755ac, const WTF::ParkingLot::compareAndPark::__l2::bool <lambda>(void) & validation=bool <lambda>(void){...}, const WTF::ParkingLot::compareAndPark::__l2::void <lambda>(void) & beforeSleep=void <lambda>(void){...}, const WTF::TimeWithDynamicClockType & timeout={...}) Line 82	C++
> WTF.dll!WTF::ParkingLot::compareAndPark<unsigned char,unsigned char>(const WTF::Atomic<unsigned char> * address=0x00007ffc230755ac, unsigned char expected='\x3') Line 94	C++
> WTF.dll!WTF::LockAlgorithm<unsigned char,1,2,WTF::EmptyLockHooks<unsigned char>>::lockSlow(WTF::Atomic<unsigned char> & lock={...}) Line 83	C++
> WTF.dll!WTF::Lock::lockSlow() Line 41	C++
> WTF.dll!WTF::Lock::lock() Line 60	C++
> WTF.dll!WTF::Locker<WTF::Lock>::lock() Line 114	C++
> WTF.dll!WTF::Locker<WTF::Lock>::Locker<WTF::Lock>(WTF::Lock & lockable={...}) Line 55	C++
> WTF.dll!WTF::holdLock<WTF::Lock>(WTF::Lock & lock={...}) Line 127	C++
> WTF.dll!WTF::Thread::didExit() Line 231	C++
> WTF.dll!WTF::Thread::ThreadHolder::~ThreadHolder() Line 274	C++
> WTF.dll!WTF::`dynamic atexit destructor for 's_threadHolder''()	C++
> WTF.dll!__dyn_tls_dtor(void * __formal=0x000000007ffe0385, const unsigned long dwReason, void * __formal) Line 119	C++
> ntdll.dll!LdrpCallInitRoutine()	Unknown
> ntdll.dll!LdrpCallTlsInitializers()	Unknown
> ntdll.dll!LdrShutdownProcess()	Unknown
> ntdll.dll!RtlExitUserProcess()	Unknown
> kernel32.dll!ExitProcessImplementation()	Unknown
> ucrtbase.dll!exit_or_terminate_process()	Unknown
> ucrtbase.dll!common_exit()	Unknown
> WebKitNetworkProcess.exe!main(int argc=7, char * * argv=0x000001f2ec737650) Line 36	C++
> [Inline Frame] WebKitNetworkProcess.exe!invoke_main() Line 78	C++
> WebKitNetworkProcess.exe!__scrt_common_main_seh() Line 288	C++
> kernel32.dll!BaseThreadInitThunk()	Unknown
> ntdll.dll!RtlUserThreadStart()	Unknown
Comment 3 Fujii Hironori 2020-04-26 22:01:26 PDT
Created attachment 397643 [details]
Patch to TerminateProcess

Using TerminateProcess solves the issue.
Comment 4 Fujii Hironori 2020-04-27 00:25:04 PDT
Created attachment 397651 [details]
a test program to exit while other thread is locking a Lock

I created a test program that the main thread exits while other thread is locking a Lock.
This program is based on Bug 204192 Comment 26.

> TestWTF.exe --gtest_filter=WTF_Lock.Test1

The deadlock happened with the following callstack.

> ntdll.dll!NtWaitForAlertByThreadId()	Unknown
> ntdll.dll!RtlSleepConditionVariableSRW()	Unknown
> KernelBase.dll!SleepConditionVariableSRW()	Unknown
> WTF.dll!WTF::ThreadCondition::timedWait(WTF::Mutex & mutex={...}, WTF::WallTime absoluteTime={...}) Line 383	C++
> WTF.dll!WTF::ParkingLot::parkConditionallyImpl(const void * address=0x00007ffc1d0d1c28, const WTF::ScopedLambda<bool __cdecl(void)> & validation={...}, const WTF::ScopedLambda<void __cdecl(void)> & beforeSleep={...}, const WTF::TimeWithDynamicClockType & timeout={...}) Line 604	C++
> WTF.dll!WTF::ParkingLot::parkConditionally<bool <lambda>(void),void <lambda>(void)>(const void * address=0x00007ffc1d0d1c28, const WTF::ParkingLot::compareAndPark::__l2::bool <lambda>(void) & validation=bool <lambda>(void){...}, const WTF::ParkingLot::compareAndPark::__l2::void <lambda>(void) & beforeSleep=void <lambda>(void){...}, const WTF::TimeWithDynamicClockType & timeout={...}) Line 82	C++
> WTF.dll!WTF::ParkingLot::compareAndPark<unsigned char,unsigned char>(const WTF::Atomic<unsigned char> * address=0x00007ffc1d0d1c28, unsigned char expected='\x3') Line 94	C++
> WTF.dll!WTF::LockAlgorithm<unsigned char,1,2,WTF::EmptyLockHooks<unsigned char>>::lockSlow(WTF::Atomic<unsigned char> & lock={...}) Line 83	C++
> WTF.dll!WTF::Lock::lockSlow() Line 41	C++
> TestWTFLib.dll!WTF::Lock::lock() Line 60	C++
> TestWTFLib.dll!WTF::Locker<WTF::Lock>::lock() Line 114	C++
> TestWTFLib.dll!WTF::Locker<WTF::Lock>::Locker<WTF::Lock>(WTF::Lock & lockable={...}) Line 55	C++
> TestWTFLib.dll!WTF::holdLock<WTF::Lock>(WTF::Lock & lock={...}) Line 127	C++
> TestWTFLib.dll!`TestWebKitAPI::WTF_Lock_Test1_Test::TestBody'::`2'::ThreadExitCallback::~ThreadExitCallback() Line 206	C++
> TestWTFLib.dll!`TestWebKitAPI::WTF_Lock_Test1_Test::TestBody'::`2'::`dynamic atexit destructor for 'callback''()	C++
> TestWTFLib.dll!__dyn_tls_dtor(void * __formal=0x000000007ffe0385, const unsigned long dwReason, void * __formal) Line 119	C++
> ntdll.dll!LdrpCallInitRoutine()	Unknown
> ntdll.dll!LdrpCallTlsInitializers()	Unknown
> ntdll.dll!LdrShutdownProcess()	Unknown
> ntdll.dll!RtlExitUserProcess()	Unknown
> kernel32.dll!ExitProcessImplementation()	Unknown
> ucrtbase.dll!exit_or_terminate_process()	Unknown
> ucrtbase.dll!common_exit()	Unknown
> TestWTF.exe!__scrt_common_main_seh() Line 295	C++
> kernel32.dll!BaseThreadInitThunk()	Unknown
> ntdll.dll!RtlUserThreadStart()	Unknown
Comment 5 Fujii Hironori 2020-04-27 23:17:24 PDT
Created attachment 397810 [details]
Patch
Comment 6 Fujii Hironori 2020-04-29 13:06:53 PDT
Comment on attachment 397810 [details]
Patch

Clearing flags on attachment: 397810

Committed r260911: <https://trac.webkit.org/changeset/260911>
Comment 7 Fujii Hironori 2020-04-29 13:06:57 PDT
All reviewed patches have been landed.  Closing bug.
Comment 8 Yusuke Suzuki 2020-04-29 13:19:16 PDT
Nice!