New issue
Advanced search Search tips

Issue 804521 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Jan 2018
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 2
Type: Bug

Blocking:
issue 469376



Sign in to add a comment

org.chromium.chrome.browser.sync.FirstRunTest#testNoSignIn fails on ToTAndroidCFI due to race condition

Project Member Reported by p...@chromium.org, Jan 22 2018

Issue description

The test case org.chromium.chrome.browser.sync.FirstRunTest#testNoSignIn consistently fails on ToTAndroidCFI with an UnsatisfiedLinkError, e.g.

https://logs.chromium.org/v/?s=chromium%2Fbb%2Fchromium.clang%2FToTAndroidCFI%2F935%2F%2B%2Frecipes%2Fsteps%2Fchrome_sync_shell_test_apk_on_Android%2F0%2Flogs%2Forg.chromium.chrome.browser.sync.FirstRunTest_testNoSignIn%2F0

I believe that this is because the additional CFI instrumentation causes the native library to take longer to initialize, which exposes a race between the registration of JNI functions and the call to ProfileSyncService.nativeInit.

If I add code that causes the test to wait for the library to be initialized before calling nativeInit:

diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
index 3744e4b8b106..587710381a77 100644
--- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
+++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
@@ -13,6 +13,8 @@ import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.library_loader.LibraryLoader;
+import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.chrome.browser.ChromeActivity;
 import org.chromium.chrome.browser.identity.UniqueIdentificationGenerator;
 import org.chromium.chrome.browser.identity.UniqueIdentificationGeneratorFactory;
@@ -210,6 +212,8 @@ public class SyncTestRule extends ChromeActivityTestRule<ChromeActivity> {
 
                 setUpMockAndroidSyncSettings();
 
+                LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER).ensureInitialized();
+
                 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
                     @Override
                     public void run() {

there is still a race, but this one is between the ProfileSyncServiceAndroid ctor and the code that initializes g_browser_process (I get a "Browser process or profile manager not initialized" assertion failure, and if I change the ctor like this:

diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc
index 751df64cb5e8..16f580382c32 100644
--- a/chrome/browser/sync/profile_sync_service_android.cc
+++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -84,9 +84,14 @@ ProfileSyncServiceAndroid::ProfileSyncServiceAndroid(JNIEnv* env, jobject obj)
     : profile_(nullptr),
       sync_service_(nullptr),
       weak_java_profile_sync_service_(env, obj) {
-  if (g_browser_process == nullptr ||
-      g_browser_process->profile_manager() == nullptr) {
-    NOTREACHED() << "Browser process or profile manager not initialized";
+  //sleep(1);
+  if (g_browser_process == nullptr) {
+    NOTREACHED() << "Browser process not initialized";
+    return;
+  }
+
+  if (g_browser_process->profile_manager() == nullptr) {
+    NOTREACHED() << "profile manager not initialized";
     return;
   }
 
it becomes "Browser process not initialized").

I can get the assertion failure to go away by adding a sleep to the Java code that calls nativeInit, i.e.

diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java
index 5e084f28caf4..359a22a191d3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java
@@ -129,6 +129,7 @@ public class ProfileSyncService {
     protected void init() {
         ThreadUtils.assertOnUiThread();
 
+        //try { Thread.sleep(1000); } catch (Exception e) {}
         // This may cause us to create ProfileSyncService even if sync has not
         // been set up, but ProfileSyncService::Startup() won't be called until
         // credentials are available.

but adding a sleep to the C++ code (i.e. the commented sleep call in profile_sync_service_android.cc) doesn't help.

I really have no idea how these tests are supposed to wait for things to be initialized, so I'd like someone who is more familiar with Chrome on Android to take a look.
 
Cc: -agrieve@chromium.org
Owner: agrieve@chromium.org
I'll take a stab at it.
Project Member

Comment 2 by bugdroid1@chromium.org, Jan 24 2018

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

commit 389df5d413d879a2e5d622c9b234a92634770e87
Author: Andrew Grieve <agrieve@chromium.org>
Date: Wed Jan 24 20:24:31 2018

Fix race condition in FirstRunTest.

Test was waiting for activity to be created, but not for native
initialization to complete.

Bug:  804521 
Change-Id: I5964546bdb4178f26fd60940443ecb9493e76912
Reviewed-on: https://chromium-review.googlesource.com/882942
Reviewed-by: Yaron Friedman <yfriedman@chromium.org>
Commit-Queue: agrieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/master@{#531660}
[modify] https://crrev.com/389df5d413d879a2e5d622c9b234a92634770e87/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
[modify] https://crrev.com/389df5d413d879a2e5d622c9b234a92634770e87/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java

Status: Fixed (was: Available)

Sign in to add a comment