Debugging.py :  » Development » PyObjC » trunk » pyobjc » pyobjc-framework-ExceptionHandling » Lib » PyObjCTools » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Development » PyObjC 
PyObjC » trunk » pyobjc » pyobjc framework ExceptionHandling » Lib » PyObjCTools » Debugging.py
"""
Low level debugging helper for PyObjC.

Allows you to log Python and ObjC (via atos) stack traces for NSExceptions
raised.

General guidelines for use:

- It's typically only useful when you log EVERY exception, because Foundation
  and AppKit will swallow most of them.  This means that you should never
  use this module in a release build.

- Typical use involves only calling installDebuggingHandler or
  installVerboseDebuggingHandler.  It may be removed at any time by calling
  removeDebuggingHandler.
"""

from Foundation import NSObject,NSLog
import objc
import os
import sys

import traceback
from ExceptionHandling import NSExceptionHandler,NSLogUncaughtExceptionMask,NSLogAndHandleEveryExceptionMask,NSStackTraceKey

DEFAULTMASK = NSLogUncaughtExceptionMask
EVERYTHINGMASK = NSLogAndHandleEveryExceptionMask


__all__ = [
    'LOGSTACKTRACE', 'DEFAULTVERBOSITY', 'DEFAULTMASK', 'EVERYTHINGMASK',
    'installDebuggingHandler', 'installVerboseDebuggingHandler',
    'installPythonExceptionHandler', 'removeDebuggingHandler',
    'handlerInstalled',
]

def isPythonException(exception):
    return (exception.userInfo() or {}).get(u'__pyobjc_exc_type__') is not None

def nsLogPythonException(exception):
    userInfo = exception.userInfo()
    NSLog(u'*** Python exception discarded!\n' +
        ''.join(traceback.format_exception(
        userInfo[u'__pyobjc_exc_type__'],
        userInfo[u'__pyobjc_exc_value__'],
        userInfo[u'__pyobjc_exc_traceback__'],
    )).decode('utf8'))
    # we logged it, so don't log it for us
    return False

def nsLogObjCException(exception):
    userInfo = exception.userInfo()
    stack = userInfo.get(NSStackTraceKey)
    if not stack or not os.path.exists('/usr/bin/atos'):
        return True
    pipe = os.popen('/usr/bin/atos -p %d %s' % (os.getpid(), stack))
    stacktrace = pipe.readlines()
    stacktrace.reverse()
    NSLog(u"*** ObjC exception '%s' (reason: '%s') discarded\n" % (
            exception.name(), exception.reason(),
        ) +
        u'Stack trace (most recent call last):\n' +
        ''.join([('  '+line) for line in stacktrace]).decode('utf8')
    )
    return False

LOGSTACKTRACE = 1 << 0
DEFAULTVERBOSITY = 0

class PyObjCDebuggingDelegate(NSObject):
    verbosity = objc.ivar('verbosity', 'i')
    
    def initWithVerbosity_(self, verbosity):
        self = self.init()
        self.verbosity = verbosity
        return self

    def exceptionHandler_shouldLogException_mask_(self, sender, exception, aMask):
        try:
            if isPythonException(exception):
                if self.verbosity & LOGSTACKTRACE:
                    nsLogObjCException(exception)
                return nsLogPythonException(exception)
            elif self.verbosity & LOGSTACKTRACE:
                return nsLogObjCException(exception)
            else:
                return False
        except:
            print >>sys.stderr, "*** Exception occurred during exception handler ***"
            traceback.print_exc(sys.stderr)
            return True
    exceptionHandler_shouldLogException_mask_ = objc.selector(exceptionHandler_shouldLogException_mask_, signature='c@:@@I')

    def exceptionHandler_shouldHandleException_mask_(self, sender, exception, aMask):
        return False
    exceptionHandler_shouldHandleException_mask_ = objc.selector(exceptionHandler_shouldHandleException_mask_, signature='c@:@@I')

def installExceptionHandler(verbosity=DEFAULTVERBOSITY, mask=DEFAULTMASK):
    """
    Install the exception handling delegate that will log every exception
    matching the given mask with the given verbosity.
    """
    # we need to retain this, cause the handler doesn't
    global _exceptionHandlerDelegate
    delegate = PyObjCDebuggingDelegate.alloc().initWithVerbosity_(verbosity)
    NSExceptionHandler.defaultExceptionHandler().setExceptionHandlingMask_(mask)
    NSExceptionHandler.defaultExceptionHandler().setDelegate_(delegate)
    _exceptionHandlerDelegate = delegate

def installPythonExceptionHandler():
    """
    Install a verbose exception handling delegate that logs every exception
    raised.

    Will log only Python stack traces, if available.
    """
    installExceptionHandler(verbosity=DEFAULTVERBOSITY, mask=EVERYTHINGMASK)

def installVerboseExceptionHandler():
    """
    Install a verbose exception handling delegate that logs every exception
    raised.

    Will log both Python and ObjC stack traces, if available.
    """
    installExceptionHandler(verbosity=LOGSTACKTRACE, mask=EVERYTHINGMASK)

def removeExceptionHandler():
    """
    Remove the current exception handler delegate
    """
    NSExceptionHandler.defaultExceptionHandler().setDelegate_(None)
    NSExceptionHandler.defaultExceptionHandler().setExceptionHandlingMask_(0)

def handlerInstalled():
    """
    Is an exception handler delegate currently installed?
    """
    return NSExceptionHandler.defaultExceptionHandler().delegate() is not None
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.