【问题标题】:How to debug an Android stack trace with __cxa_rethrow如何使用 __cxa_rethrow 调试 Android 堆栈跟踪
【发布时间】:2020-08-18 18:42:01
【问题描述】:

我正在构建一个 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 并等待报告进来。这很长往返反馈,所以我对直接把事情做对或至少改进调试可能性以在两轮中修复它非常感兴趣。

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

【问题讨论】:

  • 在投反对票之前,请提出有助于改进帖子的问题,谢谢 :-)
  • 我不知道你为什么被否决,这个问题对我来说看起来很可靠。除了如果我处于您的情况之外,我没有其他答案,我会尝试尽可能多地围绕该代码捕获日志,并为通用异常插入另一个捕获并将其记录下来,看看您能找到什么。如果无法在调试器中重现自己,您将受到日志文件的支配。

标签: android c++ exception crash abort


【解决方案1】:

在收到用户关于如何准确重现此崩溃的反馈后,可以放心地通过肯定测试来解决此问题。

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

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

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

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

【讨论】:

    猜你喜欢
    • 2021-09-28
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 2012-11-10
    相关资源
    最近更新 更多