Changeset 255189 in webkit
- Timestamp:
- Jan 27, 2020 3:37:49 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 5 deleted
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r255188 r255189 1 2020-01-27 Chris Dumez <cdumez@apple.com> 2 3 Unreviewed, revert r253984 as it appears to be causing assertion leaks. 4 https://bugs.webkit.org/show_bug.cgi?id=205687 5 6 * Configurations/WebKit.xcconfig: 7 * Platform/spi/ios/RunningBoardServicesSPI.h: Removed. 8 * Scripts/process-entitlements.sh: 9 * Shared/DependencyProcessAssertion.cpp: Removed. 10 * Shared/DependencyProcessAssertion.h: Removed. 11 * Shared/NativeWebTouchEvent.h: 12 * Shared/ios/DependencyProcessAssertionIOS.mm: Removed. 13 * Sources.txt: 14 * SourcesCocoa.txt: 15 * UIProcess/Cocoa/WebProcessProxyCocoa.mm: 16 (WebKit::WebProcessProxy::processWasResumed): 17 * UIProcess/WebProcessProxy.h: 18 * UIProcess/WebProcessProxy.messages.in: 19 * WebKit.xcodeproj/project.pbxproj: 20 * WebProcess/WebProcess.cpp: 21 (WebKit::WebProcess::initializeConnection): 22 * WebProcess/WebProcess.h: 23 * WebProcess/cocoa/WebProcessCocoa.mm: 24 (WebKit::WebProcess::processTaskStateDidChange): 25 (WebKit::WebProcess::releaseProcessWasResumedAssertions): 26 1 27 2020-01-27 Jiewen Tan <jiewen_tan@apple.com> 2 28 -
trunk/Source/WebKit/Configurations/WebKit.xcconfig
r254938 r255189 51 51 WK_ASSERTION_SERVICES_LDFLAGS = $(WK_ASSERTION_SERVICES_LDFLAGS_$(WK_COCOA_TOUCH)); 52 52 WK_ASSERTION_SERVICES_LDFLAGS_cocoatouch = -framework AssertionServices; 53 54 WK_RUNNINGBOARD_SERVICES_LDFLAGS = $(WK_RUNNINGBOARD_SERVICES_LDFLAGS_$(WK_COCOA_TOUCH));55 WK_RUNNINGBOARD_SERVICES_LDFLAGS_cocoatouch = -framework RunningBoardServices;56 53 57 54 WK_CARBON_LDFLAGS = $(WK_CARBON_LDFLAGS_$(WK_PLATFORM_NAME)); … … 127 124 WK_AUTHKIT_LDFLAGS_MACOS_SINCE_1015 = -framework AuthKit; 128 125 129 FRAMEWORK_AND_LIBRARY_LDFLAGS = -lobjc -framework CFNetwork -framework CoreAudio -framework CoreFoundation -framework CoreGraphics -framework CoreText -framework Foundation -framework ImageIO -framework IOKit -framework IOSurface -framework WebKitLegacy -lnetwork $(WK_ACCESSIBILITY_LDFLAGS) $(WK_APPKIT_LDFLAGS) $(WK_ASSERTION_SERVICES_LDFLAGS) $(WK_ RUNNINGBOARD_SERVICES_LDFLAGS) $(WK_AUTHKIT_LDFLAGS) $(WK_CARBON_LDFLAGS) $(WK_CORE_PREDICTION_LDFLAGS) $(WK_CORE_SERVICES_LDFLAGS) $(WK_DEVICE_IDENTITY_LDFLAGS) $(WK_GRAPHICS_SERVICES_LDFLAGS) $(WK_LIBSANDBOX_LDFLAGS) $(WK_LIBWEBRTC_LDFLAGS) $(WK_MOBILE_CORE_SERVICES_LDFLAGS) $(WK_MOBILE_GESTALT_LDFLAGS) $(WK_OPENGL_LDFLAGS) $(WK_PDFKIT_LDFLAGS) $(WK_SAFE_BROWSING_LDFLAGS) $(WK_SECURITY_INTERFACE_LDFLAGS) $(WK_UIKIT_LDFLAGS) $(WK_URL_FORMATTING_LDFLAGS) $(WK_WEBINSPECTORUI_LDFLAGS);126 FRAMEWORK_AND_LIBRARY_LDFLAGS = -lobjc -framework CFNetwork -framework CoreAudio -framework CoreFoundation -framework CoreGraphics -framework CoreText -framework Foundation -framework ImageIO -framework IOKit -framework IOSurface -framework WebKitLegacy -lnetwork $(WK_ACCESSIBILITY_LDFLAGS) $(WK_APPKIT_LDFLAGS) $(WK_ASSERTION_SERVICES_LDFLAGS) $(WK_AUTHKIT_LDFLAGS) $(WK_CARBON_LDFLAGS) $(WK_CORE_PREDICTION_LDFLAGS) $(WK_CORE_SERVICES_LDFLAGS) $(WK_DEVICE_IDENTITY_LDFLAGS) $(WK_GRAPHICS_SERVICES_LDFLAGS) $(WK_LIBSANDBOX_LDFLAGS) $(WK_LIBWEBRTC_LDFLAGS) $(WK_MOBILE_CORE_SERVICES_LDFLAGS) $(WK_MOBILE_GESTALT_LDFLAGS) $(WK_OPENGL_LDFLAGS) $(WK_PDFKIT_LDFLAGS) $(WK_SAFE_BROWSING_LDFLAGS) $(WK_SECURITY_INTERFACE_LDFLAGS) $(WK_UIKIT_LDFLAGS) $(WK_URL_FORMATTING_LDFLAGS) $(WK_WEBINSPECTORUI_LDFLAGS); 130 127 131 128 // Prevent C++ standard library basic_stringstream, operator new, delete and their related exception types from being exported as weak symbols. -
trunk/Source/WebKit/Scripts/process-entitlements.sh
r255155 r255189 110 110 plistbuddy Add :com.apple.private.webinspector.allow-remote-inspection bool YES 111 111 plistbuddy Add :com.apple.private.webinspector.proxy-application bool YES 112 plistbuddy Add :com.apple.runningboard.assertions.webkit bool YES113 112 plistbuddy Add :dynamic-codesigning bool YES 114 113 -
trunk/Source/WebKit/Shared/NativeWebTouchEvent.h
r253984 r255189 28 28 #include "WebEvent.h" 29 29 30 #if PLATFORM(IOS_FAMILY) && defined(__OBJC__)31 #include <UIKit/UIKit.h>32 #endif33 34 30 #if ENABLE(TOUCH_EVENTS) 35 31 36 32 #if PLATFORM(IOS_FAMILY) 37 33 #if defined(__OBJC__) 34 #include <UIKit/UIKit.h> 38 35 struct _UIWebTouchEvent; 39 36 #endif -
trunk/Source/WebKit/Sources.txt
r254817 r255189 143 143 Shared/ContextMenuContextData.cpp 144 144 Shared/DebuggableInfoData.cpp 145 Shared/DependencyProcessAssertion.cpp146 145 Shared/EditingRange.cpp 147 146 Shared/EditorState.cpp -
trunk/Source/WebKit/SourcesCocoa.txt
r254817 r255189 174 174 175 175 Shared/ios/AuxiliaryProcessIOS.mm 176 Shared/ios/DependencyProcessAssertionIOS.mm177 176 Shared/ios/InteractionInformationAtPosition.mm 178 177 Shared/ios/InteractionInformationRequest.cpp -
trunk/Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm
r253984 r255189 191 191 #endif 192 192 193 } 193 #if PLATFORM(IOS_FAMILY) 194 void WebProcessProxy::processWasResumed(CompletionHandler<void()>&& completionHandler) 195 { 196 CompletionHandlerCallingScope exitScope(WTFMove(completionHandler)); 197 198 if (m_throttler.shouldBeRunnable()) { 199 // The process becoming unsuspended was not unexpected. 200 return; 201 } 202 203 // The WebProcess was awakened by something other than the UIProcess. Take out an assertion for a 204 // limited duration to allow whatever task needs to be accomplished time to complete. 205 RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::processWasResumed() Process was unexpectedly resumed, starting background activity", this); 206 auto backgroundActivityTimeoutHandler = [activity = m_throttler.backgroundActivity("WebProcess was unexpectedly resumed"_s), weakThis = makeWeakPtr(this)] { 207 RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::processWasResumed() - lambda, background activity timed out", weakThis.get()); 208 }; 209 m_unexpectedActivityTimer = makeUnique<WebCore::DeferrableOneShotTimer>(WTFMove(backgroundActivityTimeoutHandler), unexpectedActivityDuration); 210 } 211 #endif 212 213 } -
trunk/Source/WebKit/UIProcess/WebProcessProxy.h
r254569 r255189 329 329 #endif 330 330 331 #if PLATFORM(IOS_FAMILY) 332 void processWasResumed(CompletionHandler<void()>&&); 333 #endif 334 331 335 void webPageMediaStateDidChange(WebPageProxy&); 332 336 … … 503 507 #if PLATFORM(IOS_FAMILY) 504 508 bool m_hasSentMessageToUnblockAccessibilityServer { false }; 509 std::unique_ptr<WebCore::DeferrableOneShotTimer> m_unexpectedActivityTimer; 505 510 #endif 506 511 -
trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in
r253984 r255189 73 73 #endif 74 74 75 #if PLATFORM(IOS_FAMILY) 76 ProcessWasResumed() -> () Async 77 #endif 78 75 79 # Plug-in messages. 76 80 void AddPlugInAutoStartOriginHash(String pageOrigin, uint32_t hash) -
trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj
r255135 r255189 953 953 46CE3B1123D8C8490016A96A /* WebBackForwardListCounts.h in Headers */ = {isa = PBXBuildFile; fileRef = 46CE3B1023D8C83D0016A96A /* WebBackForwardListCounts.h */; }; 954 954 46DF063C1F3905F8001980BB /* NetworkCORSPreflightChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 46DF063A1F3905E5001980BB /* NetworkCORSPreflightChecker.h */; }; 955 46F77D8023BE63BE0090B5A7 /* DependencyProcessAssertion.h in Headers */ = {isa = PBXBuildFile; fileRef = 46F77D7E23BE63B10090B5A7 /* DependencyProcessAssertion.h */; };956 955 46F9B26323526EF3006FE5FA /* WebBackForwardCacheEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 46F9B26223526ED0006FE5FA /* WebBackForwardCacheEntry.h */; }; 957 46FDA8F723BE586900B198FA /* RunningBoardServicesSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 46FDA8F623BE585900B198FA /* RunningBoardServicesSPI.h */; };958 956 4960A3BD23C52AFD00961842 /* WebViewCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 4960A3BC23C5286400961842 /* WebViewCategory.h */; }; 959 957 49BCA19223A177660028A836 /* APIResourceLoadStatisticsFirstParty.h in Headers */ = {isa = PBXBuildFile; fileRef = 49BCA19123A177660028A836 /* APIResourceLoadStatisticsFirstParty.h */; }; … … 3494 3492 46DF06391F3905E5001980BB /* NetworkCORSPreflightChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCORSPreflightChecker.cpp; sourceTree = "<group>"; }; 3495 3493 46DF063A1F3905E5001980BB /* NetworkCORSPreflightChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCORSPreflightChecker.h; sourceTree = "<group>"; }; 3496 46F77D7E23BE63B10090B5A7 /* DependencyProcessAssertion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DependencyProcessAssertion.h; sourceTree = "<group>"; };3497 46F77D7F23BE63B20090B5A7 /* DependencyProcessAssertion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DependencyProcessAssertion.cpp; sourceTree = "<group>"; };3498 46F77D8123BE63DC0090B5A7 /* DependencyProcessAssertionIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = DependencyProcessAssertionIOS.mm; path = ios/DependencyProcessAssertionIOS.mm; sourceTree = "<group>"; };3499 3494 46F9B26223526ED0006FE5FA /* WebBackForwardCacheEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebBackForwardCacheEntry.h; sourceTree = "<group>"; }; 3500 46FDA8F623BE585900B198FA /* RunningBoardServicesSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RunningBoardServicesSPI.h; sourceTree = "<group>"; };3501 3495 4960A3BC23C5286400961842 /* WebViewCategory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebViewCategory.h; sourceTree = "<group>"; }; 3502 3496 49BCA19023A175490028A836 /* _WKResourceLoadStatisticsFirstPartyInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKResourceLoadStatisticsFirstPartyInternal.h; sourceTree = "<group>"; }; … … 5681 5675 99036AE823A970870000B06A /* DebuggableInfoData.cpp */, 5682 5676 99036AE723A970870000B06A /* DebuggableInfoData.h */, 5683 46F77D7F23BE63B20090B5A7 /* DependencyProcessAssertion.cpp */,5684 46F77D7E23BE63B10090B5A7 /* DependencyProcessAssertion.h */,5685 5677 2D7FD190223C730F007887F1 /* DocumentEditingContext.h */, 5686 5678 2D7FD191223C7310007887F1 /* DocumentEditingContext.mm */, … … 6574 6566 children = ( 6575 6567 A7E93CEB192531AA00A1DC48 /* AuxiliaryProcessIOS.mm */, 6576 46F77D8123BE63DC0090B5A7 /* DependencyProcessAssertionIOS.mm */,6577 6568 2DA6731920C754B1003CB401 /* DynamicViewportSizeUpdate.h */, 6578 6569 2DA9449D1884E4F000ED86DB /* GestureTypes.h */, … … 9787 9778 3178AF9720E2A7F80074DE94 /* PDFKitSPI.h */, 9788 9779 2DC18FAF218912640025A88D /* PencilKitSPI.h */, 9789 46FDA8F623BE585900B198FA /* RunningBoardServicesSPI.h */,9790 9780 CE1A0BD01A48E6C60054EF74 /* TCCSPI.h */, 9791 9781 CE1A0BD11A48E6C60054EF74 /* TextInputSPI.h */, … … 10165 10155 99036AE923A970870000B06A /* DebuggableInfoData.h in Headers */, 10166 10156 BC032DA610F437D10058C15A /* Decoder.h in Headers */, 10167 46F77D8023BE63BE0090B5A7 /* DependencyProcessAssertion.h in Headers */,10168 10157 57DCEDAB214C60090016B847 /* DeviceIdentitySPI.h in Headers */, 10169 10158 07297F9F1C17BBEA015F0735 /* DeviceIdHashSaltStorage.h in Headers */, … … 10461 10450 1A30066E1110F4F70031937C /* ResponsivenessTimer.h in Headers */, 10462 10451 410482CE1DDD324F00F006D0 /* RTCNetwork.h in Headers */, 10463 46FDA8F723BE586900B198FA /* RunningBoardServicesSPI.h in Headers */,10464 10452 0E97D74D200E900400BF6643 /* SafeBrowsingSPI.h in Headers */, 10465 10453 5CA9854A210BEB640057EB6B /* SafeBrowsingWarning.h in Headers */, -
trunk/Source/WebKit/WebProcess/WebProcess.cpp
r255178 r255189 32 32 #include "AuthenticationManager.h" 33 33 #include "AuxiliaryProcessMessages.h" 34 #include "DependencyProcessAssertion.h"35 34 #include "DrawingArea.h" 36 35 #include "EventDispatcher.h" … … 276 275 #if PLATFORM(IOS_FAMILY) 277 276 m_viewUpdateDispatcher->initializeConnection(connection); 278 279 ASSERT(!m_uiProcessDependencyProcessAssertion);280 m_uiProcessDependencyProcessAssertion = makeUnique<DependencyProcessAssertion>(connection->remoteProcessID(), "WebContent process dependency on UIProcess"_s);281 277 #endif // PLATFORM(IOS_FAMILY) 282 283 278 m_webInspectorInterruptDispatcher->initializeConnection(connection); 284 279 … … 291 286 292 287 m_webConnection = WebConnectionToUIProcess::create(this); 288 289 #if PLATFORM(IOS_FAMILY) 290 // Make sure we have an IPC::Connection before creating the ProcessTaskStateObserver since it may call 291 // WebProcess::processTaskStateDidChange() on a background thread and deference the IPC connection. 292 m_taskStateObserver = ProcessTaskStateObserver::create(*this); 293 #endif 293 294 } 294 295 -
trunk/Source/WebKit/WebProcess/WebProcess.h
r255178 r255189 67 67 #endif 68 68 69 #if PLATFORM(IOS_FAMILY) 70 #include "ProcessTaskStateObserver.h" 71 OBJC_CLASS BKSProcessAssertion; 72 #endif 73 69 74 #if PLATFORM(WAYLAND) && USE(WPE_RENDERER) 70 75 #include <WebCore/PlatformDisplayLibWPE.h> … … 102 107 namespace WebKit { 103 108 104 class DependencyProcessAssertion;105 109 class EventDispatcher; 106 110 class GamepadData; … … 138 142 #endif 139 143 140 class WebProcess : public AuxiliaryProcess 144 class WebProcess 145 : public AuxiliaryProcess 146 #if PLATFORM(IOS_FAMILY) 147 , ProcessTaskStateObserver::Client 148 #endif 141 149 { 142 150 WTF_MAKE_FAST_ALLOCATED; … … 481 489 482 490 #if PLATFORM(IOS_FAMILY) 491 void processTaskStateDidChange(ProcessTaskStateObserver::TaskState) final; 483 492 bool shouldFreezeOnSuspension() const; 484 493 void updateFreezerStatus(); 494 495 void releaseProcessWasResumedAssertions(); 485 496 #endif 486 497 … … 569 580 #if PLATFORM(IOS_FAMILY) 570 581 WebSQLiteDatabaseTracker m_webSQLiteDatabaseTracker; 571 std::unique_ptr<DependencyProcessAssertion> m_uiProcessDependencyProcessAssertion; 582 RefPtr<ProcessTaskStateObserver> m_taskStateObserver; 583 Lock m_processWasResumedAssertionsLock; 584 RetainPtr<BKSProcessAssertion> m_processWasResumedUIAssertion; 585 RetainPtr<BKSProcessAssertion> m_processWasResumedOwnAssertion; 572 586 #endif 573 587 -
trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm
r255119 r255189 93 93 #import "AccessibilitySupportSPI.h" 94 94 #import "AssertionServicesSPI.h" 95 #import "RunningBoardServicesSPI.h"96 95 #import "UserInterfaceIdiom.h" 97 96 #import "WKAccessibilityWebPageObjectIOS.h" … … 342 341 343 342 #if PLATFORM(IOS_FAMILY) 343 void WebProcess::processTaskStateDidChange(ProcessTaskStateObserver::TaskState taskState) 344 { 345 // NOTE: This will be called from a background thread. 346 RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processTaskStateDidChange() - taskState(%d)", this, taskState); 347 if (taskState != ProcessTaskStateObserver::Running) 348 return; 349 350 LockHolder holder(m_processWasResumedAssertionsLock); 351 if (m_processWasResumedUIAssertion && m_processWasResumedOwnAssertion) 352 return; 353 354 // We were awakened from suspension unexpectedly. Notify the WebProcessProxy, but take a process assertion on our parent PID 355 // to ensure that it too is awakened. 356 RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processTaskStateChanged() Taking 'WebProcess was resumed' assertion on behalf on UIProcess", this); 357 m_processWasResumedUIAssertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:parentProcessConnection()->remoteProcessID() flags:BKSProcessAssertionPreventTaskSuspend reason:BKSProcessAssertionReasonFinishTask name:@"WebProcess was resumed" withHandler:^(BOOL acquired) { 358 if (!acquired) 359 RELEASE_LOG_ERROR(ProcessSuspension, "%p - WebProcess::processTaskStateDidChange() failed to take 'WebProcess was resumed' assertion for parent process", this); 360 }]); 361 m_processWasResumedUIAssertion.get().invalidationHandler = [this] { 362 RELEASE_LOG_ERROR(ProcessSuspension, "%p - WebProcess::processTaskStateChanged() Releasing 'WebProcess was resumed' assertion on behalf on UIProcess due to invalidation", this); 363 releaseProcessWasResumedAssertions(); 364 }; 365 m_processWasResumedOwnAssertion = adoptNS([[BKSProcessAssertion alloc] initWithPID:getpid() flags:BKSProcessAssertionPreventTaskSuspend reason:BKSProcessAssertionReasonFinishTask name:@"WebProcess was resumed" withHandler:^(BOOL acquired) { 366 if (!acquired) 367 RELEASE_LOG_ERROR(ProcessSuspension, "%p - WebProcess::processTaskStateDidChange() failed to take 'WebProcess was resumed' assertion for WebContent process", this); 368 }]); 369 m_processWasResumedOwnAssertion.get().invalidationHandler = [this] { 370 RELEASE_LOG_ERROR(ProcessSuspension, "%p - WebProcess::processTaskStateChanged() Releasing 'WebProcess was resumed' assertion on behalf on WebContent process due to invalidation", this); 371 releaseProcessWasResumedAssertions(); 372 }; 373 374 parentProcessConnection()->sendWithAsyncReply(Messages::WebProcessProxy::ProcessWasResumed(), [this] { 375 RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processTaskStateDidChange() Parent process handled ProcessWasResumed IPC, releasing our assertions", this); 376 releaseProcessWasResumedAssertions(); 377 }); 378 } 379 380 void WebProcess::releaseProcessWasResumedAssertions() 381 { 382 LockHolder holder(m_processWasResumedAssertionsLock); 383 if (m_processWasResumedUIAssertion) { 384 RELEASE_LOG(ProcessSuspension, "%p - WebProcess::releaseProcessWasResumedAssertions() Releasing parent process 'WebProcess was resumed' assertion", this); 385 [m_processWasResumedUIAssertion invalidate]; 386 m_processWasResumedUIAssertion = nullptr; 387 } 388 if (m_processWasResumedOwnAssertion) { 389 RELEASE_LOG(ProcessSuspension, "%p - WebProcess::releaseProcessWasResumedAssertions() Releasing WebContent process 'WebProcess was resumed' assertion", this); 390 [m_processWasResumedOwnAssertion invalidate]; 391 m_processWasResumedOwnAssertion = nullptr; 392 } 393 } 394 395 #endif 396 397 #if PLATFORM(IOS_FAMILY) 344 398 static NSString *webProcessLoaderAccessibilityBundlePath() 345 399 { -
trunk/WebKitLibraries/ChangeLog
r254348 r255189 1 2020-01-27 Chris Dumez <cdumez@apple.com> 2 3 Unreviewed, revert r253984 as it appears to be causing assertion leaks. 4 https://bugs.webkit.org/show_bug.cgi?id=205687 5 6 * WebKitPrivateFrameworkStubs/iOS/13/RunningBoardServices.framework/RunningBoardServices.tbd: Removed. 7 1 8 2020-01-10 Jonathan Bedard <jbedard@apple.com> 2 9
Note: See TracChangeset
for help on using the changeset viewer.