收集和解释错误数据

重要

这是 Azure Sphere(旧版)文档。 Azure Sphere(旧版)将于 2027 年 9 月 27 日停用,用户此时必须迁移到 Azure Sphere(集成)。 使用位于 TOC 上方的版本选择器查看 Azure Sphere(集成)文档。

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

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

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

不会从 RTApps 收集任何错误报告数据。 如果要记录来自 RTApps 的错误,则需要实现核心间通信,以便将错误数据记录到网络服务的高级应用程序。 有关详细信息,请参阅 与高级应用程序 通信,并与 支持实时的应用程序 通信。

可用数据类型

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

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

开始时间和结束时间定义聚合事件数据的时间窗口。 任何聚合事件组的窗口最多可以 24 小时,并且每个时间窗口的最大次数为 8 次。

应用程序事件

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

应用程序更新是计划内事件。 AppUpdate 事件的说明字段会包含 AppUpdate

应用程序故障、退出、启动失败以及类似事件是计划外事件。 对于计划外事件,说明字段的内容取决于遇到事件的应用程序。 下表列出了计划外事件的说明字段中可能出现的字段。

Data 说明
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)

Data 说明
pc 程序计数器。 指向触发崩溃的指令的地址。
lr 链接注册。 可能指向调用函数中的返回地址。
sp 堆栈指针。 指向调用堆栈的顶部。
signo POSIX 信号。 指示错误类型。
errno POSIX errno。 指示一个错误。
code 指示父信号状态中的详细崩溃状态。
component_id 发生故障的软件组件的 GUID。
pc_modulename+offset 模块的名称和偏移量到包含发生崩溃的代码的模块中。
lr_modulename+offset 模块的名称和模块中可能是调用函数的偏移量。

解释应用崩溃

可以在signal_status和signal_code中找到有关 AppCrash 的大部分信息。 执行以下步骤:

  1. 使用 Man 7 文档进行signal_status,首先查看标有“标准信号的信号编号”的表。在 x86/ARM 列中,搜索错误报告中csv分配给signal_status的值。 找到后,记下最左侧列中的相应信号名称。
  2. 向上滚动到标记为“标准信号”的表。匹配先前确定的 Signal 名称,并使用表收集有关信号指示的详细信息。
  3. 在之前找到的 signal_code 和 Signal 名称的 Man 7 文档中,找到相应的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 节中描述了 Signal man 页面 值 11 的signal_status对应于 SIGSEGV 信号。
  2. SIGSEGV 指示发生了无效的内存引用(这通常是空指针)。
  3. SI_Codes在每个signal_status的 SigAction 人页说明的第 3 节中介绍。 虽然页面未列出每个si_code的索引号,但可以从索引 1 开始的每个signal_status类别进行计数。 通过查看 SIGSEGV 的si_codes列表(从索引 1 开始),可以看到第三个匹配SEGV_BNDERR。
  4. SEGV_BNDERR指示发生了失败的地址绑定检查。

注意

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

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

AppExits 可能会由于多种原因(例如应用程序更新、设备被拔出或关闭 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 次。 无需调试即可从命令行部署示例,如下所示:

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

生成和下载错误报告

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

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

    azsphere tenant 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. 创建新的时间戳列并为其创建自定义格式:

    yyyy/mm/dd hh:mm:ss

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

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

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

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

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