产品 / 插件:实时音视频 / 实时语音 / AI视觉 / 即时通讯 / 畅直播
平台 / 框架:iOS / Android / macOS / Windows
更新时间:2023-01-11 18:45
Address Sanitizer (ASan) 是一种基于编译器的快速检测工具,用于检测原生代码中的内存错误。
ASan 可以检测以下问题:
如需获取开启了 ASan 工具的 SDK 包,请联系 ZEGO 技术支持获取。
SDK 包中已附带了匹配版本的 ASan 运行时库。
下面以 RTC SDK 为例,进行说明如何集成开启了 ASan 的 SDK 包,其他产品操作类似。
请根据 集成 SDK 文档的 “方式二:复制 SDK 文件手动集成” 进行集成 SDK。
请将 SDK 包内带有的 ASan 运行时库一并集成到 App 内。
将 wrap.sh
集成到 App 内。您可以从 跑通示例源码 中下载的 Android 示例代码中获取 wrap.sh
文件,解压示例源码后,找到 ZegoExpressExample/main/asan/lib
目录,将整个 lib
目录拷贝到您的应用工程的 app/src/main/resources
目录下,结构如下所示。
您也可以通过 Android ASan 文档 ,获取谷歌 NDK 提供的 wrap.sh
文件进行集成。
<project root>
└── app
├── src
│ └── main
│ └── resources
│ └── lib
│ ├── arm64-v8a
│ │ └── wrap.sh
│ ├── armeabi-v7a
│ │ └── wrap.sh
│ ├── x86
│ │ └── wrap.sh
│ └── x86_64
│ └── wrap.sh
└── libs
├── ZegoExpressEngine.jar
├── arm64-v8a
│ ├── libclang_rt.asan-aarch64-android.so
│ └── libZegoExpressEngine.so
├── armeabi-v7a
│ ├── libclang_rt.asan-arm-android.so
│ └── libZegoExpressEngine.so
├── x86
│ ├── libclang_rt.asan-i686-android.so
│ └── libZegoExpressEngine.so
└── x86_64
├── libclang_rt.asan-x86_64-android.so
└── libZegoExpressEngine.so
以 debuggable
运行 App,将 android:debuggable
添加到 AndroidManifest.xml
应用清单。
<application
android:debuggable="true"
...>
...
</application>
若运行 App 时报错 “The APKs are invalid.” ,请参考 GitHub 文档 进行处理,并在 app/build.gradle
中添加如下配置,请参考 配置文档 进行处理。
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared"
}
}
}
}
请根据 集成 SDK 文档的 “方式三:复制 SDK 文件手动集成” 进行集成 SDK。
SDK 包内带有 ASan 运行时库,请根据情况选择是否将其集成到 App 内。
在这种情况下,请将 ASan 运行时库以 “Embed & Sign” 的方式集成到 App 内。
SDK 包内附带三个 ASan 运行时库,分别对应 iOS 真机、iOS 模拟器和 Mac Catalyst。请勿同时集成多个 ASan 运行时库到 App 内。
当运行 iOS 真机时,需要集成 libclang_rt.asan_ios_dynamic.dylib
。
当运行 iOS 模拟器时,需要集成 libclang_rt.asan_iossim_dynamic.dylib
。
当运行 iOS Mac Catalyst 时,需要集成 libclang_rt.asan_osx_dynamic.dylib
。
集成 ZEGO SDK 的 xcframework,不需要集成 ASan 运行时库。但此时首先需要确认 ZEGO SDK 使用的 clang 版本与本机的 clang 版本是否匹配。
# 查看 ZEGO SDK 使用的 clang 版本
otool -l libclang_rt.asan_ios_dynamic.dylib | grep -A 2 LC_SOURCE_VERSION
# 查看本机 Xcode 附带的 clang 版本
clang --version
若不匹配,需要下载 ZEGO SDK 所使用的 Xcode 版本,否则 ASan 无法使用。
可通过如下链接查询 Xcode 历史版本中附带的 clang 版本:
以上图为例,本机 Xcode 附带的 clang 版本为 1400 (14.0.0) ,而该 ZEGO SDK 所使用的 clang 版本为 1316 (13.1.6),然后查询到 Xcode 13.3 到 13.4.1 所附带的 clang 版本均为 1316,因此可以下载一个 13.4.1 版本的 Xcode。
您可以使用 XcodesApp 在本机同时安装多个版本的 Xcode。
打开 Xcode 工程,在菜单栏选择 ”Product > Scheme > Edit Scheme“,在侧边栏点击 “Run”,在 ”Diagnostics“ 选项卡中,勾选 ”Address Sanitizer“ ,即可开启 ASan。
单击 Xcode 的运行按钮,开始构建并调试 App。
xcodebuild
命令中,添加 -enableAddressSanitizer YES
参数,详情请参考 文档 进行处理。若您的工程是 Xcode 原生工程,请参考上面 iOS 的使用方式进行集成,下面将介绍非 Xcode 工程的集成方式。
SDK 包内带有 ASan 运行时库,请根据情况来选择是否将其集成到 App 内。
CMake
# 链接 ZEGO SDK 以及 ZEGO SDK 包内提供的 ASan 运行时库
link_libraries(
"${CMAKE_CURRENT_LIST_DIR}/libs/ZegoExpressEngine.xcframework/macos-arm64_x86_64/libZegoExpressEngine.dylib"
"${CMAKE_CURRENT_LIST_DIR}/libs/libclang_rt.asan_osx_dynamic.dylib"
)
QMake (Qt5)
# 链接 ZEGO SDK 以及 ZEGO SDK 包内提供的 ASan 运行时库
LIBS += -L$$PWD/libs -lclang_rt.asan_osx_dynamic
LIBS += -L$$PWD/libs/ZegoExpressEngine.xcframework/macos-arm64_x86_64 -lZegoExpressEngine
请确保 ZEGO SDK 使用的 clang 版本与本机的 clang 版本匹配,请参考上述 iOS 的情况二进行处理。
CMake
# 为自己的 App 开启 ASan
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address)
# 链接 ZEGO SDK 以及 ZEGO SDK 包内提供的 ASan 运行时库
link_libraries(
"${CMAKE_CURRENT_LIST_DIR}/libs/ZegoExpressEngine.xcframework/macos-arm64_x86_64/libZegoExpressEngine.dylib"
"${CMAKE_CURRENT_LIST_DIR}/libs/libclang_rt.asan_osx_dynamic.dylib"
)
QMake (Qt5)
# 为自己的 App 开启 ASan
QMAKE_CXXFLAGS += -fsanitize=address
QMAKE_LFLAGS += -fsanitize=address
# 链接 ZEGO SDK 以及 ZEGO SDK 包内提供的 ASan 运行时库
LIBS += -L$$PWD/libs -lclang_rt.asan_osx_dynamic
LIBS += -L$$PWD/libs/ZegoExpressEngine.xcframework/macos-arm64_x86_64 -lZegoExpressEngine
目前我们使用微软 MSVC 的 ASan。请参考 官方文档 为您的 App 开启 ASan。
使用 MSVC ASan 有如下限制:
部分平台需要用非常规方式启动 App 以获得 ASan 的错误报告,详情如下:
iOS
若使用 Xcode 运行调试 App,无需做特殊处理。
若打包出 ipa 包分发给其他 iOS 设备运行,请注意开启了 ASan 后的包无法上传到 App Store Connect(包括 TestFlight,会被 Apple 拒绝),因此建议以 ad-hoc
或 development
的方式打包并通过 ipa 包来分发给内部测试设备。可以使用 tidevice 或 libimobiledevice 等工具将 ipa 安装到测试设备上。
macOS
不要直接双击打开应用,而是打开终端并 cd
到应用(.app)所在的目录下。
cd MyAwesomeApp
运行 .app
目录里的可执行二进制文件。
./MyAwesomeApp.app/Contents/MacOS/MyAwesomeApp
Windows
不要直接双击打开应用,而是打开命令提示符并 cd
到应用 .exe
所在的目录下,然后运行应用。
cd MyAwesomeApp
建议设置 ASan 的崩溃转储文件路径,当发生崩溃时将产生 Crash Dump 文件(参考文档)。
set ASAN_SAVE_DUMPS=MyFileName.dmp
.\MyAwesomeApp.exe
当发生问题时,ASan 会输出类似如下的报告到控制台或崩溃日志中 (Android Logcat / Apple Crash Report / Windows Dump),请将相关内容以及相应的 SDK 日志提交给 ZEGO 技术支持进行分析。
==9901==ERROR: AddressSanitizer: heap-use-after-free on address 0x60700000dfb5 at pc 0x45917b bp 0x7fff4490c700 sp 0x7fff4490c6f8
READ of size 1 at 0x60700000dfb5 thread T0
#0 0x45917a in main use-after-free.c:5
#1 0x7fce9f25e76c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
#2 0x459074 in _start (a.out+0x459074)
0x60700000dfb5 is located 5 bytes inside of 80-byte region [0x60700000dfb0,0x60700000e000)
freed by thread T0 here:
#0 0x4441ee in __interceptor_free projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64
#1 0x45914a in main use-after-free.c:4
#2 0x7fce9f25e76c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
previously allocated by thread T0 here:
#0 0x44436e in __interceptor_malloc projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74
#1 0x45913f in main use-after-free.c:3
#2 0x7fce9f25e76c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
SUMMARY: AddressSanitizer: heap-use-after-free use-after-free.c:5 main
ASan 默认检测 Container Overflow 问题,但是容易产生误报,详情请参考 GitHub 文档,因此在启动 App 时,建议关闭 Container Overflow 类型错误的检测。
若您从 跑通示例源码 中获取 wrap.sh
文件,则无需做额外修改,示例源码中提供的 wrap.sh
是已修改完成的。
若您从 Android NDK 或其他地方获取 wrap.sh
文件,则需要修改 wrap.sh
文件,为 ASAN_OPTIONS
环境变量添加 detect_container_overflow=0
参数,如下所示。
export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1,detect_container_overflow=0
若使用 Xcode 直接运行调试 App,打开 Xcode 工程,在菜单栏选择 ”Product > Scheme > Edit Scheme“,在侧边栏点击 “Run”,然后在 ”Arguments“ 选项卡的 “Environment Variables” 选项中,添加环境变量 ASAN_OPTIONS
其值设为 detect_container_overflow=0
,如下图所示。
若使用 ipa 包分发到其他设备运行 App,请使用 tidevice 设置环境变量,然后启动 App。
tidevice launch -e ASAN_OPTIONS:"detect_container_overflow=0" YOUR_APP_BUNDLE_ID
在终端启动 App 前,先设置 ASAN_OPTIONS
环境变量,然后运行 App。
export ASAN_OPTIONS=detect_container_overflow=0
./MyAwesomeApp.app/Contents/MacOS/MyAwesomeApp
在命令提示符启动 App 前,先设置 ASAN_OPTIONS
环境变量,然后运行 App。
set ASAN_OPTIONS=detect_container_overflow=0
set ASAN_SAVE_DUMPS=MyFileName.dmp
.\MyAwesomeApp.exe
联系我们
文档反馈