当前位置: 首页 > news >正文

心得之----XCode4 的调试定位技巧

论坛里经常有朋友会问Crash的问题。Crash最多的无非就两种,一种就是signal SIGABRT,大概的意思就是发送Message出现问题,信号迷失了。

这种的Crash其实是很好定位,Crash了后直接看Console里出的最后日志,比如这段:

 

12012-03-28 19:26:33.055 TableViewMenuDemo[3916:f803] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[__NSArrayI replaceObjectAtIndex:withObject:]: unrecognized selector sent to instance 0x6a3f3d0′
2 
3*** First throw call stack:

 

找到reason字段,那就是原因,说NSArray 调用 replaceObjectAtIndex:withObject:

这个方法是NSMutableArry的,NSArray并没有该方法。信号迷失掉了,所以Crash了。0x6a3f3d0 是出问题的内存地址,查下内存地址或搜下调用方法就比较好定位了。

Xcode4上还有个更好用的定位方法,就是设置一个Exception Breakpoint就好了
 

心得之----XCode4 <wbr>的调试定位技巧

看图在工程的左边栏中选择Breakpoint Navigator ,点击下面的+号添加一个Exception Breakpoint,然后再运行试试,Crash后,是不是直接定位到了那行代码了?再根据Console里的日志进行定位修改就好了。

下面说说另一种Crash,EXC_BAD_ACCESS ,这个比较头疼,因为Crash的时候,可能是比较早之前的某个变量释放了,现在访问时出问题。Console里也没显示什么日志。

这里光加入Exception Breakpoint是不够的了,XCode4还个可爱的地方,打开Scheme选项选择Edit  Scheme


心得之----XCode4 <wbr>的调试定位技巧

心得之----XCode4 <wbr>的调试定位技巧
 
然后按图勾上Enable Zombie Objects 和Malloc Stack那两项,记住一般只有在定位EXC_BAD_ACCESS时候才勾选,别有事没事都勾上。

这样重新跑一下,如果是到Exception Breakpoint处停止了,可以在Console中输入:c(continue)按回车继续跑,直到Crash。看下Console是不是有跟SIGABRT类似的错误信息日志了,后面定位什么的你懂的。

如果还没有日志,在Console中输入 po $eax   $eax标志出错的地方,适用模拟器,真机用$r0(话说EXC_BAD_ACCESS这种错误模拟器定位就行),还可以输入比如:po [$eax name]     po [$eax reason]等指令查看错误其他信息(注意方括号后没分号的)。然后,就没有然后了。

还要补充点,程序开发过程就要多关注左边栏中Issue Navigator里的警告信息,Xcode4不仅会警告,还多数给出解决建议。能避免后面不必要的Crash

心得之----XCode4 <wbr>的调试定位技巧
 
如果程序Crash,第一时间关注下debug Navigator里的执行信息,将滑块拉向右边可以看到更多调用信息,根据这个能大致设想是调用什么方法或进行什么操作时Crash的。

心得之----XCode4 <wbr>的调试定位技巧

 
====================== ================= 技巧2============================ ============
 

iPhone-NSAssert使用 
调试cocoa程序在程序出错时,不会马上停止。使用宏NSAssert可以让程序出错时马上抛出异常。
在debug情况下,所有NSAssert都会被执行。在release下不希望NSAssert被执行,我们通常在release种将断言设置成禁用。
设置方法:在targets种选择build,选择release。在gcc preprocessing下增加Preprocessor Macros 值为 NS_BLOCK_ASSERTIONS.
C语言调试用NSCAssert.

 

//=============================================================================================================================

 使用Xcode 4编译器设定Release/Debug教程

使用Xcode4编译器设定Release/Debug教程是本文要介绍的你内容,主要是来学习xcode 4的相关内容,让我们更一步的去熟悉、了解xcode 4,内容不多,不过真的可以帮助友们去解决xcode 4中编译器的问题。先来看内容。

进入Xcode 4,选择菜单“Product”->“Manage Schemes”,出现下图:

 
心得之----XCode4 <wbr>的调试定位技巧

选择一个项目,点击“Edit”,如图:

心得之----XCode4 <wbr>的调试定位技巧
 

Bulid Configuration

在调试中,如果需要传入参数,在上图中Arguments上设置。

一般这个设置常用于控制台程序,比如:A.exe -p boy

那么,在Arguments上添加-p boy

说明下,在XCode上,可以这么设定,如图所示:


心得之----XCode4 <wbr>的调试定位技巧
 
也可以这样,如图所示

心得之----XCode4 <wbr>的调试定位技巧
当然,个人建议使用后一种

另外:追加编译宏:选择项目,找到“Bulid Setting”,下面有一项:Preprocessor Macros。

小结:使用Xcode4编译器设定Release/Debug教程的内容介绍完了,希望本文对你有所帮助!

====================== ========== ======= 技巧3============================ ========== ==
 

xcode4 设置调试错误信息小结

方案1:NSZombieEnabled

先选中工程, 依次 "Product"-"Edit Scheme", 左栏选择"Run...", 右栏选中Arguments,然后在Environment Variables下面添加以下三个属性, 设值为YES

NSDebugEnabled

NSZombieEnabled

NSAutoreleaseFreedObjectCheckEnabled

 

心得之----XCode4 <wbr>的调试定位技巧
 

有时候在程序出错的时候能准确定位到奔溃的那一行,或者会给你下面这样的提示,而不仅仅是EXEC_BAD_ACCESS:

 

message sent to deallocated instance 0x126550

 

如果要查看上面地址的分配情况

开启MallocStackLogging(Xcode4勾选下MallocStackLogging就行)

出错时shell malloc_history pid address

另:有时候可以重载respondsToSelector可以帮你找到程序崩溃时最后执行的函数,然后排查.


 

 
 
 
 

方案2:添加全局断点

 

Xcode4可以很方便的添加全局的异常断点


心得之----XCode4 <wbr>的调试定位技巧

心得之----XCode4 <wbr>的调试定位技巧
 

方案3:中断和未捕获异常

 

1.未拦截信号来源:内核,其他程序,本身.

常见的两个信号:

1).EXC_BAD_ACCESS试图访问非法内存,导致SIGBUS或者SIGSEGV信号 

2).未能拦截obj_exception_throw导致的SIGABRT信号.

2.方法

1).使用NSUncaughtionHandler安装一个handler拦截未拦截异常

2).使用signal函数安装一个handler拦截BSD信号.(SIGKILL[kill-9]和SIGSTOP[Control+z]无法拦截)

两个c函数

 


 
  1. void SignalHandler(int signal)  
  2. {  
  3. //中断信号  
  4. }  
  5.   
  6.   
  7. void uncaughtExceptionHandler(NSException *exception)  
  8. {  
  9. //未捕获异常  
  10. }  


安装(与全局异常断点冲突,当有这样的断点是,下面拦截函数失效)


 
  1. void InstallUncaughtExceptionHandler()  
  2. {  
  3.     NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);  
  4.     signal(SIGABRT, SignalHandler);  
  5.     signal(SIGILL, SignalHandler);  
  6.     signal(SIGSEGV, SignalHandler);  
  7.     signal(SIGFPE, SignalHandler);  
  8.     signal(SIGBUS, SignalHandler);  
  9.     signal(SIGPIPE, SignalHandler);  
  10. }  

3.具体实例

1.http://cocoawithlove.com/2010/05/handling-unhandled-exceptions-and.html

重点在于尝试继续运行程序

告诉用户那些因为这些未拦截的异常和信号导致的崩溃,或者自己记录,甚至可以避开这样导致的崩溃.不过,如果多个信号拦截了,这可能失效.

非常推荐看看这篇文章

2.http://parveenkaler.com/2010/08/11/crashkit-helping-your-iphone-apps-suck-less/

重点在于记录异常(之后返回主线程)


 
  1. - (void)pumpRunLoop  
  2. {  
  3.     self.finishPump = NO;  
  4.     CFRunLoopRef runLoop = CFRunLoopGetCurrent();  
  5.     CFArrayRef runLoopModesRef =     CFRunLoopCopyAllModes(runLoop);  
  6.     NSArray * runLoopModes = (NSArray*)runLoopModesRef;  
  7.     while (self.finishPump == NO)  
  8.     {  
  9.         for (NSString *mode in runLoopModes)  
  10.         {  
  11.             CFStringRef modeRef = (CFStringRef)mode;  
  12.             CFRunLoopRunInMode(modeRef, 1.0f/120.0f, false);  // Pump the loop at 120 FPS  
  13.         }  
  14.     }  
  15.     CFRelease(runLoopModesRef);  
  16. }  

SIGKILL,程序在ios4下启动不了   

我把以前用sdk3写的代码升级到SDK4.0的模拟器上运行,退出时GDB提示Program received signal:  “SIGKILL”.
再次启动程序时程序启动不了.
在真机测试有时能起来有时起不来,如果起不来关机再开机,再启动就能起来
请问1. "SIGKILL"是什么情况下产生的?
        2. 如何解决?

注释:单击home是后台挂起,在双击home后才退出。


有哪位大侠知道敬请指教!不慎感激!

 

 

plist 加上UIApplicationExitsOnSuspend bool 值
參考這裡
UIApplicationExitsOnSuspend = Application does not run in background

相关文章:

  • VMWare Authorization 服务错误及其重装
  • [ZT]Dev-C++中编译C语言报错
  • activity-alias的使用
  • SqlDataSource GridView 刷新
  • 重新编译内核支持 PAE
  • Nginx perl cgi 支持
  • python文件读写学习
  • love2d教程16--简单拼音中文输入法
  • Linux中网络编程的常用函数(1)
  • ftp by libcurl
  • internet笔记
  • JXL导出Excel文件兼容性问题
  • 留与后人一段面试的总结
  • 俄罗斯方块总结
  • XYOrigami
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • 4. 路由到控制器 - Laravel从零开始教程
  • Android单元测试 - 几个重要问题
  • Apache Zeppelin在Apache Trafodion上的可视化
  • Apache的基本使用
  • Github访问慢解决办法
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • Java编程基础24——递归练习
  • Python - 闭包Closure
  • React-redux的原理以及使用
  • SpiderData 2019年2月25日 DApp数据排行榜
  • Spring Cloud Feign的两种使用姿势
  • webpack4 一点通
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 初识MongoDB分片
  • 读懂package.json -- 依赖管理
  • 给github项目添加CI badge
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 记录一下第一次使用npm
  • 蓝海存储开关机注意事项总结
  • 你真的知道 == 和 equals 的区别吗?
  • 如何使用 JavaScript 解析 URL
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • scrapy中间件源码分析及常用中间件大全
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • $.proxy和$.extend
  • (02)Hive SQL编译成MapReduce任务的过程
  • (1)(1.11) SiK Radio v2(一)
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转)项目管理杂谈-我所期望的新人
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .NET Core中Emit的使用
  • .NET Framework 服务实现监控可观测性最佳实践