从版本堆栈跟踪中定位异常

时间:2019-03-29 16:52:09

标签: c# debugging xamarin.android async-await

我有一个Xamarin Android应用程序,该应用程序已部署到测试仪,该应用程序间歇性崩溃。当应用程序具有未处理的异常时,我会记录堆栈跟踪,但是我很难从跟踪中找到崩溃的源头。我找到了这篇关于在发布版本堆栈跟踪中获取文件名/行号的文章,并在我的代码(https://developer.xamarin.com/releases/android/xamarin.android_6/xamarin.android_6.1/#Release_Stack_Traces)中实现了它。注意我确实必须将调试信息选项更改为“ Full”,以获取生成msym目录的生成过程。

我通过向我的应用程序添加一个引发未处理异常的按钮来测试功能。如预期的那样,我能够使用单符号实用程序从报告的堆栈跟踪中确定异常的来源。

我注意到msym文件夹的内容是随机命名的,因此在重建应用程序后,我部署了新版本并保存在msym目录之外。以下是我从崩溃报告中收到的堆栈跟踪。

Object reference not set to an instance of an object

 at MyApp.Droid.Dashboard.DashboardActivity+<OnResume>d__18.MoveNext () [0x0003b] in <e3858b3570dd4244985ab7c8da45615a>:0 \n--- End of stack trace from previous location where exception was thrown ---\n 
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <151302d8db184dfd9dfbf4e0ac550df9>:0 \n 
 at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in <151302d8db184dfd9dfbf4e0ac550df9>:0 \n 
 at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <c8c020c6a36f47959fcbe54313f43792>:0 \n 
 at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <c8c020c6a36f47959fcbe54313f43792>:0 \n 
 at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <c8c020c6a36f47959fcbe54313f43792>:0 \n 
 at (wrapper dynamic-method) System.Object.452a73e4-d2f9-4ade-a6c1-b8346138dd0d(intptr,intptr)","reportType":"UHELogEntry","timestamp_ticks":636894071182040326}

但是,当我在上面的跟踪中运行mono-symbolicate实用程序时,该实用程序抱怨以下警告。

    Warning: MVID directory does not exist: .\e3858b3570dd4244985ab7c8da45615a

很容易看出异常来自DashboardActivity的OnResume方法(请参见下文)。但是,有几种可能的异常源,但是似乎都没有,所以我想在进行多次野鹅追逐之前更好地了解异常的来源。

protected override async void OnResume()
{
    base.OnResume();
    var provider = KernelBuilder.KERNEL.Get<ServiceProvider>();
    await provider.initializationTask;

    _service = provider.getService();
    Log.Debug(TAG, string.Format("OnResume, post service assignment", "Service: " + (_service?.ToString() ?? "null")));

    var wrapper = new ExerciseServiceWrapper(_service, null);
    _connectionView.Setup(wrapper, _service.userSetupHardware);

    _service?.stopRecordingSession();
    LibITagAndroid.ContinuousITagClickSrc.instance.stop();
}

我的问题如下:

  1. 为什么单符号工具无法将堆栈跟踪信息转换为文件/行号?
  2. 是否可以使用堆栈跟踪顶部的方法名称中编码的信息(MyApp.Droid.Dashboard.DashboardActivity + d__18.MoveNext)来缩小异常的来源?似乎d__18后缀可以指示异常是在调用await provider.initializationTask之前还是之后发生的,但是我没有找到任何有助于我理解此后缀的东西。

其他观察:

我注意到,如果将调试信息设置为“ Full”并禁用“ Optimize Code”,则会在测试异常但不是OnResume函数中发生的异常的堆栈跟踪中报告文件路径/行号。这使我认为这是在“特殊”某处发生的,provider.initializationTask为空?

谢谢!

约翰

0 个答案:

没有答案