- Revision
- 279902
- Author
- [email protected]
- Date
- 2021-07-13 19:42:10 -0700 (Tue, 13 Jul 2021)
Log Message
[WK2] Push OS state dumping logic down from WebProcess to AuxiliaryProcess
https://bugs.webkit.org/show_bug.cgi?id=227916
Reviewed by Tim Horton.
Refactor state dumping registration code in preparation for supporting state dumping in the GPU process on Cocoa
platforms when triggering system diagnostics. The logic that currently lives in
`WebProcess::registerWithStateDumper` is comprised of two parts: (1) code that calls `os_state_add_handler` with
a `os_state_data_t` provider, and (2) code that builds a dictionary containing diagnostic information specific
to the web process.
Since GPUProcess will require only the former, we hoist logic for (1) into the superclass (AuxiliaryProcess) so
that both GPUProcess and WebProcess can invoke it, and refactor (2) to be a virtual method that may be
overridden by subclasses to provide process-specific information.
* Shared/AuxiliaryProcess.h:
(WebKit::AuxiliaryProcess::additionalStateForDiagnosticReport const):
* Shared/Cocoa/AuxiliaryProcessCocoa.mm:
(WebKit::AuxiliaryProcess::registerWithStateDumper):
Additionally make this take the title string that will be used to label the state data, to avoid the need for a
second subclassing method to provide the title.
* WebProcess/WebProcess.h:
* WebProcess/cocoa/WebProcessCocoa.mm:
(WebKit::WebProcess::additionalStateForDiagnosticReport const):
Pull logic for collecting diagnostic information in the web process out into a separate helper method.
(WebKit::WebProcess::platformInitializeProcess):
(WebKit::WebProcess::registerWithStateDumper): Deleted.
Modified Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (279901 => 279902)
--- trunk/Source/WebKit/ChangeLog 2021-07-14 00:36:25 UTC (rev 279901)
+++ trunk/Source/WebKit/ChangeLog 2021-07-14 02:42:10 UTC (rev 279902)
@@ -1,3 +1,37 @@
+2021-07-13 Wenson Hsieh <[email protected]>
+
+ [WK2] Push OS state dumping logic down from WebProcess to AuxiliaryProcess
+ https://bugs.webkit.org/show_bug.cgi?id=227916
+
+ Reviewed by Tim Horton.
+
+ Refactor state dumping registration code in preparation for supporting state dumping in the GPU process on Cocoa
+ platforms when triggering system diagnostics. The logic that currently lives in
+ `WebProcess::registerWithStateDumper` is comprised of two parts: (1) code that calls `os_state_add_handler` with
+ a `os_state_data_t` provider, and (2) code that builds a dictionary containing diagnostic information specific
+ to the web process.
+
+ Since GPUProcess will require only the former, we hoist logic for (1) into the superclass (AuxiliaryProcess) so
+ that both GPUProcess and WebProcess can invoke it, and refactor (2) to be a virtual method that may be
+ overridden by subclasses to provide process-specific information.
+
+ * Shared/AuxiliaryProcess.h:
+ (WebKit::AuxiliaryProcess::additionalStateForDiagnosticReport const):
+ * Shared/Cocoa/AuxiliaryProcessCocoa.mm:
+ (WebKit::AuxiliaryProcess::registerWithStateDumper):
+
+ Additionally make this take the title string that will be used to label the state data, to avoid the need for a
+ second subclassing method to provide the title.
+
+ * WebProcess/WebProcess.h:
+ * WebProcess/cocoa/WebProcessCocoa.mm:
+ (WebKit::WebProcess::additionalStateForDiagnosticReport const):
+
+ Pull logic for collecting diagnostic information in the web process out into a separate helper method.
+
+ (WebKit::WebProcess::platformInitializeProcess):
+ (WebKit::WebProcess::registerWithStateDumper): Deleted.
+
2021-07-13 Alex Christensen <[email protected]>
REGRESSION(r279069): http/tests/websocket/tests/hybi/too-long-payload.html is a constant timeout when using NSURLSESSION_WEBSOCKET
Modified: trunk/Source/WebKit/Shared/AuxiliaryProcess.h (279901 => 279902)
--- trunk/Source/WebKit/Shared/AuxiliaryProcess.h 2021-07-14 00:36:25 UTC (rev 279901)
+++ trunk/Source/WebKit/Shared/AuxiliaryProcess.h 2021-07-14 02:42:10 UTC (rev 279902)
@@ -36,6 +36,12 @@
#include <wtf/text/StringHash.h>
#include <wtf/text/WTFString.h>
+#if PLATFORM(COCOA)
+#include <wtf/RetainPtr.h>
+#endif
+
+OBJC_CLASS NSDictionary;
+
namespace WebKit {
class SandboxInitializationParameters;
@@ -107,6 +113,11 @@
virtual void stopRunLoop();
+#if USE(OS_STATE)
+ void registerWithStateDumper(ASCIILiteral title);
+ virtual RetainPtr<NSDictionary> additionalStateForDiagnosticReport() const { return { }; }
+#endif // USE(OS_STATE)
+
#if USE(APPKIT)
static void stopNSAppRunLoop();
#endif
Modified: trunk/Source/WebKit/Shared/Cocoa/AuxiliaryProcessCocoa.mm (279901 => 279902)
--- trunk/Source/WebKit/Shared/Cocoa/AuxiliaryProcessCocoa.mm 2021-07-14 00:36:25 UTC (rev 279901)
+++ trunk/Source/WebKit/Shared/Cocoa/AuxiliaryProcessCocoa.mm 2021-07-14 02:42:10 UTC (rev 279902)
@@ -26,6 +26,7 @@
#import "config.h"
#import "AuxiliaryProcess.h"
+#import "OSStateSPI.h"
#import "WKCrashReporter.h"
#import "XPCServiceEntryPoint.h"
#import <WebCore/FloatingPointEnvironment.h>
@@ -81,4 +82,52 @@
XPCServiceExit(WTFMove(m_priorityBoostMessage));
}
+#if USE(OS_STATE)
+
+void AuxiliaryProcess::registerWithStateDumper(ASCIILiteral title)
+{
+ os_state_add_handler(dispatch_get_main_queue(), [this, title] (os_state_hints_t hints) {
+ @autoreleasepool {
+ os_state_data_t os_state = nullptr;
+
+ // Only gather state on faults and sysdiagnose. It's overkill for
+ // general error messages.
+ if (hints->osh_api == OS_STATE_API_ERROR)
+ return os_state;
+
+ auto stateDictionary = additionalStateForDiagnosticReport();
+
+ // Submitting an empty process state object may provide an
+ // indication of the existance of private sessions, which we'd like
+ // to hide, so don't return empty dictionaries.
+ if (![stateDictionary count])
+ return os_state;
+
+ // Serialize the accumulated process state so that we can put the
+ // result in an os_state_data_t structure.
+ NSError *error = nil;
+ auto data = "" dataWithPropertyList:stateDictionary.get() format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error];
+
+ if (!data) {
+ ASSERT(data);
+ return os_state;
+ }
+
+ auto neededSize = OS_STATE_DATA_SIZE_NEEDED(data.length);
+ os_state = (os_state_data_t)malloc(neededSize);
+ if (os_state) {
+ memset(os_state, 0, neededSize);
+ os_state->osd_type = OS_STATE_DATA_SERIALIZED_NSCF_OBJECT;
+ os_state->osd_data_size = data.length;
+ strlcpy(os_state->osd_title, title.characters(), sizeof(os_state->osd_title));
+ memcpy(os_state->osd_data, data.bytes, data.length);
+ }
+
+ return os_state;
+ }
+ });
}
+
+#endif // USE(OS_STATE)
+
+} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/WebProcess.h (279901 => 279902)
--- trunk/Source/WebKit/WebProcess/WebProcess.h 2021-07-14 00:36:25 UTC (rev 279901)
+++ trunk/Source/WebKit/WebProcess/WebProcess.h 2021-07-14 02:42:10 UTC (rev 279902)
@@ -410,7 +410,7 @@
void prewarmWithDomainInformation(const WebCore::PrewarmInformation&);
#if USE(OS_STATE)
- void registerWithStateDumper();
+ RetainPtr<NSDictionary> additionalStateForDiagnosticReport() const final;
#endif
void markAllLayersVolatile(CompletionHandler<void()>&&);
Modified: trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm (279901 => 279902)
--- trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm 2021-07-14 00:36:25 UTC (rev 279901)
+++ trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm 2021-07-14 02:42:10 UTC (rev 279902)
@@ -33,7 +33,6 @@
#import "Logging.h"
#import "NetworkConnectionToWebProcessMessages.h"
#import "NetworkProcessConnection.h"
-#import "OSStateSPI.h"
#import "ObjCObjectGraph.h"
#import "ProcessAssertion.h"
#import "SandboxExtension.h"
@@ -591,87 +590,45 @@
}
#if USE(OS_STATE)
-void WebProcess::registerWithStateDumper()
+
+RetainPtr<NSDictionary> WebProcess::additionalStateForDiagnosticReport() const
{
- os_state_add_handler(dispatch_get_main_queue(), ^(os_state_hints_t hints) {
+ auto stateDictionary = adoptNS([[NSMutableDictionary alloc] init]);
+ {
+ auto memoryUsageStats = adoptNS([[NSMutableDictionary alloc] init]);
+ for (auto& it : PerformanceLogging::memoryUsageStatistics(ShouldIncludeExpensiveComputations::Yes)) {
+ auto keyString = adoptNS([[NSString alloc] initWithUTF8String:it.key]);
+ [memoryUsageStats setObject:@(it.value) forKey:keyString.get()];
+ }
+ [stateDictionary setObject:memoryUsageStats.get() forKey:@"Memory Usage Stats"];
+ }
+ {
+ auto jsObjectCounts = adoptNS([[NSMutableDictionary alloc] init]);
+ for (auto& it : PerformanceLogging::_javascript_ObjectCounts()) {
+ auto keyString = adoptNS([[NSString alloc] initWithUTF8String:it.key]);
+ [jsObjectCounts setObject:@(it.value) forKey:keyString.get()];
+ }
+ [stateDictionary setObject:jsObjectCounts.get() forKey:@"_javascript_ Object Counts"];
+ }
+ auto pageLoadTimes = createNSArray(m_pageMap.values(), [] (auto& page) -> id {
+ if (page->usesEphemeralSession())
+ return nil;
- @autoreleasepool {
- os_state_data_t os_state = nil;
+ return [NSDate dateWithTimeIntervalSince1970:page->loadCommitTime().secondsSinceEpoch().seconds()];
+ });
- // Only gather state on faults and sysdiagnose. It's overkill for
- // general error messages.
- if (hints->osh_api == OS_STATE_API_ERROR)
- return os_state;
+ // Adding an empty array to the process state may provide an
+ // indication of the existance of private sessions, which we'd like
+ // to hide, so don't add empty arrays.
+ if ([pageLoadTimes count])
+ [stateDictionary setObject:pageLoadTimes.get() forKey:@"Page Load Times"];
- // Create a dictionary to contain the collected state. This
- // dictionary will be serialized and passed back to os_state.
- auto stateDict = adoptNS([[NSMutableDictionary alloc] init]);
+ // --- Possibly add other state here as other entries in the dictionary. ---
+ return stateDictionary;
+}
- {
- auto memoryUsageStats = adoptNS([[NSMutableDictionary alloc] init]);
- for (auto& it : PerformanceLogging::memoryUsageStatistics(ShouldIncludeExpensiveComputations::Yes)) {
- auto keyString = adoptNS([[NSString alloc] initWithUTF8String:it.key]);
- [memoryUsageStats setObject:@(it.value) forKey:keyString.get()];
- }
- [stateDict setObject:memoryUsageStats.get() forKey:@"Memory Usage Stats"];
- }
+#endif // USE(OS_STATE)
- {
- auto jsObjectCounts = adoptNS([[NSMutableDictionary alloc] init]);
- for (auto& it : PerformanceLogging::_javascript_ObjectCounts()) {
- auto keyString = adoptNS([[NSString alloc] initWithUTF8String:it.key]);
- [jsObjectCounts setObject:@(it.value) forKey:keyString.get()];
- }
- [stateDict setObject:jsObjectCounts.get() forKey:@"_javascript_ Object Counts"];
- }
-
- auto pageLoadTimes = createNSArray(m_pageMap.values(), [] (auto& page) -> id {
- if (page->usesEphemeralSession())
- return nil;
-
- return [NSDate dateWithTimeIntervalSince1970:page->loadCommitTime().secondsSinceEpoch().seconds()];
- });
-
- // Adding an empty array to the process state may provide an
- // indication of the existance of private sessions, which we'd like
- // to hide, so don't add empty arrays.
- if ([pageLoadTimes count])
- [stateDict setObject:pageLoadTimes.get() forKey:@"Page Load Times"];
-
- // --- Possibly add other state here as other entries in the dictionary. ---
-
- // Submitting an empty process state object may provide an
- // indication of the existance of private sessions, which we'd like
- // to hide, so don't return empty dictionaries.
- if (![stateDict count])
- return os_state;
-
- // Serialize the accumulated process state so that we can put the
- // result in an os_state_data_t structure.
- NSError* error = nil;
- NSData* data = "" dataWithPropertyList:stateDict.get() format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error];
-
- if (!data) {
- ASSERT(data);
- return os_state;
- }
-
- size_t neededSize = OS_STATE_DATA_SIZE_NEEDED(data.length);
- os_state = (os_state_data_t)malloc(neededSize);
- if (os_state) {
- memset(os_state, 0, neededSize);
- os_state->osd_type = OS_STATE_DATA_SERIALIZED_NSCF_OBJECT;
- os_state->osd_data_size = data.length;
- strlcpy(os_state->osd_title, "WebContent state", sizeof(os_state->osd_title));
- memcpy(os_state->osd_data, data.bytes, data.length);
- }
-
- return os_state;
- }
- });
-}
-#endif
-
void WebProcess::platformInitializeProcess(const AuxiliaryProcessInitializationParameters& parameters)
{
#if PLATFORM(MAC)
@@ -702,7 +659,7 @@
m_processType = ProcessType::WebContent;
#if USE(OS_STATE)
- registerWithStateDumper();
+ registerWithStateDumper("WebContent state"_s);
#endif
#if HAVE(APP_SSO) || PLATFORM(MACCATALYST)