如何使用 __cxa_rethrow 调试 Android 堆栈跟踪

How to debug an Android stack trace with __cxa_rethrow

我正在构建一个 Android 应用程序,该应用程序在最新版本中有很多崩溃报告,例如 google play dash 上的崩溃报告。它由几个使用 android-ndk.

交叉编译的库组成

从第 05 帧开始,它对我来说中途有意义。我想知道的是如何去另一半以及从上面的框架中制作什么。

跟踪:

  #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)

我所知道的:QgsCoordinateTransform::transformInPlace 可以抛出一个 QgsCsException 并在 updatePosition() 中捕获和处理。

  try
  {
    mCoordinateTransform.transformInPlace( x, y, z );
  }
  catch ( const QgsCsException &exp )
  {
    QgsDebugMsg( exp.what() );
  }

鉴于它已得到处理,我不确定这与崩溃有何关系,但我认为这可能是有趣的信息。

我无法理解的是 libqca-qt5 是如何发挥作用的,这在 transformInPlace 中从未使用过。它可能有一些魔法来处理未处理的异常(可以从 __cxa_rethrow 中提取一些东西)吗?

我想到的唯一想法是它不是 QgsCsException 而是引发并导致崩溃的另一个(未处理的)异常。这将是一个简单的修复,但由于我无法重现这个,我所拥有的只是这里的堆栈跟踪,唯一的测试方法是发布一个新的 apk 并等待报告进来。这是一个很长的过程反馈的往返,所以我非常有兴趣直接把事情做好,或者至少提高调试的可能性,在两轮中修复它。

所以问题是:可以从这样的堆栈跟踪中读取什么以及如何调试它?

在收到用户关于如何准确重现此崩溃的反馈后,有信心通过积极的测试解决此问题。

正如假设的那样,这是从 transformInPlace() 中调用的另一个库引发的不同异常。

添加以下行修复了崩溃并至少起到了创可贴的作用。

  try
  {
    mCoordinateTransform.transformInPlace( x, y, z );
  }
  catch ( const QgsCsException &exp )
  {
    QgsDebugMsg( exp.what() );
  }
  catch ( ... )
  {
    QgsDebugMsg( "Unknown exception caught" );
  }

我仍然不清楚 qca 如何参与此堆栈跟踪。如果有任何代码可以处理未处理的异常,或者它只是一个定义一些符号的随机库,或者是否有其他机制在起作用。我假设 __cxa_rethrow 起作用,毕竟它与异常处理有关。如果有人能阐明一些问题,我仍然会很高兴。同时,对于未来的读者来说,很高兴知道在这里添加一个 catch all 子句是一种可行的方法。