diff --git a/xwords4/android/app/build.gradle b/xwords4/android/app/build.gradle index 92c526c22..ce175b4d3 100644 --- a/xwords4/android/app/build.gradle +++ b/xwords4/android/app/build.gradle @@ -70,6 +70,7 @@ android { resValue "string", "invite_prefix", "/and/" buildConfigField "int[]", "SMS_BANNED_EXPL", "null" buildConfigField "boolean", "UDP_ENABLED", "true" + buildConfigField "boolean", "REPORT_LOCKS", "false" } xw4 { @@ -104,6 +105,7 @@ android { buildConfigField "boolean", "WIDIR_ENABLED", "true" buildConfigField "boolean", "RELAYINVITE_SUPPORTED", "true" buildConfigField "String", "VARIANT_NAME", "\"Dev/Debug\"" + buildConfigField "boolean", "REPORT_LOCKS", "true" } xw4dNoSMS { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java index 5331827ba..0132d2a16 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java @@ -510,6 +510,7 @@ public class BoardDelegate extends DelegateBase m_activity = delegator.getActivity(); } + private static int s_noLockCount = 0; // supports a quick debugging hack protected void init( Bundle savedInstanceState ) { m_isFirstLaunch = null == savedInstanceState; @@ -544,7 +545,13 @@ public class BoardDelegate extends DelegateBase public void gotLock( GameLock lock ) { if ( null == lock ) { finish(); + if ( BuildConfig.REPORT_LOCKS && ++s_noLockCount == 3 ) { + String msg = "BoardDelegate unable to get lock; holder stack: " + + GameLock.getHolderStack( m_rowid ); + CrashTrack.logAndSend( msg ); + } } else { + s_noLockCount = 0; m_jniThreadRef = JNIThread.getRetained( lock ); // see http://stackoverflow.com/questions/680180/where-to-stop- \ diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameLock.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameLock.java index c482cb0fe..0e0620a5c 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameLock.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameLock.java @@ -64,7 +64,6 @@ public class GameLock implements AutoCloseable, Serializable { Owner() { mThread = Thread.currentThread(); - // mTrace = mThread.getStackTrace(); mTrace = android.util.Log.getStackTraceString(new Exception()); } @@ -361,6 +360,13 @@ public class GameLock implements AutoCloseable, Serializable { } ).start(); } + public static String getHolderStack( long rowid ) + { + GameLockState state = getFor( rowid ); + Owner owner = state.mOwners.peek(); + return owner.mTrace; + } + // used only for asserts public boolean canWrite() { diff --git a/xwords4/android/app/src/xw4/java/org/eehouse/android/xw4/CrashTrack.java b/xwords4/android/app/src/xw4/java/org/eehouse/android/xw4/CrashTrack.java index 5b1d90b1c..97af2f750 100644 --- a/xwords4/android/app/src/xw4/java/org/eehouse/android/xw4/CrashTrack.java +++ b/xwords4/android/app/src/xw4/java/org/eehouse/android/xw4/CrashTrack.java @@ -24,4 +24,5 @@ import android.content.Context; public class CrashTrack { public static void init( Context context ) {} // does nothing here + public static void logAndSend( String msg ) {} } diff --git a/xwords4/android/app/src/xw4d/java/org/eehouse/android/xw4/CrashTrack.java b/xwords4/android/app/src/xw4d/java/org/eehouse/android/xw4/CrashTrack.java index 0d2081b49..8d4521804 100644 --- a/xwords4/android/app/src/xw4d/java/org/eehouse/android/xw4/CrashTrack.java +++ b/xwords4/android/app/src/xw4d/java/org/eehouse/android/xw4/CrashTrack.java @@ -60,4 +60,19 @@ public class CrashTrack { } } } + + public static void logAndSend( String msg ) + { + Crashlytics.log( msg ); + new Thread( new Runnable() { + @Override + public void run() { + String foo = null; + try { + Thread.sleep( 5000 ); + throw new RuntimeException( "crash generator" ); + } catch ( InterruptedException ex ) {} + } + } ).start(); + } }