添加调试符号时C动态库出现dyld加载错误求助
解决Mac上带调试符号的动态库与ASAN链接时的dyld加载错误
在Mac Sonoma(14.3)环境下,用Homebrew Clang编译带调试符号的双架构(arm64/x86_64)动态库,链接启用Address Sanitizer的测试程序时,出现dyld找不到临时目录文件的错误。移除库编译的-g选项后程序能运行,但ASAN无法显示库内代码的调试符号。以下是可行的解决方案:
方案1:分开编译各架构再用lipo合并
一次编译双架构胖二进制时,调试符号容易嵌入编译过程中的临时文件路径,导致运行时dyld错误。分开编译每个架构再合并可规避此问题:
- 编译arm64架构的库:
/opt/homebrew/opt/llvm/bin/clang -dynamiclib -framework ApplicationServices -lcups lib/macos/*.c -o ./test/macos/libTest-arm64.dylib -Wall -Werror -Wextra -fvisibility=hidden -current_version 1.0 -compatibility_version 1.0 -arch arm64 -fno-limit-debug-info -g - 编译x86_64架构的库:
/opt/homebrew/opt/llvm/bin/clang -dynamiclib -framework ApplicationServices -lcups lib/macos/*.c -o ./test/macos/libTest-x86_64.dylib -Wall -Werror -Wextra -fvisibility=hidden -current_version 1.0 -compatibility_version 1.0 -arch x86_64 -fno-limit-debug-info -g - 用
lipo合并成胖二进制:lipo -create ./test/macos/libTest-arm64.dylib ./test/macos/libTest-x86_64.dylib -output ./test/macos/libTest.dylib - 正常编译测试程序并运行(注意修正ASAN环境变量写法):
/opt/homebrew/opt/llvm/bin/clang ./test/macos/*.c -o ./test/macos/run -L ./test/macos -lTest -Wall -Werror -Wextra -g -fsanitize=address -fsanitize-address-use-after-return=runtime -fsanitize-address-use-after-scope -fno-optimize-sibling-calls -O1ASAN_OPTIONS=detect_stack_use_after_return=1:detect_leaks=1 ./test/macos/run
方案2:编译库时添加-Wl,-headerpad_max_install_names选项
该选项会扩展动态库的头空间,确保安装路径能正确被处理,避免调试符号中的临时路径被错误引用:
修改后的库编译命令:
/opt/homebrew/opt/llvm/bin/clang -dynamiclib -framework ApplicationServices -lcups lib/macos/*.c -o ./test/macos/libTest.dylib -Wall -Werror -Wextra -fvisibility=hidden -current_version 1.0 -compatibility_version 1.0 -arch arm64 -arch x86_64 -fno-limit-debug-info -g -Wl,-headerpad_max_install_names
之后正常编译测试程序并运行即可。
额外注意:修正ASAN环境变量的写法
之前的启动命令中,两个ASAN_OPTIONS会被覆盖,正确的写法是用冒号分隔多个选项:
ASAN_OPTIONS=detect_stack_use_after_return=1:detect_leaks=1 ./test/macos/run
内容的提问来源于stack exchange,提问作者bren
相关产品推荐
相关产品推荐

