# Path: symsynd/exceptions.py
# class SymbolicationError(Exception):
#     message = None
# 
#     def __init__(self, message):
#         if isinstance(message, bytes):
#             message = message.decode('utf-8', 'replace')
#         Exception.__init__(self, message)
#         self.message = message
# 
#     def __str__(self):
#         return self.message.encode('utf-8')
# 
#     def __unicode__(self):
#         return self.message
# 
# Path: symsynd/libdebug.py
# class DebugInfo(object):
# 
#     def __init__(self):
#         raise TypeError('Cannot instanciate debug infos')
# 
#     @staticmethod
#     def _from_ptr(ptr):
#         rv = object.__new__(DebugInfo)
#         rv._ptr = ptr
#         return rv
# 
#     @staticmethod
#     def open_path(path):
#         di = rustcall(_lib.debug_info_open_path, to_bytes(path))
#         return DebugInfo._from_ptr(di)
# 
#     def _get_ptr(self):
#         if self._ptr is None:
#             raise RuntimeError('Debug info closed')
#         return self._ptr
# 
#     def get_compilation_dir(self, cpu_name, path):
#         ptr = self._get_ptr()
# 
#         try:
#             rv = rustcall(_lib.debug_info_get_compilation_dir,
#                           ptr, to_bytes(cpu_name), to_bytes(path))
#             rv = _ffi.string(rv)
#             if isinstance(path, text_type):
#                 rv = rv.decode('utf-8')
#             return rv
#         except exceptions.DwarfLookupError:
#             pass
# 
#     def get_variants(self):
#         ptr = self._get_ptr()
#         count = _ffi.new('int *')
#         arr = rustcall(_lib.debug_info_get_variants, ptr, count)
#         return [Variant(arr[x]) for x in range(count[0])]
# 
#     def get_variant(self, uuid_or_cpu_name):
#         if isinstance(uuid_or_cpu_name, uuid.UUID):
#             id = uuid_or_cpu_name
#             cpu_name = None
#         else:
#             try:
#                 id = uuid.UUID(uuid_or_cpu_name)
#                 cpu_name = None
#             except ValueError:
#                 id = None
#                 cpu_name = uuid_or_cpu_name
#         for variant in self.get_variants():
#             if (id is not None and variant.uuid == id) or \
#                (cpu_name is not None and variant.cpu_name == cpu_name):
#                 return variant
# 
#     def close(self):
#         if self._ptr:
#             _lib.debug_info_free(self._ptr)
#         self._ptr = None
# 
#     def __del__(self):
#         try:
#             self.close()
#         except Exception:
#             pass
# 
# Path: symsynd/_compat.py
# PY2 = sys.version_info[0] == 2
# def to_bytes(x):


import os
import posixpath
from threading import Lock
from symsynd.exceptions import SymbolicationError
from symsynd.libdebug import DebugInfo
from symsynd._symbolizer import ffi
from symsynd._compat import to_bytes, itervalues
            'symbol': symbol,
            'filename': filename,
            'abs_path': abs_path,
            'lineno': struct.lineno,
            'colno': struct.column,
        }

    def symbolize(self, dsym_path, offset, cpu_name, is_data=False):
        if self._ptr is None:
            raise RuntimeError('Symbolizer closed')

        rv = lib.llvm_symbolizer_symbolize(
            self._ptr, to_bytes(dsym_path + ':' + cpu_name),
            offset, is_data and 1 or 0)
        try:
            if rv.error:
                raise SymbolicationError(_symstr(rv.error))

            return self._make_frame(dsym_path, cpu_name, rv)
        finally:
            lib.llvm_symbol_free(rv)

    def symbolize_inlined(self, dsym_path, offset, cpu_name):
        if self._ptr is None:
            raise RuntimeError('Symbolizer closed')

        sym_out = ffi.new('llvm_symbol_t ***')
        sym_count_out = ffi.new('size_t *')

        err = lib.llvm_symbolizer_symbolize_inlined(

# Path: symsynd/exceptions.py
# class SymbolicationError(Exception):
#     message = None
# 
#     def __init__(self, message):
#         if isinstance(message, bytes):
#             message = message.decode('utf-8', 'replace')
#         Exception.__init__(self, message)
#         self.message = message
# 
#     def __str__(self):
#         return self.message.encode('utf-8')
# 
#     def __unicode__(self):
#         return self.message
# 
# Path: symsynd/libdebug.py
# class DebugInfo(object):
# 
#     def __init__(self):
#         raise TypeError('Cannot instanciate debug infos')
# 
#     @staticmethod
#     def _from_ptr(ptr):
#         rv = object.__new__(DebugInfo)
#         rv._ptr = ptr
#         return rv
# 
#     @staticmethod
#     def open_path(path):
#         di = rustcall(_lib.debug_info_open_path, to_bytes(path))
#         return DebugInfo._from_ptr(di)
# 
#     def _get_ptr(self):
#         if self._ptr is None:
#             raise RuntimeError('Debug info closed')
#         return self._ptr
# 
#     def get_compilation_dir(self, cpu_name, path):
#         ptr = self._get_ptr()
# 
#         try:
#             rv = rustcall(_lib.debug_info_get_compilation_dir,
#                           ptr, to_bytes(cpu_name), to_bytes(path))
#             rv = _ffi.string(rv)
#             if isinstance(path, text_type):
#                 rv = rv.decode('utf-8')
#             return rv
#         except exceptions.DwarfLookupError:
#             pass
# 
#     def get_variants(self):
#         ptr = self._get_ptr()
#         count = _ffi.new('int *')
#         arr = rustcall(_lib.debug_info_get_variants, ptr, count)
#         return [Variant(arr[x]) for x in range(count[0])]
# 
#     def get_variant(self, uuid_or_cpu_name):
#         if isinstance(uuid_or_cpu_name, uuid.UUID):
#             id = uuid_or_cpu_name
#             cpu_name = None
#         else:
#             try:
#                 id = uuid.UUID(uuid_or_cpu_name)
#                 cpu_name = None
#             except ValueError:
#                 id = None
#                 cpu_name = uuid_or_cpu_name
#         for variant in self.get_variants():
#             if (id is not None and variant.uuid == id) or \
#                (cpu_name is not None and variant.cpu_name == cpu_name):
#                 return variant
# 
#     def close(self):
#         if self._ptr:
#             _lib.debug_info_free(self._ptr)
#         self._ptr = None
# 
#     def __del__(self):
#         try:
#             self.close()
#         except Exception:
#             pass
# 
# Path: symsynd/_compat.py
# PY2 = sys.version_info[0] == 2
# def to_bytes(x):


# Path: symsynd/libsymbolizer.py
import os
import posixpath
from threading import Lock
from symsynd.exceptions import SymbolicationError
from symsynd.libdebug import DebugInfo
from symsynd._symbolizer import ffi
from symsynd._compat import to_bytes, itervalues

            'symbol': symbol,
            'filename': filename,
            'abs_path': abs_path,
            'lineno': struct.lineno,
            'colno': struct.column,
        }

    def symbolize(self, dsym_path, offset, cpu_name, is_data=False):
        if self._ptr is None:
            raise RuntimeError('Symbolizer closed')

        rv = lib.llvm_symbolizer_symbolize(
            self._ptr, to_bytes(dsym_path + ':' + cpu_name),
            offset, is_data and 1 or 0)
        try:
            if rv.error:
                raise SymbolicationError(_symstr(rv.error))

            return self._make_frame(dsym_path, cpu_name, rv)
        finally:
            lib.llvm_symbol_free(rv)

    def symbolize_inlined(self, dsym_path, offset, cpu_name):
        if self._ptr is None:
            raise RuntimeError('Symbolizer closed')

        sym_out = ffi.new('llvm_symbol_t ***')
        sym_count_out = ffi.new('size_t *')

        err = lib.llvm_symbolizer_symbolize_inlined(

            self._ptr, to_bytes(dsym_path + ':' + cpu_name),