在 Mac OS X Snow Leopard 上的 iPhone 模拟器上使用 Valgrind
由于在我的 iOS 程序中看到随机内存崩溃,我决定使用 Valgrind 来帮助解决问题,因为他们有一个在 32 位 mac OS X 上运行的端口。我按照此网页中的说明进行设置iPhone 模拟器上的 Valgrind 位于:
http://landonf.bikemonkey.org/code/ iphone/iPhone_Simulator_Valgrind.20081224.html
但是,虽然我可以在 iOS 模拟器中编译程序并设置预处理器标志,但我无法让 Valgrind 实际运行我的程序。它总是退出并出现以下错误:
valgrind: /Users/megahub/Library/Application Support/iPhone Simulator/4.2/Applications/6FD1FFF3-0EFB-4D81-A95A-F02E0AA9095E/QuamStockAdHoc.app/QuamStockAdHoc: cannot execute binary file
cannot execute binary file
我该如何解决此问题?我已经验证了可执行文件存在于该路径中,因为我可以在模拟器中没有 Valgrind 的情况下运行它。
Due to seeing random memory crashes in my iOS program, I decided to use Valgrind to help root out the problem, as they have a port that runs on the 32-bit mac OS X. I followed the instructions in this web page to set up Valgrind on the iPhone simulator here:
http://landonf.bikemonkey.org/code/iphone/iPhone_Simulator_Valgrind.20081224.html
However, although I can get the program to compile in the iOS simulator, and the preprocessor flags set, I could not get Valgrind to actually run my program. It always quits with the following error:
valgrind: /Users/megahub/Library/Application Support/iPhone Simulator/4.2/Applications/6FD1FFF3-0EFB-4D81-A95A-F02E0AA9095E/QuamStockAdHoc.app/QuamStockAdHoc: cannot execute binary file
cannot execute binary file
How can I resolve this problem? I've verified that the executable is present at that path, because I can run it without Valgrind in the simulator.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
编译器默认为 64 位(假设您有一台 64 位机器),但 valgrind 尚未正式支持 Mac OS X 上的 64 位可执行文件(据我所知,我可能是错的)。可执行文件上的文件命令应报告“Mach-Oexecutable i386”。还要确保您使用的所有库都是 32 位版本。
The compiler default is 64-bit (assuming you have a 64-bit machine), but valgrind does not yet officially support 64-bit executables on Mac OS X,(As per my knowledge, I might be wrong). The file command on your executable should report "Mach-O executable i386". Also be sure that you have 32-bit versions of all the libraries you are using.
可能还有其他原因触发此消息,但一个常见原因是尝试在 32 位可执行文件上使用 valgrind,而该文件已编译为仅在 64 位可执行文件上运行。 (截至撰写本文时,MacPorts 在 64 位操作系统版本上执行此操作)。这不是模拟器特有的:尝试 valgrind 任何 32 位应用程序都会产生这种情况。
从 valgrind 源进行的本机安装无需
configure
额外参数,可在 32 位或 64 位可执行文件上运行。这并不能让我在模拟器中运行 valgrind。还没有......
跟进:
获得正确的宽度不会让你走得太远。正如其他地方提到的,真正需要的是将 valgrind 移植到模拟器运行时。它需要像目标应用程序一样使用所有平台 SDK。
事实证明,这是可能的。这并不容易,而且我不确定它有多稳定,但有可能。我想我会与 valgrind 人员讨论是否可以以某种方式清理此问题并使其成为受支持的端口/目标。
当它工作时,它很漂亮:
变成
漂亮的符号和行号。精彩的。
状态:
我已经到了 valgrind 会在 Apple 的 sqlite3 dylib 上呕吐的地步。我不是 100% 确定原因,但我认为这是因为 Apple 版本的 sqlite3 有一些 valgrind 未涵盖的 mach 调用。所以我从来没有让它在我的应用程序上完全运行。我在 valgrind 列表上提出了这个话题,但没有引起任何兴趣。我仍然想让它发挥作用,但这不会太快发生……至少不会由我来实现。
嗯……不知道我是否可以在 WWDC 上引起任何兴趣……
There may be other things that trigger this message, but a common cause is trying to use valgrind on a 32 bit executable when it has been compiled to only run on 64 bit executables. (MacPorts as of this writing does that on 64 bit OS builds). This isn't specific to the simulator: trying to valgrind any 32 bit app will produce this.
A native install from source of valgrind with no extra arguments to
configure
will work on either 32 or 64 bit executables.This doesn't get me all the way to being able to run valgrind within the simulator. Not yet ...
Follow up:
Getting the width right doesn't get you too far. As mentioned somewhere else, what's really required is porting valgrind to the simulator runtime. It needs to use all the platform SDKs just like the target app does.
Turns out, this is possible. Not easy, and I'm not sure how stable it is, but possible. I think I'll talk to the valgrind folks about whether this can be cleaned up somehow and made a supported port/target.
When it works, it's beautiful:
turns into
Pretty symbols and line numbers. Wonderful.
Status:
I got to the point where valgrind would barf on Apple's sqlite3 dylib. I'm not 100% sure why but I think it's because Apple's version of sqlite3 has some mach calls that valgrind doesn't cover. So I never got it to work in total on my app. I raised the topic on the valgrind list but it didn't raise any interest. I'd still like to get it to work, but it's not going to happen too soon ... at least not by me.
Hmmm ... wonder if I can raise any interest at WWDC ...
为什么首先要使用 valgrind?您有 NSZombie 和朋友以及带有泄漏检查器的 Instruments。
如何设置:
或者为了获得更多控制:
在您的主目录中创建一个名为“的新文件” .gdbinit”(注意前面的点),内容如下:
fb -[NSException 引发]
fb -[NSAssertionHandler handleFailureInFunction:文件:行号:描述:]
fb -[NSAssertionHandler handleFailureInMethod:对象:文件:行号:描述:]
设置环境 MallocHelp=YES
设置环境 NSZombieEnabled=YES
设置环境 NSDallocateZombies=NO
设置环境 MallocCheckHeapEach=100000
设置环境 MallocCheckHeapStart=100000
设置环境 MallocScribble=YES
设置环境 MallocGuardEdges=YES
设置环境 MallocCheckHeapAbort=1
设置环境 CFZombie 5
fb -[_NSZombie 初始化]
fb -[_NSZombie keepCount]
fb -[_NSZombie 保留]
fb -[_NSZombie 版本]
fb -[_NSZombie 自动释放]
fb -[_NSZombie methodSignatureForSelector:]
fb -[_NSZombie respondsToSelector:]
fb -[_NSZombie 前向调用:]
fb -[_NSZombie 类]
fb -[_NSZombie 释放]
fb szone_error
如果您在标准调试器中运行应用程序,那么它会在出现每个内存错误时停止。
如果启动调试并观察控制台,您可以看到如果显示长内存调试器帮助文本,它是否有效。
Why use valgrind in the first place? You have NSZombie and friends plus Instruments with its leak checker.
How to set up:
Alternatively for more control:
Create a new file in your home directory named ".gdbinit" (note the dot in front) with the following content:
fb -[NSException raise]
fb -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:]
fb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
set env MallocHelp=YES
set env NSZombieEnabled=YES
set env NSDeallocateZombies=NO
set env MallocCheckHeapEach=100000
set env MallocCheckHeapStart=100000
set env MallocScribble=YES
set env MallocGuardEdges=YES
set env MallocCheckHeapAbort=1
set env CFZombie 5
fb -[_NSZombie init]
fb -[_NSZombie retainCount]
fb -[_NSZombie retain]
fb -[_NSZombie release]
fb -[_NSZombie autorelease]
fb -[_NSZombie methodSignatureForSelector:]
fb -[_NSZombie respondsToSelector:]
fb -[_NSZombie forwardInvocation:]
fb -[_NSZombie class]
fb -[_NSZombie dealloc]
fb szone_error
If you run your App in a standard debugger now it halts on every memory error.
You can see if it works if a long memory debugger help text is displayed if you start the debugging and watch the console.