Native Library Timeout Exception Android

Hi

Any assistance with the possible causes of the below crash I am seeing in my firebase logs would be much appreciated, I unfortunately have not replicated it locally.

Couchbase lite Android: 3.1.6
Android Version: 11

Fatal Exception: java.util.concurrent.TimeoutException: com.couchbase.lite.internal.core.C4Query.finalize() timed out after 10 seconds
       at com.couchbase.lite.internal.core.impl.NativeC4Query.free(NativeC4Query.java)
       at com.couchbase.lite.internal.core.impl.NativeC4Query.nFree(NativeC4Query.java:51)
       at com.couchbase.lite.internal.core.C4Query$$ExternalSyntheticLambda2.accept(:8)
       at com.couchbase.lite.internal.core.C4NativePeer.releasePeer(C4NativePeer.java:195)
       at com.couchbase.lite.internal.core.C4NativePeer.releasePeer(C4NativePeer.java:167)
       at com.couchbase.lite.internal.core.C4Query.closePeer(C4Query.java:139)
       at com.couchbase.lite.internal.core.C4Query.finalize(C4Query.java:131)
       at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:291)
       at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:278)
       at java.lang.Daemons$Daemon.run(Daemons.java:139)
       at java.lang.Thread.run(Thread.java:923)

and

Fatal Exception: java.util.concurrent.TimeoutException: com.couchbase.lite.internal.core.C4QueryEnumerator.finalize() timed out after 10 seconds
       at com.couchbase.lite.internal.core.impl.NativeC4QueryEnumerator.free(NativeC4QueryEnumerator.java)
       at com.couchbase.lite.internal.core.impl.NativeC4QueryEnumerator.nFree(NativeC4QueryEnumerator.java:28)
       at com.couchbase.lite.internal.core.C4QueryEnumerator$$ExternalSyntheticLambda0.accept(:8)
       at com.couchbase.lite.internal.core.C4NativePeer.releasePeer(C4NativePeer.java:195)
       at com.couchbase.lite.internal.core.C4NativePeer.releasePeer(C4NativePeer.java:167)
       at com.couchbase.lite.internal.core.C4QueryEnumerator.closePeer(C4QueryEnumerator.java:137)
       at com.couchbase.lite.internal.core.C4QueryEnumerator.finalize(C4QueryEnumerator.java:112)
       at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:291)
       at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:278)
       at java.lang.Daemons$Daemon.run(Daemons.java:139)
       at java.lang.Thread.run(Thread.java:923)

I am also able to privately share a dump of all the threads if that will help things.

There is an internal issue CBSE-9214 that shows a similar stack trace.

My understanding from that issue is that the timeout will be avoided if the application always closes the result set of a query :


ResultSet rs = query.execute();
//  ...
rs.close();

... or, better yet:

try (ResultSet rs = query.execute()) {
    //  ...
}

Thank you so much for the quick response!
I will make that update and roll out asap, fingers crossed it resolves the problem.

Yeah… I confirm that @mreiche has it just right.

As with most Java Autocloseables, CBL takes a belt-and-suspenders approach. If you don’t close the Autocloseable (and you SHOULD close any Autocloseable!!!) we try to prevent memory leaks by closing the object from a finalizer. In this case, the finalizer has to seize a lock on the associated database. If there are, for instance, long running queries, executing at the same time, the finalizer will not be able to seize the lock and will time out.

The obvious solution is to close the ResultSet, explicitly. Be warned, though, that if you attempt to use any of the contents of the ResultSet (a Result, or any object – Dictionary, Array, etc – obtained from the Result, after you close the ResultSet, you are likely to cause a native crash.

While the above describes a perfectly legit solution I believe both things – the finalizer failure and the native crash on use after close – are user traps. I have plans to improve both things in future releases.

1 Like