4

地址消毒器https://code.google.com/p/address-sanitizer/wiki/AddressSanitizer

我已经编译了我自己的 llvm(非常直接的编译),因为苹果的 llvm 不支持这个功能。

我已经测试了 mac 命令行程序的 clang,它可以工作(但没有显示源代码行)。

对于iOS,仍然存在一些问题:

  • 编译模拟器版本:报告预编译头错误:

在 /Users/fluke/Documents/projects/tmp/testAsanNoARC/testAsanNoARC/testAsanNoARC-Prefix.pch:12 包含的文件中: 在 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/ 包含的文件中SDKs/iPhoneSimulator6.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIKit.h:9: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1 .sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:53:24:错误:“UIAccelerometer”不可用:在 OS X 上不可用 - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:( UIAcceleration *) 加速 NS_DEPRECATED_IOS(2_0, 5_0); ^ /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1。sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:33:12:注意:声明已在此处明确标记为不可用@interface UIAccelerometer:NSObject { ^ /Applications/Xcode.app/Contents/Developer/Platforms /iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:53:71:错误:'UIAcceleration'不可用:在OS X上不可用-( void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration NS_DEPRECATED_IOS(2_0, 5_0); ... app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:53:71:错误:“UIAcceleration”不可用:在 OS X 上不可用 - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration NS_DEPRECATED_IOS(2_0, 5_0); ... app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAccelerometer.h:53:71:错误:“UIAcceleration”不可用:在 OS X 上不可用 - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration NS_DEPRECATED_IOS(2_0, 5_0); ...

  • 为设备版本编译,它报告缺少 libarc(但实际上我没有启用 ARC)

ld:找不到文件:/Users/fluke/Documents/tools/asan/Debug+Asserts/lib/arc/libarclite_iphoneos.a clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

  • 所以我尝试将它用于单独的库 - 只是新的库目标并使用我自己的clang,而主要目标仍然使用苹果的llvm。程序编译(可能需要链接到内置 llvm 中的 asan dylib),但无法正常工作,因为我需要在程序进入之前加载我的 asan。

谁有这样做的经验?

4

2 回答 2

1

在朋友的帮助下,我终于得到了 asan 的工作。

  • 将所有 c/c++ 代码移动到 xcode 项目的新目标(可可库目标)。使项目正常构建和运行,因为它是一个单独的应用程序,然后将 c/c++ 代码分离到一个库中。

  • 构建llvm。参考http://blog.wadetregaskis.com/tot-clang-llvm-in-xcode/

  • 向 xcode 添加一个 clang 选项。为方便起见,您可以使用此模板:http ://blog.wadetregaskis.com/tot-clang-llvm-in-xcode/ 。将 clang 路径更改为上一步中刚刚构建的 clang。

  • 将 xcode 中的 lib 目标更改为使用新的 clang/llvm,添加一个 cflag -fsanitize=address。然后编译,如果某些api(如opengl/系统视频功能)报不支持,那么你可以把它放到app项目中,你的clang不支持编译它。

  • 如果你通过编译,它会报告__asan_xxx函数的链接问题,添加一个名为“libclang_rt.asan_osx_dynamic.dylib”的lib到应用程序的链接依赖中,它位于你的llvm的./Debug+Asserts/lib/clang/3.4/ lib/darwin/ 文件夹。

  • 那么您需要指定输出文件,否则报告将进入标准输出并带有颜色字符,这会让您感到困惑。将此行放入您的 main.m 中:

    extern void __sanitizer_set_report_path(const char *path); __sanitizer_set_report_path("/tmp/asan.txt");

  • 然后您可以使您的程序出现一些内存错误,例如在空闲或堆缓冲区溢出后使用。asan 将让程序在第一个错误中崩溃,并生成 /tmp/asan.txt.number 报告。

  • 你快到了,报告显示带有文件偏移量的错误堆栈。您需要做的只是多一步 - 将地址解析为代码行。您需要找到项目的 DWARF 文件,然后使用名为 asan_symbolize.py 的工具生成带有源代码行的新报告。您可以 goole asan_symbolize.py 然后获取并修复此脚本以使用 DWARF 文件。您可以通过右键单击您的生产应用程序找到 DWARF 文件,选择在 finder 中显示,然后上一级以获取 iphone 模拟器目录,打开名为 your.app.dSYM 的包,然后您可以在 ./Content 中获取 DWARF /资源/矮人。

我这里唯一没有列出的是修改后的asan_symbolize.py,你可以自己修改它,它没有魔法,你只要纠正一些路径就可以了。

于 2013-06-29T12:39:47.547 回答
0

原始帖子中列出的错误与 ASan 本身几乎没有关系。如果没有 -fsanitize=address 标志,您肯定会得到它们。尚不支持为 iOS 构建和运行,但是您可以构建一个针对 iOS 模拟器的应用程序 - 它应该可以正常工作。请随时将更多问题发送至 address-sanitizer@googlegroups.com

于 2013-07-03T09:17:05.420 回答