New issue
Advanced search Search tips

Issue 888555 link

Starred by 2 users

Issue metadata

Status: Fixed
Owner:
Closed: Oct 23
Cc:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

Potential jank caused by ReadErrorAssistantProtoFromResourceBundle

Project Member Reported by etienneb@chromium.org, Sep 24

Issue description

Slow-reports are sent back when jank is detected on main thread.

The following reports show a common jank with the same stackframe.


Reports (see attachments):
  c7be69bf9592fb94
  51807c8f025abf8d
  0f8646c082f79310
  ee965cc4c578e70d


Stackframe:

chrome_browser_ssl::SSLErrorAssistantConfig::MergePartialFromCodedStream(google::protobuf::io::CodedInputStream *)
google::protobuf::`anonymous namespace'::InlineMergeFromCodedStream
google::protobuf::MessageLite::ParseFromZeroCopyStream(google::protobuf::io::ZeroCopyInputStream *)
`anonymous namespace'::ReadErrorAssistantProtoFromResourceBundle
SSLErrorAssistant::SetErrorAssistantProto(std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig,std::default_delete<chrome_browser_ssl::SSLErrorAssistantConfig> >)
SSLErrorHandler::SetErrorAssistantProto(std::unique_ptr<chrome_browser_ssl::SSLErrorAssistantConfig,std::default_delete<chrome_browser_ssl::SSLErrorAssistantConfig> >)
<aliased> base::internal::Invoker<base::internal::BindState<void (*)(std::unique_ptr<(anonymous namespace)::AfterStartupTask,std::default_delete<(anonymous namespace)::AfterStartupTask> >),std::unique_ptr<(anonymous namespace)::AfterStartupTask,std::default_delete<(anonymous namespace)::AfterStartupTask> > >,void ()>::RunOnce
base::debug::TaskAnnotator::RunTask(char const *,base::PendingTask *)
base::MessageLoop::RunTask(base::PendingTask *)
base::MessageLoop::DoWork()
base::MessagePumpForUI::DoRunLoop()
base::MessagePumpWin::Run(base::MessagePump::Delegate *)
base::RunLoop::Run()
ChromeBrowserMainParts::MainMessageLoopRun(int *)
content::BrowserMainLoop::RunMainMessageLoopParts()
content::BrowserMainRunnerImpl::Run()
content::BrowserMain(content::MainFunctionParams const &)
content::RunBrowserProcessMain(content::MainFunctionParams const &,content::ContentMainDelegate *)
content::ContentMainRunnerImpl::Run(bool)
service_manager::Main(service_manager::MainParams const &)
content::ContentMain(content::ContentMainParams const &)
ChromeMain
MainDllLoader::Launch(HINSTANCE__ *,base::TimeTicks)
wWinMain
__scrt_common_main_seh
kernel32.dll
ntdll.dll
 
onError_ssl1.png
13.5 KB View Download
onError_ssl2.png
13.8 KB View Download
onError_ssl3.png
14.0 KB View Download
onError_ssl4.png
12.7 KB View Download
Labels: Hotlist-SamplingProfilerInField Performance-Browser
The jank is caused by SSLErrorAssistant::SetErrorAssistantProto

https://cs.chromium.org/chromium/src/chrome/browser/ssl/ssl_error_assistant.cc?type=cs&l=335

With the following code:

  if (!error_assistant_proto_) {
    // If the user hasn't seen an SSL error and a component update is available,
    // the local resource bundle won't have been read and error_assistant_proto_
    // will be null. It's possible that the local resource bundle has a higher
    // version_id than the component updater component, so load the local
    // resource bundle once to compare versions.
    // TODO(meacer): Ideally, ReadErrorAssistantProtoFromResourceBundle should
    // only be called once and not on the UI thread. Move the call to the
    // component updater component.
    error_assistant_proto_ = ReadErrorAssistantProtoFromResourceBundle();
  }
Cc: carlosil@chromium.org agl@chromium.org
 Issue 868383  has been merged into this issue.
The code on c2 is there to be sure the version reported by the component updater is not older than the local bundled version. But, unfortunately, the parsing (ReadErrorAssistantProtoFromResourceBundle) is done when calling SetErrorAssistantProto. The load should be (somehow) done before, on the component installer thread before going back to the UI thread.

Unfortunately, that will implies to add synchronization.
Cc: etienneb@chromium.org
 Issue 867972  has been merged into this issue.
> Unfortunately, that will implies to add synchronization.

We can get around this by just returning early if the assistant is not yet ready. SSL Error Assistant works on a best-effort basis, so missing these cases on startup isn't critical.

I was able to lift-out the read from the resource bundle to the component updater. 

The component updater will:
  * Unpack and load the proto from the component
  * Read the local error assistant in the resource bundle
  * Chose the most recent one
  * Set it as the error assistant.

As far as I get, the only place where we need to choose for a more recent version was from the component updater.

There are still a corner case when:
  1) user is having an SSL error
     -> The error assistant got loaded
  2) The component updater is ready
     -> Unpack the component
     -> Read the resource bundle assistant  *** Twice, since already loaded
     -> Choose and set

I don't see the potential double read as an issue since it's on rare error case.
Project Member

Comment 8 by bugdroid1@chromium.org, Oct 5

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/df6d38587a2fe5ad2649469822d70c666d938589

commit df6d38587a2fe5ad2649469822d70c666d938589
Author: Siddhartha <ssid@chromium.org>
Date: Fri Oct 05 14:34:28 2018

Move out load of bundled assistant proto to the component updater

This CL is moving lifting out the loading from the resource bundle to
the corresponding 'ssl_error_assistant_component'.

The previous implementation was loading on-demand the bundled proto
when needed. But, when the 'ssl_error_assistant_component' is ready, it's
setting the received proto. As no SSL error occured, the bundled proto is
not loaded and must be loaded on the UI thread.

This is causing jank on the UI thread. Which can be seen on the  bug 888555 .

The current proposition is to keep the bundle loading on-demand since
error paths are not the common ones. But, for the
'ssl_error_assistant_component' path we proposed to also read the bundled
proto and choose the most recent one before sending it to the error
assistant on the UI thread.

That way, most of the job is done before getting on the UI thread.

NOTE: ReadErrorAssistantProtoFromResourceBundle is thread safe and can be
executed on any thread. It can also be executed twice.

R=fdoray@chromium.org, meacer@chromium.org
CC=carlosil@chromium.org, agl@chromium.org

Bug:  888555 
Change-Id: Icd994f93c849b3c4d8b01d7921dff69f571397a8
Reviewed-on: https://chromium-review.googlesource.com/c/1247025
Commit-Queue: Etienne Bergeron <etienneb@chromium.org>
Reviewed-by: François Doray <fdoray@chromium.org>
Reviewed-by: Sorin Jianu <sorin@chromium.org>
Reviewed-by: Mustafa Emre Acer <meacer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#597109}
[modify] https://crrev.com/df6d38587a2fe5ad2649469822d70c666d938589/chrome/browser/component_updater/ssl_error_assistant_component_installer.cc
[modify] https://crrev.com/df6d38587a2fe5ad2649469822d70c666d938589/chrome/browser/ssl/captive_portal_helper_android.cc
[modify] https://crrev.com/df6d38587a2fe5ad2649469822d70c666d938589/chrome/browser/ssl/ssl_browsertest.cc
[modify] https://crrev.com/df6d38587a2fe5ad2649469822d70c666d938589/chrome/browser/ssl/ssl_error_assistant.cc
[modify] https://crrev.com/df6d38587a2fe5ad2649469822d70c666d938589/chrome/browser/ssl/ssl_error_assistant.h
[modify] https://crrev.com/df6d38587a2fe5ad2649469822d70c666d938589/chrome/browser/ssl/ssl_error_handler.cc
[modify] https://crrev.com/df6d38587a2fe5ad2649469822d70c666d938589/chrome/browser/ssl/ssl_error_handler_unittest.cc

Owner: etienneb@chromium.org
Let keep eyes on this, it should be solved by now.
Status: Fixed (was: Untriaged)

Sign in to add a comment