Exemple #1
0
def resolve_frame_symbols(data):
    debug_meta = data['debug_meta']
    debug_images = debug_meta['images']
    sdk_info = get_sdk_from_event(data)

    stacktraces = find_all_stacktraces(data)
    if not stacktraces:
        return

    project = Project.objects.get_from_cache(
        id=data['project'],
    )

    errors = []
    referenced_images = find_stacktrace_referenced_images(
        debug_images, [x[0] for x in stacktraces])
    sym = Symbolizer(project, debug_images,
                     referenced_images=referenced_images)

    frame = None
    idx = -1

    def report_error(e):
        errors.append({
            'type': EventError.NATIVE_INTERNAL_FAILURE,
            'frame': frame,
            'error': 'frame #%d: %s: %s' % (
                idx,
                e.__class__.__name__,
                six.text_type(e),
            )
        })

    with sym:
        for stacktrace, container in stacktraces:
            store_raw = False

            new_frames = list(stacktrace['frames'])
            for idx, frame in enumerate(stacktrace['frames']):
                if 'image_addr' not in frame or \
                   'instruction_addr' not in frame or \
                   'symbol_addr' not in frame:
                    continue
                try:
                    sfrm = sym.symbolize_frame({
                        'object_name': frame.get('package'),
                        'object_addr': frame['image_addr'],
                        'instruction_addr': frame['instruction_addr'],
                        'symbol_addr': frame['symbol_addr'],
                    }, sdk_info, report_error=report_error)
                    if not sfrm:
                        continue
                    new_frame = dict(frame)
                    # XXX: log here if symbol could not be found?
                    symbol = sfrm.get('symbol_name') or \
                        new_frame.get('function') or '<unknown>'
                    function = demangle_symbol(symbol, simplified=True)

                    new_frame['function'] = function

                    # If we demangled something, store the original in the
                    # symbol portion of the frame
                    if function != symbol:
                        new_frame['symbol'] = symbol

                    new_frame['abs_path'] = sfrm.get('filename') or None
                    if new_frame['abs_path']:
                        new_frame['filename'] = posixpath.basename(new_frame['abs_path'])
                    if sfrm.get('line') is not None:
                        new_frame['lineno'] = sfrm['line']
                    else:
                        new_frame['instruction_offset'] = \
                            parse_addr(sfrm['instruction_addr']) - \
                            parse_addr(sfrm['symbol_addr'])
                    if sfrm.get('column') is not None:
                        new_frame['colno'] = sfrm['column']
                    new_frame['package'] = sfrm['object_name'] or new_frame.get('package')
                    new_frame['symbol_addr'] = '0x%x' % parse_addr(sfrm['symbol_addr'])
                    new_frame['instruction_addr'] = '0x%x' % parse_addr(
                        sfrm['instruction_addr'])
                    new_frame['in_app'] = is_in_app(new_frame)

                    if new_frame != frame:
                        new_frames[idx] = new_frame
                        store_raw = True
                except Exception:
                    logger.exception('Failed to symbolicate')
                    errors.append({
                        'type': EventError.NATIVE_INTERNAL_FAILURE,
                        'error': 'The symbolicator encountered an internal failure',
                    })

            # Remember the raw stacktrace.
            if store_raw and container is not None:
                container['raw_stacktrace'] = {
                    'frames': stacktrace['frames'],
                }

            # Put the new frames in
            stacktrace['frames'] = new_frames

    if errors:
        data.setdefault('errors', []).extend(errors)

    return data
Exemple #2
0
def resolve_frame_symbols(data):
    debug_meta = data.get('debug_meta')
    if not debug_meta:
        return

    debug_images = debug_meta['images']
    sdk_info = get_sdk_from_event(data)

    stacktraces = find_all_stacktraces(data)
    if not stacktraces:
        return

    project = Project.objects.get_from_cache(
        id=data['project'],
    )

    errors = []
    referenced_images = find_stacktrace_referenced_images(
        debug_images, stacktraces)
    sym = Symbolizer(project, debug_images,
                     referenced_images=referenced_images)

    frame = None
    idx = -1

    def report_error(e):
        errors.append({
            'type': EventError.NATIVE_INTERNAL_FAILURE,
            'frame': frame,
            'error': 'frame #%d: %s: %s' % (
                idx,
                e.__class__.__name__,
                six.text_type(e),
            )
        })

    longest_addr = 0
    processed_frames = []
    with sym:
        for stacktrace in stacktraces:
            for idx, frame in enumerate(stacktrace['frames']):
                if 'image_addr' not in frame or \
                   'instruction_addr' not in frame or \
                   'symbol_addr' not in frame:
                    continue
                try:
                    sfrm = sym.symbolize_frame({
                        'object_name': frame.get('package'),
                        'object_addr': frame['image_addr'],
                        'instruction_addr': frame['instruction_addr'],
                        'symbol_addr': frame['symbol_addr'],
                    }, sdk_info, report_error=report_error)
                    if not sfrm:
                        continue
                    # XXX: log here if symbol could not be found?
                    frame['function'] = sfrm.get('symbol_name') or \
                        frame.get('function') or '<unknown>'
                    frame['abs_path'] = sfrm.get('filename') or None
                    if frame['abs_path']:
                        frame['filename'] = posixpath.basename(frame['abs_path'])
                    if sfrm.get('line') is not None:
                        frame['lineno'] = sfrm['line']
                    else:
                        frame['instruction_offset'] = \
                            parse_addr(sfrm['instruction_addr']) - \
                            parse_addr(sfrm['symbol_addr'])
                    if sfrm.get('column') is not None:
                        frame['colno'] = sfrm['column']
                    frame['package'] = sfrm['object_name'] or frame.get('package')
                    frame['symbol_addr'] = '0x%x' % parse_addr(sfrm['symbol_addr'])
                    frame['instruction_addr'] = '0x%x' % parse_addr(
                        sfrm['instruction_addr'])
                    frame['in_app'] = is_in_app(frame)
                    longest_addr = max(longest_addr, len(frame['symbol_addr']),
                                       len(frame['instruction_addr']))
                    processed_frames.append(frame)
                except Exception:
                    logger.exception('Failed to symbolicate')
                    errors.append({
                        'type': EventError.NATIVE_INTERNAL_FAILURE,
                        'error': 'The symbolicator encountered an internal failure',
                    })

    # Pad out addresses to be of the same length
    for frame in processed_frames:
        for key in 'symbol_addr', 'instruction_addr':
            frame[key] = '0x' + frame[key][2:].rjust(longest_addr - 2, '0')

    if errors:
        data.setdefault('errors', []).extend(errors)

    return data
Exemple #3
0
def resolve_frame_symbols(data):
    debug_meta = data['debug_meta']
    debug_images = debug_meta['images']
    sdk_info = get_sdk_from_event(data)

    stacktraces = find_all_stacktraces(data)
    if not stacktraces:
        return

    project = Project.objects.get_from_cache(
        id=data['project'],
    )

    errors = []
    referenced_images = find_stacktrace_referenced_images(
        debug_images, [x[0] for x in stacktraces])
    sym = Symbolizer(project, debug_images,
                     referenced_images=referenced_images)

    frame = None
    idx = -1

    def report_error(exc_type, exc_value, tb):
        if exc_value.is_user_fixable or exc_value.is_sdk_failure:
            errors.append({
                'type': EventError.NATIVE_INTERNAL_FAILURE,
                'frame': frame,
                'error': u'frame #%d: %s' % (idx, exc_value)
            })
        if not exc_value.is_user_fixable:
            logger.debug('Failed to symbolicate',
                         exc_info=(exc_type, exc_value, tb))

    with sym:
        for stacktrace, container in stacktraces:
            store_raw = False

            new_frames = list(stacktrace['frames'])
            for idx, frame in enumerate(stacktrace['frames']):
                if 'image_addr' not in frame or \
                   'instruction_addr' not in frame or \
                   'symbol_addr' not in frame:
                    continue
                try:
                    # Construct a raw frame that is used by the symbolizer
                    # backend.
                    raw_frame = {
                        'object_name': frame.get('package'),
                        'object_addr': frame['image_addr'],
                        'instruction_addr': frame['instruction_addr'],
                        'symbol_addr': frame['symbol_addr'],
                    }
                    new_frame = dict(frame)

                    try:
                        sfrm = sym.symbolize_frame(raw_frame, sdk_info)
                    except SymbolicationFailed:
                        report_error(*sys.exc_info())
                    else:
                        symbol = sfrm.get('symbol_name') or \
                            new_frame.get('function') or '<unknown>'
                        function = demangle_symbol(symbol, simplified=True)

                        new_frame['function'] = function

                        # If we demangled something, store the original in the
                        # symbol portion of the frame
                        if function != symbol:
                            new_frame['symbol'] = symbol

                        new_frame['abs_path'] = sfrm.get('filename') or None
                        if new_frame['abs_path']:
                            new_frame['filename'] = posixpath.basename(
                                new_frame['abs_path'])
                        if sfrm.get('line') is not None:
                            new_frame['lineno'] = sfrm['line']
                        else:
                            new_frame['instruction_offset'] = \
                                parse_addr(sfrm['instruction_addr']) - \
                                parse_addr(sfrm['symbol_addr'])
                        if sfrm.get('column') is not None:
                            new_frame['colno'] = sfrm['column']
                        new_frame['package'] = sfrm['object_name'] \
                            or new_frame.get('package')
                        new_frame['symbol_addr'] = '0x%x' % \
                            parse_addr(sfrm['symbol_addr'])
                        new_frame['instruction_addr'] = '0x%x' % parse_addr(
                            sfrm['instruction_addr'])

                    new_frame['in_app'] = sym.is_in_app(raw_frame)
                    if new_frame != frame:
                        new_frames[idx] = new_frame
                        store_raw = True
                except Exception:
                    logger.exception('Failed to symbolicate')
                    errors.append({
                        'type': EventError.NATIVE_INTERNAL_FAILURE,
                        'error': 'The symbolicator encountered an internal failure',
                    })

            # Remember the raw stacktrace.
            if store_raw and container is not None:
                container['raw_stacktrace'] = {
                    'frames': stacktrace['frames'],
                }

            # Put the new frames in
            stacktrace['frames'] = new_frames

    if errors:
        data.setdefault('errors', []).extend(errors)

    return data