相信很多人都知道通过NSZombies来帮助调试出现EXC_BAD_ACCESS的情况,但有时还是找不到需要的信息,那么应该怎么办呢?
下面通过一个例子来说明.下面是hello world的代码:
1 2 3 | NSString * hello = [ NSString stringWithFormat : @ "Hello world" ]; NSLog ( @ "What you say is %@",hello ); [hello release ]; |
运行后出现EXC_BAD_ACCESS错误.但没有其他任何提示,这时候通过右击executables下的应用程序名,选择get info后,在arguments下输入环境变量(NSZombieEnabled,MallocStackLogging),如图所示:
NSDebugEnabled
NSZombieEnabled
MallocStackLogging
MallocStackLoggingNoCompact
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SZpJWbvp3XkRWYvwFMx8CXwEDMy8CXzRWYvxGc19CX05WZ052bj1Cc39CXuNmLrVWZn1SZu9GawlmL3d3dvw1LcpDc0RHaiojIsJye.png)
再次运行后程序crash,如图:
这次可以看到问题是”message sent to dealloced object”了,但具体是哪个语句引起的还并不知道,于是需要在gdb上输入以下语句:
shell malloc_history pid address
那么pid和address是什么呢?再看下crash的图片结合一下我以下使用的命令,你应该很快就可以判定pid和address是从哪里来的了,我的命令是:
shell malloc_history 596 0×5f3ef80
再次运行,程序crash时会出现大量的stack trace信息,如下图是与本程序相关的:
根据这些信息大家就可以找到问题出现在[BadAccessViewController viewDidLoad] 中与 +[NSString stringWithFormat:] 有关的地方.
最后大家记得把环境变量NSZombieEnabled,MallocStackLogging删除或设置为NO,因为它们会使得内存不会被释放.