如何调查 Xamarin/libmonosgen-2.0.so 本机崩溃?

How to investigate Xamarin/libmonosgen-2.0.so native crash?

我的最新版本崩溃率约为每 1000 台设备 99 次——明显高于之前的版本。 libmonosgen 中有两种新的崩溃:

集群 1:libmonosgen-2.0.so

signal 11 (SIGSEGV), code 2 (SEGV_ACCERR)
libmonosgen-2.0.so

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.dailybits.foodjournal <<<

backtrace:
  #00  pc 0000000000192304  /data/app/com.dailybits.foodjournal-KapbLS3Zx20G2S79yI3CTw==/lib/arm/libmonosgen-2.0.so

集群 2:libmonosgen-2.0.so (mono_class_get_flags)

signal 11 (SIGSEGV), code 2 (SEGV_ACCERR)
mono_class_get_flags
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.dailybits.foodjournal <<<

backtrace:
  #00  pc 000000000014f310  /data/app/com.dailybits.foodjournal-rwLqwfyotHI-Ulk481Wk8g==/lib/arm64/libmonosgen-2.0.so (mono_class_get_flags)

预发布报告看起来全是绿色,App Center 有 none 这些崩溃,它们只出现在 Google Play 中。

问题:

  1. 有谁知道pid:0和tid:0是什么意思?这是否意味着这些崩溃是在加载应用程序代码之前发生的,还是无关的?

  2. 如果这不是在应用程序启动时发生的,我能以某种方式在崩溃发生多长时间后找出来吗?或者更好的是,我可以将崩溃与应用程序生成的会话日志相关联吗?

  3. 有没有办法配置Play,或者App来收集更好的痕迹?

配置详情如下

(两个构建选项似乎都会导致相同的问题)

版本信息

Microsoft Visual Studio Professional 2019
Version 16.4.2
VisualStudio.16.Release/16.4.2+29613.14
Microsoft .NET Framework
Version 4.8.03752

Xamarin   16.4.000.307 (d16-4@e031886)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android SDK   10.1.1.0 (d16-4/f2c9364)
Xamarin.Android Reference Assemblies and MSBuild support.
    Mono: bef1e63
    Java.Interop: xamarin/java.interop/d16-4@c4e569f
    ProGuard: xamarin/proguard/master@905836d
    SQLite: xamarin/sqlite/3.28.0@46204c4
    Xamarin.Android Tools: xamarin/xamarin-android-tools/master@9f4ed4b

编辑 2/17/2020

我迄今为止的一些调查:

  1. 看起来 libmonosgen 包含 Xamarin 垃圾收集器。
  2. SEGV_ACCERR 是对平台对象(已处理的 IE 对象)的访问被拒绝。获得这些的一个好方法显然是从多个线程访问静态对象。我认为这可能意味着其中一个线程在不告知 Mono 运行时的情况下处理底层 Java 对象。
  3. 第三方库以及新的 Java 对象(IE 更改为我正在使用的 UI 控件)是可疑的。

我决定仔细梳理所有更改,还原所有软件包更新,然后一个接一个地重新执行,直到发布开始崩溃。 如果我不走运,这将需要几周的时间,但应该可以找出导致崩溃的原因。它还应该允许我 100% 交付我的新功能,而不会为所有用户造成崩溃高峰。祈祷:)

经过大量研究(见问题底部),我决定从应用程序中删除 所有 更改,并开始将它们一一重新分发。幸运的是,就在我完成所有更改的详细梳理(来自 2 个月的工作)时,一位用户发布了 1 星评论,并附有详细的重现说明!

所以,"how to investigate crashes with no stack trace"问题的答案:

你必须找到一个复制品,找到一个的方法(对于生产版本)是等待你的用户告诉你。

其他在线问题的答案:

  1. 有谁知道pid:0和tid:0是什么意思?这是不是意味着这些 崩溃发生在应用程序代码加载之前,或者 那个不相关的?

    • 这意味着堆栈已损坏,进程和 tid 不再可用(是否意味着这是在启动时)。 IE Weird Native Crash - pid: 0, tid: 0 signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
  2. 如果这不是在应用程序启动时,我可以在多长时间后以某种方式找到 崩溃发生?或者更好的是,我可以将崩溃与应用关联起来吗? 生成的会话日志?

    • 我还没有找到添加到这些日志的方法,更好的方法是找到一个repro。
  3. 有没有办法配置Play,或者App采集比较好 痕迹?

    • 不适用于此类崩溃。

实际崩溃的详细信息/根本原因:

事实证明,自从我上次更新以来,我最喜欢的 PropertyChanged.Fody 和 Xamarin Forms 的行为发生了变化,以至于生成了比过去更多的 PropertyChanged 事件(IE,即使分配的值等于原始值,现在触发 "propertychanged" 事件)。

在我的一个更有趣的视图模型中(它根据来自输入控件的文本值进行自动单位转换),当与自定义控件结合使用时,这会导致无限递归。 (这意味着值会改变,这会触发 propertychanged 事件,这会更新控件,这会将值分配给 viewmodel,这会触发 propertychanged,等等...)

一旦我有了重现,调查和解决这个问题就变得微不足道了; 我能够通过使用 [DoNotNotify]

装饰其中一个属性来解决问题