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


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

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

     

    1 2012-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

  • 相关阅读:
    vue-cli脚手架工具构建&初始化vue项目
    2020/05/17 Github加速-DNS配置
    同时将本地git仓库提交到gitee和github
    git远程仓库在本地看不到&push 到远程仓库失败的解决方案
    stylus的使用-变量和函数
    webpack使用4-HRM热替换&SourceMap&解析es语法
    webpack使用3-plugin插件的使用
    webpack使用2-常用的几个loader的使用
    webpack基本使用
    spring框架里面的注入?
  • 原文地址:https://www.cnblogs.com/zhwl/p/2850622.html
Copyright © 2020-2023  润新知