macOS下如何查看应用程序运行结束后的Address Sanitizer(Asan)输出
macOS平台获取Address Sanitizer(Asan)输出的可行方案
方法1:启动时直接重定向stderr(无需修改代码)
这是最通用、稳定性最高的方案:
- 终端直接启动应用时,执行命令时附带重定向规则即可:
仅保存日志到文件:./你的应用程序 2> asan_report.log
同时在终端输出并保存日志:./你的应用程序 2>&1 | tee asan_report.log - 如果是通过Xcode调试运行,打开「Edit Scheme」->「Run」->「Arguments」,在「Environment Variables」中添加变量
ASAN_OPTIONS,值设为log_path=asan_report.log,Asan触发时会自动将完整报告写入带进程ID后缀的日志文件中,沙盒应用日志默认生成在沙盒目录下,非沙盒应用生成在当前工作目录。
方法2:代码层面重定向Asan输出
如果需要固定日志输出路径,可在程序入口最开始的位置重定向stderr,示例代码如下:
#include <stdio.h> #include <unistd.h> #include <fcntl.h> int main(int argc, char** argv) { // 必须放在所有业务逻辑执行前执行 int log_fd = open("asan_output.log", O_WRONLY | O_CREAT | O_APPEND, 0644); if (log_fd >= 0) { dup2(log_fd, STDERR_FILENO); close(log_fd); } // 原有业务代码 // ... }
关于捕获Asan信号的说明
Asan触发错误时默认会发送SIGABRT信号终止程序,不建议自行捕获该信号读取Asan输出,自定义信号处理逻辑会打断Asan的报告生成流程,大概率导致日志丢失、不完整。
如果需要在Asan触发后执行自定义收尾逻辑,可以使用Asan官方提供的回调接口__asan_on_error,该函数会在Asan打印完所有错误报告后、程序退出前执行,示例如下:
#include <sanitizer/asan_interface.h> void __asan_on_error() { // 仅可做简单的收尾操作,比如写入崩溃标记、触发自定义上报等,不要修改stderr配置 fprintf(stderr, "Asan错误已触发,程序即将退出\n"); }
额外注意事项
- 若macOS开启了系统完整性保护(SIP),第三方工具跨进程读取其他应用的stderr会有权限限制,优先使用上述启动时重定向、Asan自带
log_path参数的方案,避免权限问题 - 沙盒应用生成的Asan日志默认保存在应用自身的沙盒目录下,获取日志时需要对应目录的读写权限
内容的提问来源于stack exchange,提问作者Arial Pilisov
相关产品推荐
相关产品推荐

