收集和解释错误数据

每天将错误和事件数据上传到 Azure Sphere 安全服务。 有权访问特定目录的任何人都可以下载该目录的数据。 报表涵盖目录中的所有设备。

每个报告最多包含 1,000 个事件或 14 天的数据,以先到达者为准。 数据可以写入文件,也可以通过管道传输到脚本或应用程序。 CLI 只能返回 1,000 个事件。 使用 Azure Sphere 公共 API 指定页面上返回的最大事件数。

可以通过以下方式下载有关影响设备的错误和其他事件的数据:

不会从 RTApps 收集错误报告数据。 如果要记录来自 RTApps 的错误,则需要实现核心间通信,以将错误从 RTApps 传达给高级应用程序,以便将错误数据记录到网络服务。

可用数据类型

针对每个错误或事件返回的数据包括:

数据 描述
设备 ID 遇到事件的设备的 ID。
事件类型 事件是计划内还是计划外。 OS 和应用更新被视为计划内事件,而错误是计划外事件。
事件类 遇到事件的软件组件:OS 或应用程序。
事件计数 事件在以 StartTime 和 EndTime 分隔的时间段内发生的次数。
描述 有关事件的信息。 此字段是泛型字段,根据事件及其源而异。 对于应用程序,它可能包含退出代码、信号状态和信号代码,但字段的确切内容不是固定的。 这包含有关事件的信息,并且来自时间窗口中该事件的第一个匹配项。
开始时间 事件窗口开始) UTC (日期和时间。
结束时间 事件窗口结束) UTC (日期和时间。

“开始时间”和“结束时间”定义聚合事件数据的时间窗口。 任何聚合事件组的时段最长为 24 小时,最大为每个时间窗口出现 8 次。

应用程序事件

应用程序事件包括云加载的应用更新以及崩溃、退出和其他类型的应用程序故障。

应用程序更新是计划事件。 对于 AppUpdate 事件,“说明”字段包含 AppUpdate

应用程序崩溃、退出、启动失败和类似事件是计划外事件。 对于计划外事件,“说明”字段的内容取决于遇到该事件的应用程序。 下表列出了计划外事件的“说明”字段中可能存在的字段。

数据 描述
exit_status或exit_code 应用程序报告的退出状态或代码。
signal_status 描述崩溃的高级原因的整数,由 OS 返回。 可以在 Man 7 文档或其他 Linux 资源中找到状态列表。
signal_code 指示父信号状态中详细崩溃状态的整数。 有关详细信息,请参阅 Man 7 文档或其他 Linux 资源。
component_id 崩溃的软件组件的 GUID。
image_id 发生错误时正在运行的映像的 GUID。

AppCrash 说明中的特定信息取决于崩溃的根源。 对于大多数崩溃,说明如下所示:

AppCrash (exit_status=11; signal_status=11; signal_code=3; component_id=685f13af-25a5-40b2-8dd8-8cbc253ecbd8; image_id=7053e7b3-d2bb-431f-8d3a-173f52db9675)

在某些情况下,崩溃会触发其他错误数据,例如以下内容,这补充了上一示例中的数据:

AppCrash (pc=BEEED2EE; lr=BEEED2E5; sp=BEFFDE58; signo=11; errno=0; code=0; component_id=685f13af-25a5-40b2-8dd8-8cbc253ecbd8; pc_modulename+offset=appname+80000; lr_modulename+offset=app+100CC)

数据 描述
Pc 程序计数器。 指向触发崩溃的指令的地址。
Lr 链接注册。 可能指向调用函数中的返回地址。
Sp 堆栈指针。 指向调用堆栈的顶部。
signo POSIX 信号。 指示错误类型。
Errno POSIX errno。 指示错误。
代码 指示父信号状态中的详细崩溃状态。
component_id 崩溃的软件组件的 GUID。
pc_modulename+offset 模块的名称和包含发生崩溃的代码的模块中的偏移量。
lr_modulename+offset 模块的名称和模块中的偏移量可能是调用函数。

解释应用崩溃

可以在signal_status和signal_code中找到有关 AppCrash 的大多数信息。 请按照以下步骤操作:

  1. 使用 适用于signal_status的 Man 7 文档,首先查看标有“标准信号的信号编号”的表。在 x86/ARM 列中,在错误报告 csv中搜索分配给signal_status的值。 找到后,记下最左侧列中的相应 Signal 名称。
  2. 向上滚动到标有“标准信号”的表。匹配之前确定的信号名称,并使用表收集有关信号指示内容的详细信息。
  3. 在针对signal_code的 Man 7 文档和之前找到的 Signal 名称中,找到相应的si_codes列表。
  4. 使用错误报告 csv 文件中分配给signal_code的值来确定与错误消息匹配的代码。

例如,请考虑以下 AppCrash 说明:

AppCrash (exit_status=11; signal_status=11; signal_code=3; component_id=685f13af-25a5-40b2-8dd8-8cbc253ecbd8; image_id=7053e7b3-d2bb-431f-8d3a-173f52db9675)

使用 Man 7 文档,可以发现有关 AppCrash 的以下附加信息:

  1. 信号手册页说明的第 10 节介绍了 信号。 值 11 的signal_status对应于 SIGSEGV 信号。
  2. SIGSEGV 指示发生了无效的内存引用, (这通常是空指针) 。
  3. 每个signal_status的 SigAction 手册页 说明的第 3 节介绍了SI_Codes。 虽然页面未列出每个si_code的索引号,但可以从索引 1 开始的每个signal_status类别进行计数。 通过查看从索引 1) 开始的 SIGSEGV (si_codes列表,可以看到第三个匹配SEGV_BNDERR。
  4. SEGV_BNDERR指示发生了失败的地址绑定检查。

注意

经常遇到的 AppCrash 包含signal_status值 9(即 SIGKILL 信号)以及 SEND_SIG_PRIV si_code。 此状态表示 OS 终止了应用程序,因为它超出了其内存使用限制。 若要了解有关应用程序内存限制的详细信息,请参阅 高级应用程序中的内存使用

解释 AppExits

当应用在没有错误的情况下退出时,signal_status和signal_code字段不存在,并且说明包含退出代码,而不是exit_status:

AppExit (exit_code=0; component_id=685f13af-25a5-40b2-8dd8-8cbc253ecbd8; image_id=0a7cc3a2-f7c2-4478-8b02-723c1c6a85cd)

出现 AppExit 的原因有很多,例如应用程序更新、设备被拔出或者使用关闭 API 等。 请务必实现 退出代码 ,以便深入了解 AppExit 的原因。

若要解释 AppExits,请使用错误报告的“说明”字段中的 exit_code 值。 如果应用返回退出代码,则可以使用错误报告中exit_code的值来确定错误发生的位置或时间。 使用此值,在应用程序代码中搜索,以查看哪个退出代码消息对应于错误报告中提供的值。 然后,查找应用程序中的哪个函数返回了退出代码消息,以及它这样做的原因。 通过查看 return 语句及其上下文,可以发现错误的原因。

OS 事件

错误数据还包括基础 OS 和硬件事件,这些事件可能会导致应用程序失败或重启,从而影响应用程序。 此类事件可包括以下内容:

  • 内核错误导致的计划外设备重启
  • 云 OS 更新
  • 暂时性硬件问题

数据中包含 OS 事件,以帮助确定应用程序错误是 OS 或硬件问题的结果,还是反映应用程序本身的问题。 如果事件数据显示设备已启动到安全模式,则应用可能无法启动。

浏览错误数据

如果计划开发用于分析错误数据的脚本或工具,但没有大量可用于报告错误的设备,则可以使用 Azure Sphere 示例应用程序生成此类数据进行测试。 Azure Sphere 示例存储库中的 Tutorials/ErrorReporting 示例介绍了如何分析应用程序崩溃时报告的错误。 按照自述文件中的说明使用 Visual Studio、Visual Studio Code 或命令行生成示例

在没有调试器的情况下从命令行部署应用时,OS 会在每次失败时重启它。 聚合类似事件,以便一个经常发生故障的设备不会屏蔽其他设备的错误,并且每个时间窗口最多出现 8 次。 无需调试即可从命令行部署示例,如下所示:

az sphere device sideload deploy --image-package <path to image package for the app>

生成和下载错误报告

每天将错误和事件数据上传到 Azure Sphere 安全服务。 确保 Azure Sphere 设备已使用 Wi-Fi以太网 连接到 Internet,以便与 Azure Sphere 安全服务进行通信。

  1. 运行以下命令,将报表下载到 CSV 文件:

    az sphere catalog download-error-report --destination error.csv
    
  2. 打开下载的 CSV 文件并查找 组件 ID。 应会看到类似于以下内容的错误说明:

    AppExit (exit_code=0; component_id=685f13af-25a5-40b2-8dd8-8cbc253ecbd8; image_id=6d2646aa-c0ce-4e55-b7d6-7c206a7a6363)

还可以使用 Azure Sphere 公共 API 进行错误报告。

注意

  • 最近报告的事件最多可能需要 24 小时才能下载。
  • 如果在设备与 NTP 服务器连接之前发生事件或错误,则上传到 AS3 的遥测数据中包含的事件的时间戳可能不正确。 这将反映在从 AS3 下载的后续报表 的 StartTime 列中的错误条目中。 在这种情况下,请使用报表的 EndTime 字段来帮助估计事件发生的时间。 此字段包含云服务接收上传的遥测数据的时间,并且始终具有有效日期。

设置错误数据的格式

错误报告文件中的时间戳和数据列的格式不同于典型的 CSV 文件。 如果要在 Excel 中查看结果,可以通过创建新列并添加自定义公式来重新设置数据格式。

若要设置导出的 CSV 文件中的时间戳的格式以使用 Excel,请执行以下操作:

  1. 创建新的 Timestamp 列并为其创建自定义格式:

    yyyy/mm/dd hh:mm:ss

  2. 将以下公式添加到新 Timestamp 列中的单元格,更改 F2 单元格值以匹配列和行:

    =(DATEVALUE(LEFT(RawErrorReport!F2,10))+TIMEVALUE(RIGHT(RawErrorReport!F2,8)))

若要将“说明”字段拆分为单独的列,请按照以下步骤更改 F2 单元格值以匹配列和行:

  1. 创建名为 Shortname 或类似内容的新列,并将以下公式添加到单元格中:

    =TRIM(LEFT(F2,FIND("(",F2)-1))

  2. 创建行 1 标头与参数值具有相同名称的列,并将以下公式添加到每个列中的单元格:

    =IF(ISERROR(FIND("; " & H$1 & "=", SUBSTITUTE($F2,"(","; "))), "", MID($F2, FIND("; " & H$1 & "=", SUBSTITUTE($F2,"(","; ")) + (LEN(H$1) + 2), FIND("; ", SUBSTITUTE($F2,")","; "), FIND("; " & H$1 & "=", SUBSTITUTE($F2,"(","; "))) - FIND("; " & H$1 & "=", SUBSTITUTE($F2,"(","; ")) - (LEN(H$1) + 2)))