收集和解释错误数据
每天将错误和事件数据上传到 Azure Sphere 安全服务。 有权访问特定目录的任何人都可以下载该目录的数据。 报表涵盖目录中的所有设备。
每个报告最多包含 1,000 个事件或 14 天的数据,以先到达者为准。 数据可以写入文件,也可以通过管道传输到脚本或应用程序。 CLI 只能返回 1,000 个事件。 使用 Azure Sphere 公共 API 指定页面上返回的最大事件数。
可以通过以下方式下载有关影响设备的错误和其他事件的数据:
使用 az sphere catalog download-error-report 命令。 下载包含当前目录中设备报告的错误和事件信息的 CSV 文件。
使用 Azure Sphere 公共 API 进行错误报告。 API 终结点返回一个 JSON 对象,你可以根据需要分析该对象。
不会从 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 的大多数信息。 请按照以下步骤操作:
- 使用 适用于signal_status的 Man 7 文档,首先查看标有“标准信号的信号编号”的表。在 x86/ARM 列中,在错误报告
csv
中搜索分配给signal_status的值。 找到后,记下最左侧列中的相应 Signal 名称。 - 向上滚动到标有“标准信号”的表。匹配之前确定的信号名称,并使用表收集有关信号指示内容的详细信息。
- 在针对signal_code的 Man 7 文档和之前找到的 Signal 名称中,找到相应的si_codes列表。
- 使用错误报告
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 的以下附加信息:
- 信号手册页说明的第 10 节介绍了 信号。 值 11 的signal_status对应于 SIGSEGV 信号。
- SIGSEGV 指示发生了无效的内存引用, (这通常是空指针) 。
- 每个signal_status的 SigAction 手册页 说明的第 3 节介绍了SI_Codes。 虽然页面未列出每个si_code的索引号,但可以从索引 1 开始的每个signal_status类别进行计数。 通过查看从索引 1) 开始的 SIGSEGV (si_codes列表,可以看到第三个匹配SEGV_BNDERR。
- 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 安全服务进行通信。
运行以下命令,将报表下载到 CSV 文件:
az sphere catalog download-error-report --destination error.csv
打开下载的 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,请执行以下操作:
创建新的 Timestamp 列并为其创建自定义格式:
yyyy/mm/dd hh:mm:ss
将以下公式添加到新 Timestamp 列中的单元格,更改 F2 单元格值以匹配列和行:
=(DATEVALUE(LEFT(RawErrorReport!F2,10))+TIMEVALUE(RIGHT(RawErrorReport!F2,8)))
若要将“说明”字段拆分为单独的列,请按照以下步骤更改 F2 单元格值以匹配列和行:
创建名为 Shortname 或类似内容的新列,并将以下公式添加到单元格中:
=TRIM(LEFT(F2,FIND("(",F2)-1))
创建行 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)))