Example #1
0
def main(argv):
    parser = OptionParser()
    parser.add_option('-v', '--verbose', action='store_true', dest='verbose', \
                        help='increase verbosity')
    parser.add_option('--pid', type='int', help='process id')
    parser.add_option('--pname', help='process name')
    parser.add_option('--log-file', dest='logfile',  default='pyumdh.log',  \
            help='log file (default is %default)')
    opts, args = parser.parse_args(argv)

    binpath = utils.module_path()
    # load configuration and map its contents to a dict so that we could later
    # merge stock options with any dynamic content
    configpath = os.path.join(binpath, 'config.py')
    if os.path.exists(configpath):
        extconfig = imp.load_source('config', configpath)
        configopts = utils.Attributify(extconfig)
    else:
        configopts = utils.Attributify(config)

    log = logging.getLogger('umdh')
    log.addHandler(logging.StreamHandler())
    if opts.logfile:
        log.addHandler(logging.FileHandler(opts.logfile))
    if opts.verbose:
        log.setLevel(logging.DEBUG)

    datadir = utils.data_dir(configopts.get('WORK_DIR', binpath))
    log.debug('data files are here=%s' % datadir)

    configerrors = []

    if not configopts['DBG_BIN_PATHS']:
        log.warning('You might want to provide path to your application ' \
                    'binaries for symbol lookup to work best\n(configure ' \
                    'DBG_BIN_PATHS)')
    if not configopts['DBG_SYMBOL_PATHS']:
        log.warning('You might want to configure symbol paths for UMDH ' \
                'in DBG_SYMBOL_PATHS')
    if not configopts['DBG_TOOLS_PATH']:
        configerrors.append('You have to provide path to debugging tools for ' \
                'windows in DBG_TOOLS_PATH')

    if configerrors:
        error = '\n'.join(configerrors)
        log.critical(error)
        print 'If it is your first time running, please take time ' \
                'to go over config.py'
        return 1

    # check if any .cache files are available
    # cache files are a handy way to continue working on a particular active
    # umdh session
    cachefiles = [fn for fn in os.listdir(datadir) if fnmatch(fn, '.cache.py')]

    if not cachefiles and not opts.pid and not opts.pname:
        print 'Specify either process name or process id'
        parser.print_help()
        return 2

    if opts.pid or opts.pname:
        # if only process name has been specified, look up its pid
        pid = opts.pid or _find_pid(opts.pname, configopts)
    elif cachefiles:
        # currently, it makes sense to only handle a single cache file
        # i.e. file for the current session
        fn = cachefiles.pop()
        cachedconfig = imp.load_source('config', os.path.join(datadir, fn))
        cachedopts = utils.Attributify(cachedconfig)
        configopts.update(cachedopts)
        pid = int(configopts['active_pid'])
    umdh(pid, configopts)
    return 0
Example #2
0
def main(argv):
    parser = OptionParser()
    parser.add_option('-v', '--verbose', action='store_true', dest='verbose', \
                        help='increase verbosity')
    parser.add_option('--pid', type='int', help='process id')
    parser.add_option('--pname', help='process name')
    parser.add_option('--log-file', dest='logfile',  default='pyumdh.log',  \
            help='log file (default is %default)')
    opts, args = parser.parse_args(argv)

    binpath = utils.module_path()
    # load configuration and map its contents to a dict so that we could later
    # merge stock options with any dynamic content
    configpath = os.path.join(binpath, 'config.py')
    if os.path.exists(configpath):
        extconfig = imp.load_source('config', configpath)
        configopts = utils.Attributify(extconfig)
    else:
        configopts = utils.Attributify(config)

    log = logging.getLogger('umdh')
    log.addHandler(logging.StreamHandler())
    if opts.logfile:
        log.addHandler(logging.FileHandler(opts.logfile))
    if opts.verbose:
        log.setLevel(logging.DEBUG)

    datadir = utils.data_dir(configopts.get('WORK_DIR', binpath))
    log.debug('data files are here=%s' % datadir)

    configerrors = []

    if not configopts['DBG_BIN_PATHS']:
        log.warning('You might want to provide path to your application ' \
                    'binaries for symbol lookup to work best\n(configure ' \
                    'DBG_BIN_PATHS)')
    if not configopts['DBG_SYMBOL_PATHS']:
        log.warning('You might want to configure symbol paths for UMDH ' \
                'in DBG_SYMBOL_PATHS')
    if not configopts['DBG_TOOLS_PATH']:
        configerrors.append('You have to provide path to debugging tools for ' \
                'windows in DBG_TOOLS_PATH')

    if configerrors:
        error = '\n'.join(configerrors)
        log.critical(error)
        print 'If it is your first time running, please take time ' \
                'to go over config.py'
        return 1

    # check if any .cache files are available
    # cache files are a handy way to continue working on a particular active
    # umdh session
    cachefiles = [fn for fn in os.listdir(datadir) if fnmatch(fn, '.cache.py')]

    if not cachefiles and not opts.pid and not opts.pname:
        print 'Specify either process name or process id'
        parser.print_help()
        return 2

    if opts.pid or opts.pname:
        # if only process name has been specified, look up its pid
        pid = opts.pid or _find_pid(opts.pname, configopts)
    elif cachefiles:
        # currently, it makes sense to only handle a single cache file
        # i.e. file for the current session
        fn = cachefiles.pop()
        cachedconfig = imp.load_source('config', os.path.join(datadir, fn))
        cachedopts = utils.Attributify(cachedconfig)
        configopts.update(cachedopts)
        pid = int(configopts['active_pid'])
    umdh(pid, configopts)
    return 0
Example #3
0
_USAGE = """
Syntax: differ[.py] [options] [datafile1] [datafile2]

--data-file options are optional, data files can be specified w/o
qualification. More over, you can specify data files by their indices:
    differ 0 1 --out-file data\\0_1.log

Will match data\\[pid]_snapshot_0.log and data\\[pid]_snapshot_1.log in the
`data' working directory if pid can be read from the cached configuration
(data\.cache.py).
"""

if __name__ == '__main__':
    freeze_support()

    binpath = utils.module_path()
    # load configuration and map its contents to a dict so that we could later
    # merge stock options with any dynamic content
    configpath = os.path.join(binpath, 'config.py')
    if os.path.exists(configpath):
        extconfig = imp.load_source('config', configpath)
        config = utils.Attributify(extconfig)
    else:
        config = utils.Attributify(config)

    parser = OptionParser()
    parser.add_option('--data-file', dest='logs', action='append', \
            default=[], \
            help='specify memory logs to diff; at (least and most) two are ' \
                    'required')
    parser.add_option('--out-file', dest='outfile', \
Example #4
0
        self._path = []
        super(WindowsLibraryLoader, self).__init__(*args, **kwargs)

    def add_path(self, fpath):
        self._path.append(fpath)

    def __getattr__(self, name):
        if name[0] == '_':
            raise AttributeError(name)
        dll = self._dlltype(name, self._path)
        setattr(self, name, dll)
        return dll


wdll = WindowsLibraryLoader(WindowsLibrary)
wdll.add_path(os.path.join(utils.module_path(), 'x64' if _win64() else 'x86'))

from logging import getLogger


class WinDll(WinDLL):
    """
    Implements a windows library type that wraps all calls to provide error logging
    and throws WinError if a wrapped function call fails.
    Default error checking assumes that the wrapped api call returns zero in case of
    errors.
    This behaviour can be overriden by providing a callable to check for error
    condition:
        api_fn.errfn = lambda ret, args: check(ret)
    This also provides the ability to bypass error checking by providing a
    function to check errors that always defaults to True
Example #5
0
class WindowsLibraryLoader(LibraryLoader):
    def __init__(self, *args, **kwargs):
        self._path = []
        super(WindowsLibraryLoader, self).__init__(*args, **kwargs)
    def add_path(self, fpath):
        self._path.append(fpath)
    def __getattr__(self, name):
        if name[0] == '_':
            raise AttributeError(name)
        dll = self._dlltype(name, self._path)
        setattr(self, name, dll)
        return dll

wdll = WindowsLibraryLoader(WindowsLibrary)
wdll.add_path(os.path.join(utils.module_path(), 'x64' if _win64() else 'x86'))


from logging import getLogger

class WinDll(WinDLL):
    """
    Implements a windows library type that wraps all calls to provide error logging
    and throws WinError if a wrapped function call fails.
    Default error checking assumes that the wrapped api call returns zero in case of
    errors.
    This behaviour can be overriden by providing a callable to check for error
    condition:
        api_fn.errfn = lambda ret, args: check(ret)
    This also provides the ability to bypass error checking by providing a
    function to check errors that always defaults to True