Bug 234358 - [iOS 15] Crash during WebProcessProxy::didClose while writing to NSUserDefaults on another thread
Summary: [iOS 15] Crash during WebProcessProxy::didClose while writing to NSUserDefaul...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit API (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-12-15 11:54 PST by Ali Juma
Modified: 2022-03-07 14:39 PST (History)
5 users (show)

See Also:


Attachments
Crash report 1 (32.65 KB, text/plain)
2021-12-15 11:54 PST, Ali Juma
no flags Details
Crash report 2 (39.43 KB, text/plain)
2021-12-15 11:55 PST, Ali Juma
no flags Details
Crash report 3 (32.42 KB, text/plain)
2021-12-15 11:55 PST, Ali Juma
no flags Details
Crash report 4 (29.10 KB, text/plain)
2021-12-15 11:55 PST, Ali Juma
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ali Juma 2021-12-15 11:54:46 PST
Created attachment 447264 [details]
Crash report 1

Chrome for iOS is getting a large number of crash reports that have the following combination of events:

1) The main thread is in inside WebProcessProxy::didClose.

2) The crashing thread is writing to NSUserDefaults (this part is being called from Chrome code).

Since (2) happens every 30s in Chrome, it may be that when this happens to coincide with WebProcessProxy::didClose, something related to CFPREFS_DIRECT_MODE (e.g., WKPreferenceObserver gets callbacks for all changes to NSUserDefaults) is in a bad state.

Here's a sample crash stack. I'll also attach some crash reports.

Thread 0:
0x0000000198e53384	(libobjc.A.dylib + 0x00008384)		getMethodNoSuper_nolock(objc_class*, objc_selector*)
0x0000000198e50610	(libobjc.A.dylib + 0x00005610)		lookUpImpOrForward
0x0000000198e4c3fc	(libobjc.A.dylib + 0x000013fc)		_objc_msgSend_uncached
0x000000018fa6c180	(WebKit + 0x003c5180)		WebKit::WebPageProxy::resetStateAfterProcessTermination(WebKit::ProcessTerminationReason)
0x000000018fab4014	(WebKit + 0x0040d014)		WebKit::WebProcessProxy::processDidTerminateOrFailedToLaunch(WebKit::ProcessTerminationReason)
0x000000018fab39f8	(WebKit + 0x0040c9f8)		WebKit::WebProcessProxy::didClose(IPC::Connection&)
0x000000018f6dc91c	(WebKit + 0x0003591c)		WTF::Detail::CallableWrapper<IPC::Connection::connectionDidClose()::$_8, void>::call()
0x000000018d17bd64	(JavaScriptCore + 0x00fa7d64)		WTF::RunLoop::performWork()
0x000000018d17cc48	(JavaScriptCore + 0x00fa8c48)		WTF::RunLoop::performWork(void*)
0x0000000181ccc20c	(CoreFoundation + 0x000b220c)		__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
0x0000000181cdc234	(CoreFoundation + 0x000c2234)		__CFRunLoopDoSource0
0x0000000181c1f638	(CoreFoundation + 0x00005638)		__CFRunLoopDoSources0
0x0000000181c24a04	(CoreFoundation + 0x0000aa04)		__CFRunLoopRun
0x0000000181c37d78	(CoreFoundation + 0x0001dd78)		CFRunLoopRunSpecific
0x000000019beac99c	(GraphicsServices + 0x0000199c)		GSEventRunModal
0x000000018446a058	(UIKitCore + 0x004ec058)		-[UIApplication _run]
0x00000001841ffcdc	(UIKitCore + 0x00281cdc)		UIApplicationMain
0x0000000100bc826c	(Chrome -chrome_exe_main.mm:65)		main
0x0000000102f9418c	

Thread 4 (id: 0x00006003) CRASHED [EXC_BAD_ACCESS / KERN_INVALID_ADDRESS @ 0xffffffff90d301c0 ] 
0x0000000198e5081c	(libobjc.A.dylib + 0x0000581c)		class_getMethodImplementation
0x00000001833966c4	(Foundation + 0x0003e6c4)		_NSKVONotifyingOriginalClassForIsa
0x00000001833966c4	(Foundation + 0x0003e6c4)		_NSKVONotifyingOriginalClassForIsa
0x0000000183398088	(Foundation + 0x00040088)		_NSKeyValueObservationInfoGetObservances
0x0000000183399510	(Foundation + 0x00041510)		NSKeyValueWillChange
0x0000000183382ec4	(Foundation + 0x0002aec4)		-[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:maybeNewValuesDict:usingBlock:]
0x00000001833a05b0	(Foundation + 0x000485b0)		-[NSObject(NSKeyValueObservingPrivate) _notifyObserversOfChangeFromValuesForKeys:toValuesForKeys:]
0x0000000181c75714	(CoreFoundation + 0x0005b714)		-[CFPrefsSource forEachObserver:]
0x0000000181d08cb0	(CoreFoundation + 0x000eecb0)		-[CFPrefsSource _notifyObserversOfChangeFromValuesForKeys:toValuesForKeys:]
0x0000000181ce5a54	(CoreFoundation + 0x000cba54)		___CFPrefsDeliverPendingKVONotificationsGuts_block_invoke
0x0000000181c43ac4	(CoreFoundation + 0x00029ac4)		__CFDictionaryApplyFunction_block_invoke
0x0000000181c41718	(CoreFoundation + 0x00027718)		CFBasicHashApply
0x0000000181c432e0	(CoreFoundation + 0x000292e0)		CFDictionaryApplyFunction
0x0000000181cd1eb4	(CoreFoundation + 0x000b7eb4)		_CFPrefsDeliverPendingKVONotificationsGuts
0x0000000181c4093c	(CoreFoundation + 0x0002693c)		-[_CFXPreferences _deliverPendingKVONotifications]
0x0000000181c6c990	(CoreFoundation + 0x00052990)		__108-[_CFXPreferences(SearchListAdditions) withSearchListForIdentifier:container:cloudConfigurationURL:perform:]_block_invoke
0x0000000181c46d14	(CoreFoundation + 0x0002cd14)		normalizeQuintuplet
0x0000000181c40620	(CoreFoundation + 0x00026620)		-[_CFXPreferences withSearchListForIdentifier:container:cloudConfigurationURL:perform:]
0x0000000181ce88e8	(CoreFoundation + 0x000ce8e8)		-[_CFXPreferences setValue:forKey:appIdentifier:container:configurationURL:]
0x0000000181c71c2c	(CoreFoundation + 0x00057c2c)		_CFPreferencesSetAppValueWithContainerAndConfiguration
0x00000001833918ac	(Foundation + 0x000398ac)		-[NSUserDefaults(NSUserDefaults) setObject:forKey:]
0x0000000100ec6d68	(Chrome -previous_session_info.mm:625)		-[PreviousSessionInfo setReportParameterValue:forKey:]
0x0000000101a8ec2c	(Chrome -crash_key_breakpad_ios.mm:54)		crash_reporter::internal::CrashKeyStringImpl::Set(base::BasicStringPiece<char, std::__1::char_traits<char> >)
0x0000000101032e3c	(Chrome -crash_key.h:218)		crash_reporter::CrashKeyStringCombined<16u>::Set(base::BasicStringPiece<char, std::__1::char_traits<char> >)
0x0000000101033840	(Chrome -crash_keys_helper.mm:80)		crash_keys::SetCurrentFreeMemoryInKB(int)
0x0000000100bce108	(Chrome -memory_monitor.mm:38)		(anonymous namespace)::AsynchronousFreeMemoryMonitor()
0x00000001014f9648	(Chrome -callback.h:142)		base::TaskAnnotator::RunTask(char const*, base::PendingTask*)
0x000000010150d818	(Chrome -task_tracker.cc:660)		base::internal::TaskTracker::RunSkipOnShutdown(base::internal::Task*)
0x000000010150d42c	(Chrome -task_tracker.cc:675)		base::internal::TaskTracker::RunTask(base::internal::Task, base::internal::TaskSource*, base::TaskTraits const&)
0x0000000101535f18	(Chrome -task_tracker_posix.cc:22)		base::internal::TaskTrackerPosix::RunTask(base::internal::Task, base::internal::TaskSource*, base::TaskTraits const&)
0x000000010150d0cc	(Chrome -task_tracker.cc:431)		base::internal::TaskTracker::RunAndPopNextTask(base::internal::RegisteredTaskSource)
0x000000010151a29c	(Chrome -worker_thread.cc:377)		base::internal::WorkerThread::RunWorker()
0x0000000101519ec8	(Chrome -worker_thread.cc:271)		base::internal::WorkerThread::RunBackgroundPooledWorker()
0x0000000101536414	(Chrome -platform_thread_posix.cc:96)		base::(anonymous namespace)::ThreadFunc(void*)
0x00000001dad8b3a0	(libsystem_pthread.dylib + 0x000063a0)		_pthread_start
Comment 1 Ali Juma 2021-12-15 11:55:01 PST
Created attachment 447265 [details]
Crash report 2
Comment 2 Ali Juma 2021-12-15 11:55:22 PST
Created attachment 447266 [details]
Crash report 3
Comment 3 Ali Juma 2021-12-15 11:55:36 PST
Created attachment 447267 [details]
Crash report 4
Comment 4 Alexey Proskuryakov 2021-12-17 17:29:58 PST
This offset in WebPageProxy::resetStateAfterProcessTermination corresponds to line 7951 in https://trac.webkit.org/browser/webkit/tags/Safari-612.2.9.0.20/Source/WebKit/UIProcess/WebPageProxy.cpp

        pageClient().processDidExit();

Tracing into what it could be calling, I don't see anything helpful (seems like it would be [CATransaction commit] in WebViewImpl::setAcceleratedCompositingRootLayer, based on omitted frames?.. But trying to guess execution flow based on missing frames is a long shot.

Can you say what key the Chrome thread is writing? Maybe that would help see who is observing it, and whether there is a refcounting bug.
Comment 5 Radar WebKit Bug Importer 2021-12-17 17:30:12 PST
<rdar://problem/86657481>
Comment 6 Ali Juma 2021-12-20 05:55:10 PST
(In reply to Alexey Proskuryakov from comment #4)
> This offset in WebPageProxy::resetStateAfterProcessTermination corresponds
> to line 7951 in
> https://trac.webkit.org/browser/webkit/tags/Safari-612.2.9.0.20/Source/
> WebKit/UIProcess/WebPageProxy.cpp
> 
>         pageClient().processDidExit();
> 
> Tracing into what it could be calling, I don't see anything helpful (seems
> like it would be [CATransaction commit] in
> WebViewImpl::setAcceleratedCompositingRootLayer, based on omitted frames?..
> But trying to guess execution flow based on missing frames is a long shot.
> 
> Can you say what key the Chrome thread is writing? Maybe that would help see
> who is observing it, and whether there is a refcounting bug.

The Chrome thread is writing the key "PreviousSessionInfoParams".
Comment 7 Per Arne Vollan 2022-02-28 09:51:38 PST
This seems to be crashing in the UI process. CF prefs direct mode is not enabled in the UI process, and is possibly not related to this crash.
Comment 8 Per Arne Vollan 2022-03-07 14:18:15 PST
This seems to be crashing when notifying a released preference observer about a preference change. Is Chrome using KVO?
Comment 9 Ali Juma 2022-03-07 14:39:41 PST
(In reply to Per Arne Vollan from comment #8)
> This seems to be crashing when notifying a released preference observer
> about a preference change. Is Chrome using KVO?

Chrome uses KVO in general, but not specifically for observing preferences afaik.

Also, avoiding writing to NSUserDefaults off the main thread (that is, by instead dispatching this back to the main thread) has so far been successful in working around this crash.