zoukankan      html  css  js  c++  java
  • xcode4 设置调试错误信息小结

    本文中示例的xcode版本为4.3.1


    方案1:NSZombieEnabled

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

    NSDebugEnabled

    NSZombieEnabled

    NSAutoreleaseFreedObjectCheckEnabled



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

     

    message sent to deallocated instance 0x126550

     

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

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

    出错时shell malloc_history pid address

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



    方案2:添加全局断点


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

     


    方案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函数

     

    void SignalHandler(int signal)  
    {  
        //中断信号  
    }  
    
    
    void uncaughtExceptionHandler(NSException *exception)  
    {  
        //未捕获异常  
    } 
    



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


    void InstallUncaughtExceptionHandler()  
    {  
        NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);  
        signal(SIGABRT, SignalHandler);  
        signal(SIGILL, SignalHandler);  
        signal(SIGSEGV, SignalHandler);  
        signal(SIGFPE, SignalHandler);  
        signal(SIGBUS, SignalHandler);  
        signal(SIGPIPE, SignalHandler);  
    }  
    



    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/

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


    - (void)pumpRunLoop  
    {  
        self.finishPump = NO;  
        CFRunLoopRef runLoop = CFRunLoopGetCurrent();  
        CFArrayRef runLoopModesRef =     CFRunLoopCopyAllModes(runLoop);  
        NSArray * runLoopModes = (NSArray*)runLoopModesRef;  
        while (self.finishPump == NO)  
        {  
            for (NSString *mode in runLoopModes)  
            {  
                CFStringRef modeRef = (CFStringRef)mode;  
                CFRunLoopRunInMode(modeRef, 1.0f/120.0f, false);  // Pump the loop at 120 FPS  
            }  
        }  
        CFRelease(runLoopModesRef);  
    }  
    





    作者:
    出处:http://www.cnblogs.com/ChenYilong/(点击RSS订阅)
    本文版权归作者和博客园共有,欢迎转载,
    但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    【60.97%】【BZOJ 1925】 [Sdoi2010]地精部落
    【14.06%】【hdu 5904】LCIS
    【50.40%】【BZOJ 4553】[Tjoi2016&Heoi2016]序列
    【52.55%】【BZOJ 4520】K远点对
    洛谷——P2446 [SDOI2010]大陆争霸
    Python模块之re
    Docker从入门到实战
    分析增加站点权重的四大切入点(转载)
    远程桌面连接不上|windows server 2003 sp2 termdd.sys(转载)
    不同服务器数据库之间的数据操作(转载)
  • 原文地址:https://www.cnblogs.com/ChenYilong/p/2808613.html
Copyright © 2011-2022 走看看