大家在做iOS App开发时,调试是必不可少的。而对于像我这种新手来说,看懂Xcode 的Crash Logs或者调试过程中的stack trace又是必不可少的,下面俺总结下自己在开发过程中遇到的常见Crash Logs的具体含义和追踪此类问题的具体技巧。

SIGSEGV(Segmentation fault)

在内存中,这个地址是存在的。但是,你的程序并没有权利进入这一区域。

当Xcode打出这条Crash Logs时,表示你意图进入一个非法的内存地址区域。它并非是ObjC相关的,而是C放出来的,所以,就算你没有ObjC的对象,也可能碰到这个导致程序当掉的BUG。

值得注意的是它并不是一个异常,所以我们不能用@try 和@catch对去抓他们,但是你可以设置你自己的 signal & sigaction 函数去处理。

如果你不懂什么叫signal ,可以先看看​​wikipedia​​是怎么解释的。

SIGBUS(Bus error)

进入非法的内存空间。至多时候,这一块内存空间都是不存在的,又或者你的赋值方式不正确。

SIGFPE(Floating point exception)

无效的算术操作,但是能够被识别成整型操作。

SIGPIPE

你尝试写入一些内容(比如一个音频文件)到管道,但是没有去处理读取结束。

SIGILL

illegal processor instruction.

SIGTRAP

当你在支持指令断点或者变量断点处查看的处理器上运行程序时候,调试器将会去请求CPU进入当相关地址查看指令集,或者进入特定地址段的读写。这个时候,整个程序还是全速运行的。

当处理器检测到断点事件时候,它将追踪到内核当中,内核发送SIGTRAP到正在调试运行的进程。一般情况下,SIGTRAP将会将次进程干掉,但是因为程序正在被调试,调试器将会被通知这一信号同时处理这一情况,调试器继续运行前,通常会让你去查看进程的状态。

SIGABRT

程序当掉。比如你有这样一句代码:

for(…..){
[NSString* objectkey = NSString stringWithFormat:@"%@",[line objectAtIndex:1]];
}

当程序跑到这一行的时候,程序挂掉了,并且抛出了SIGABRT。这个时候,可能是[line objectAtIndex:1],出问题了。可是当你去调试的时候,比如:NSLog(@”%d”,[line count]);打印出来的是数组中有三个数据,问题处在那里呢?

遇到这种情况的时候,有两个调试技巧可以帮助你解决问题:

1、认为问题还是line这个数组上,那么你可以这样做:

for(Object* obj in  line)
NSLog(@”%@”,[line description]);

先看看是不是真的问题处在Line数组的第二个位置没有相应的元素(不是一个NSString*对象,而是一个内存地址)。

2、因为我们是在GDB下的程序,用stringWithString 取代stringWithFormat这一个函数。StringWithFormat使用不确定的方式分割字符串并格式化,而stringWithString是复制char by char。

先写到这里