I am building an Android app which in the latest version has a lot of crash reports like the following one on google play dash. It consists of several libraries cross compiled with android-ndk.
Starting from frame #05 it halfway makes sense to me. What I wonder is how to go for the other half and what to make from the upper frames.
Trace:
#00 pc 0000000000083134 /apex/com.android.runtime/lib64/bionic/libc.so (abort+160)
#01 pc 000000000017cf00 /data/app/[...]==/lib/arm64/libqca-qt5_arm64-v8a.so
#02 pc 000000000017d070 /data/app/[...]==/lib/arm64/libqca-qt5_arm64-v8a.so
#03 pc 0000000000179f48 /data/app/[...]==/lib/arm64/libqca-qt5_arm64-v8a.so
#04 pc 0000000000179850 /data/app/[...]==/lib/arm64/libqca-qt5_arm64-v8a.so (__cxa_rethrow+196)
#05 pc 0000000000c0e10c /data/app/[...]==/lib/arm64/libqgis_core_arm64-v8a.so (QgsCoordinateTransform::transformInPlace(double&, double&, double&, QgsCoordinateTransform::TransformDirection) const+300)
#06 pc 00000000000340d8 /data/app/[...]==/lib/arm64/libqfield_qgsquick_arm64-v8a.so (QgsQuickCoordinateTransformer::updatePosition()+136)
#07 pc 0000000000034350 /data/app/[...]==/lib/arm64/libqfield_qgsquick_arm64-v8a.so (QgsQuickCoordinateTransformer::setDestinationCrs(QgsCoordinateReferenceSystem const&)+176)
#08 pc 0000000000028488 /data/app/[...]==/lib/arm64/libqfield_qgsquick_arm64-v8a.so
#09 pc 0000000000028a18 /data/app/[...]==/lib/arm64/libqfield_qgsquick_arm64-v8a.so (QgsQuickCoordinateTransformer::qt_metacall(QMetaObject::Call, int, void**)+316)
#10 pc 00000000002f36a8 /data/app/[...]==/lib/arm64/libQt5Qml_arm64-v8a.so (QV4::QQmlValueTypeWrapper::write(QObject*, int) const+180)
What I know: QgsCoordinateTransform::transformInPlace
can throw a QgsCsException
which is caught and handled inside updatePosition()
.
try
{
mCoordinateTransform.transformInPlace( x, y, z );
}
catch ( const QgsCsException &exp )
{
QgsDebugMsg( exp.what() );
}
Given that it's handled I'm not sure how that's related to a crash, nonetheless I think it could be interesting information.
What I can't make sense of is how libqca-qt5
comes into play, this is never used inside transformInPlace
. Might it have some magic in place to handle unhandled exceptions (Can something be extracted from __cxa_rethrow
)?
The only idea that comes to my mind is that it's not a QgsCsException
but another (unhandled) exception that's raised and causes the crash. This would be an easy fix, but since I'm not able to reproduce this and all I have is this stack trace here and the only way to test is to ship a new apk and wait for reports to come in. This is a long roundtrip for feedback, so I'm very interested in either getting things right directly or at least improving the debug possibilities to fix it in two rounds.
So the question: what can be read from a stack trace like this and how to go about debugging this?
After having received feedback from a user about how exactly to reproduce this crash, it was possible to resolve this with the confidence of a positive test.
As assumed, it was a different exception raised by another library which was called from within transformInPlace()
.
Adding the following line fixed the crash and helped at least as a band aid.
try
{
mCoordinateTransform.transformInPlace( x, y, z );
}
catch ( const QgsCsException &exp )
{
QgsDebugMsg( exp.what() );
}
catch ( ... )
{
QgsDebugMsg( "Unknown exception caught" );
}
It is still unclear to me, how qca is involved in this stack trace. And if there is any code to handle unhandled exceptions or if it is just a random library defining some symbols or if there are other mechanisms at play. I assume __cxa_rethrow
plays a role, after all it's related to exception handling. I'd still be happy if someone could shed some light. Meanwhile, for future readers, it's good to know that adding a catch all clause is a feasible approach here.