Esempio n. 1
0
class Driver(object):

    def __init__(self, symbolizer_path=None):
        # symbolizer_path is no longer used.
        self._lock = RLock()
        self._proc = None
        self._closed = False
        self.symbolizer = Symbolizer()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, tb):
        self.close()

    def close(self):
        if not self._closed:
            self.symbolizer.close()
        self._closed = True

    def symbolize(self, dsym_path, image_vmaddr, image_addr,
                  instruction_addr, cpu_name, uuid=None, silent=True,
                  demangle=True):
        if self._closed:
            raise RuntimeError('Symbolizer is closed')
        if not is_valid_cpu_name(cpu_name):
            raise ValueError('"%s" is not a valid cpu name' % cpu_name)
        dsym_path = normalize_dsym_path(dsym_path)

        image_vmaddr = parse_addr(image_vmaddr)
        if not image_vmaddr:
            image_vmaddr = get_macho_vmaddr(dsym_path, cpu_name) or 0

        image_addr = parse_addr(image_addr)
        instruction_addr = parse_addr(instruction_addr)

        addr = image_vmaddr + instruction_addr - image_addr

        try:
            with self._lock:
                with timedsection('symbolize'):
                    sym = self.symbolizer.symbolize(dsym_path, addr, cpu_name)
            if sym[0] is None:
                raise SymbolicationError('Symbolizer could not find symbol')
        except SymbolicationError:
            if not silent:
                raise
            sym = (None, None, 0, 0)

        symbol_name = sym[0]
        if demangle:
            symbol_name = demangle_symbol(symbol_name)

        return {
            'symbol_name': symbol_name,
            'filename': sym[1],
            'line': sym[2],
            'column': sym[3],
            'uuid': uuid,
        }
Esempio n. 2
0
class Driver(object):
    def __init__(self, symbolizer_path=None):
        # symbolizer_path is no longer used.
        self._lock = RLock()
        self._proc = None
        self._closed = False
        self.symbolizer = Symbolizer()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, tb):
        self.close()

    def close(self):
        if not self._closed:
            self.symbolizer.close()
        self._closed = True

    def symbolize(self,
                  dsym_path,
                  image_vmaddr,
                  image_addr,
                  instruction_addr,
                  cpu_name,
                  uuid=None,
                  silent=True):
        if self._closed:
            raise RuntimeError('Symbolizer is closed')
        if not is_valid_cpu_name(cpu_name):
            raise ValueError('"%s" is not a valid cpu name' % cpu_name)
        dsym_path = normalize_dsym_path(dsym_path)

        image_vmaddr = parse_addr(image_vmaddr)
        if not image_vmaddr:
            image_vmaddr = get_macho_vmaddr(dsym_path, cpu_name) or 0

        image_addr = parse_addr(image_addr)
        instruction_addr = parse_addr(instruction_addr)

        addr = image_vmaddr + instruction_addr - image_addr

        try:
            with self._lock:
                with timedsection('symbolize'):
                    sym = self.symbolizer.symbolize(dsym_path, addr, cpu_name)
            if sym[0] is None:
                raise SymbolicationError('Symbolizer could not find symbol')
        except SymbolicationError:
            if not silent:
                raise
            sym = (None, None, 0, 0)

        return {
            'symbol_name': demangle_symbol(sym[0]),
            'filename': sym[1],
            'line': sym[2],
            'column': sym[3],
            'uuid': uuid,
        }
Esempio n. 3
0
class Symbolizer(object):
    """The main symbolication driver.  This abstracts around a low level
    LLVM based symbolizer that works with DWARF files.  It's recommended to
    explicitly close the driver to ensure memory cleans up timely.
    """
    def __init__(self):
        self._lock = RLock()
        self._proc = None
        self._closed = False
        self._symbolizer = LowLevelSymbolizer()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, tb):
        self.close()

    def close(self):
        if not self._closed:
            self._symbolizer.close()
        self._closed = True

    def symbolize(self,
                  dsym_path,
                  image_vmaddr,
                  image_addr,
                  instruction_addr,
                  cpu_name,
                  symbolize_inlined=False):
        """Symbolizes a single frame based on the information provided.  If
        the symbolication fails a `SymbolicationError` is raised.

        `dsym_path` is the path to the dsym file on the file system.
        `image_vmaddr` is the slide of the image.  For most situations this
        can just be set to `0`.  If it's zero or unset we will attempt to
        find the slide from the dsym file.  `image_addr` is the canonical
        image address as loaded.  `instruction_addr` is the address where the
        error happened.

        `cpu_name` is the CPU name.  It follows general apple conventions and
        is used to special case certain behavior and look up the right
        symbols.  Common names are `armv7` and `arm64`.

        Additionally if `symbolize_inlined` is set to `True` then a list of
        frames is returned instead which might contain inlined frames.  In
        that case the return value might be an empty list instead.
        """
        if self._closed:
            raise RuntimeError('Symbolizer is closed')
        dsym_path = normalize_dsym_path(dsym_path)

        image_vmaddr = parse_addr(image_vmaddr)
        if not image_vmaddr:
            di = self._symbolizer.get_debug_info(dsym_path)
            if di is not None:
                variant = di.get_variant(cpu_name)
                if variant is not None:
                    image_vmaddr = variant.vmaddr

        image_addr = parse_addr(image_addr)
        instruction_addr = parse_addr(instruction_addr)
        if not is_valid_cpu_name(cpu_name):
            raise SymbolicationError('"%s" is not a valid cpu name' % cpu_name)

        addr = image_vmaddr + instruction_addr - image_addr

        with self._lock:
            with timedsection('symbolize'):
                if symbolize_inlined:
                    return self._symbolizer.symbolize_inlined(
                        dsym_path, addr, cpu_name)
                return self._symbolizer.symbolize(dsym_path, addr, cpu_name)