def process_frame(self, processable_frame, processing_task): frame = processable_frame.frame raw_frame = dict(frame) # Ensure that package is set in the raw frame, mapped from the # debug_images array in the payload. Grouping and UI can use this path # to infer in_app and exclude frames from grouping. if raw_frame.get('package') is None: obj = processable_frame.data['obj'] raw_frame['package'] = obj and obj.code_file or None symbolicated_frames = convert_ios_symbolserver_match( processable_frame.data['instruction_addr'], processable_frame.data['symbolserver_match'] ) if not symbolicated_frames: if raw_frame.get('trust') == 'scan': return [], [raw_frame], [] else: return None, [raw_frame], [] new_frames = [] for sfrm in symbolicated_frames: new_frame = dict(raw_frame) merge_symbolicated_frame(new_frame, sfrm) new_frames.append(new_frame) return new_frames, [raw_frame], []
def process_frame(self, processable_frame, processing_task): frame = processable_frame.frame raw_frame = dict(frame) errors = [] # Ensure that package is set in the raw frame, mapped from the # debug_images array in the payload. Grouping and UI can use this path # to infer in_app and exclude frames from grouping. if raw_frame.get('package') is None: obj = processable_frame.data['obj'] raw_frame['package'] = obj and obj.code_file or None if processable_frame.cache_value is None: # Construct a raw frame that is used by the symbolizer # backend. We only assemble the bare minimum we need here. instruction_addr = processable_frame.data['instruction_addr'] debug_id = processable_frame.data['debug_id'] if debug_id is not None: self.difs_referenced.add(debug_id) try: symbolicated_frames = self.sym.symbolize_frame( instruction_addr, self.sdk_info, symbolserver_match=processable_frame. data['symbolserver_match'], symbolicator_match=processable_frame.data.get( 'symbolicator_match'), trust=raw_frame.get('trust'), ) if not symbolicated_frames: if raw_frame.get('trust') == 'scan': return [], [raw_frame], [] else: return None, [raw_frame], [] except SymbolicationFailed as e: errors = [] handle_symbolication_failed(e, data=self.data, errors=errors) return [raw_frame], [raw_frame], errors _ignored = None # Used to be in_app processable_frame.set_cache_value([_ignored, symbolicated_frames]) else: # processable_frame.cache_value is present _ignored, symbolicated_frames = processable_frame.cache_value platform = raw_frame.get('platform') or self.data.get('platform') new_frames = [] for sfrm in symbolicated_frames: new_frame = dict(raw_frame) merge_symbolicated_frame(new_frame, sfrm, platform=platform) new_frames.append(new_frame) return new_frames, [raw_frame], []
def merge_symbolicator_minidump_response(data, response): sdk_info = get_sdk_from_event(data) # TODO(markus): Add OS context here when `merge_process_state_event` is no # longer called for symbolicator projects images = [] set_path(data, 'debug_meta', 'images', value=images) for complete_image in response['modules']: image = {} merge_symbolicator_image( image, complete_image, sdk_info, lambda e: handle_symbolication_failed(e, data=data) ) images.append(image) data_threads = [] data['threads'] = {'values': data_threads} data_exception = get_path(data, 'exception', 'values', 0) for complete_stacktrace in response['stacktraces']: is_requesting = complete_stacktrace.get('is_requesting') thread_id = complete_stacktrace.get('thread_id') data_thread = { 'id': thread_id, 'crashed': is_requesting, } data_threads.append(data_thread) if is_requesting: data_stacktrace = get_path(data_exception, 'stacktrace') assert isinstance(data_stacktrace, dict), data_stacktrace # Make exemption specifically for unreal portable callstacks # TODO(markus): Allow overriding stacktrace more generically # (without looking into unreal context) once we no longer parse # minidump in the endpoint (right now we can't distinguish that # from user json). if data_stacktrace['frames'] and is_unreal_exception_stacktrace(data): continue del data_stacktrace['frames'][:] else: data_thread['stacktrace'] = data_stacktrace = {'frames': []} if complete_stacktrace.get('registers'): data_stacktrace['registers'] = complete_stacktrace['registers'] for complete_frame in reversed(complete_stacktrace['frames']): new_frame = {} merge_symbolicated_frame(new_frame, complete_frame) data_stacktrace['frames'].append(new_frame)
def merge_symbolicator_minidump_response(data, response): sdk_info = get_sdk_from_event(data) # TODO(markus): Add OS context here when `merge_process_state_event` is no # longer called for symbolicator projects images = [] set_path(data, 'debug_meta', 'images', value=images) for complete_image in response['modules']: image = {} merge_symbolicator_image( image, complete_image, sdk_info, lambda e: handle_symbolication_failed(e, data=data)) images.append(image) data_threads = [] data['threads'] = {'values': data_threads} data_exception = get_path(data, 'exception', 'values', 0) for complete_stacktrace in response['stacktraces']: is_requesting = complete_stacktrace.get('is_requesting') thread_id = complete_stacktrace.get('thread_id') data_thread = { 'id': thread_id, 'crashed': is_requesting, } data_threads.append(data_thread) if is_requesting: data_stacktrace = get_path(data_exception, 'stacktrace') assert isinstance(data_stacktrace, dict), data_stacktrace # Make exemption specifically for unreal portable callstacks # TODO(markus): Allow overriding stacktrace more generically # (without looking into unreal context) once we no longer parse # minidump in the endpoint (right now we can't distinguish that # from user json). if data_stacktrace['frames'] and is_unreal_exception_stacktrace( data): continue data_stacktrace['frames'] = [] else: data_thread['stacktrace'] = data_stacktrace = {'frames': []} if complete_stacktrace.get('registers'): data_stacktrace['registers'] = complete_stacktrace['registers'] for complete_frame in reversed(complete_stacktrace['frames']): new_frame = {} merge_symbolicated_frame(new_frame, complete_frame) data_stacktrace['frames'].append(new_frame)
def process_frame(self, processable_frame, processing_task): frame = processable_frame.frame raw_frame = dict(frame) errors = [] # Ensure that package is set in the raw frame, mapped from the # debug_images array in the payload. Grouping and UI can use this path # to infer in_app and exclude frames from grouping. if raw_frame.get('package') is None: obj = processable_frame.data['obj'] raw_frame['package'] = obj and obj.code_file or None if processable_frame.cache_value is None: # Construct a raw frame that is used by the symbolizer # backend. We only assemble the bare minimum we need here. instruction_addr = processable_frame.data['instruction_addr'] debug_id = processable_frame.data['debug_id'] if debug_id is not None: self.difs_referenced.add(debug_id) try: symbolicated_frames = self.sym.symbolize_frame( instruction_addr, self.sdk_info, symbolserver_match=processable_frame.data['symbolserver_match'], symbolicator_match=processable_frame.data.get('symbolicator_match'), trust=raw_frame.get('trust'), ) if not symbolicated_frames: if raw_frame.get('trust') == 'scan': return [], [raw_frame], [] else: return None, [raw_frame], [] except SymbolicationFailed as e: errors = [] handle_symbolication_failed(e, data=self.data, errors=errors) return [raw_frame], [raw_frame], errors _ignored = None # Used to be in_app processable_frame.set_cache_value([_ignored, symbolicated_frames]) else: # processable_frame.cache_value is present _ignored, symbolicated_frames = processable_frame.cache_value platform = raw_frame.get('platform') or self.data.get('platform') new_frames = [] for sfrm in symbolicated_frames: new_frame = dict(raw_frame) merge_symbolicated_frame(new_frame, sfrm, platform=platform) new_frames.append(new_frame) return new_frames, [raw_frame], []
def process_frame(self, processable_frame, processing_task): frame = processable_frame.frame raw_frame = dict(frame) # Ensure that package is set in the raw frame, mapped from the # debug_images array in the payload. Grouping and UI can use this path # to infer in_app and exclude frames from grouping. if raw_frame.get('package') is None: obj = processable_frame.data['obj'] raw_frame['package'] = obj and obj.code_file or None if processable_frame.cache_value is None: symbolicator_match = processable_frame.data['symbolicator_match'] if not any(x["status"] != "symbolicated" for x in symbolicator_match): symbolicated_frames = symbolicator_match else: symbolicated_frames = convert_ios_symbolserver_match( processable_frame.data['instruction_addr'], processable_frame.data['symbolserver_match'] ) if not symbolicated_frames: if raw_frame.get('trust') == 'scan': return [], [raw_frame], [] else: return None, [raw_frame], [] _ignored = None # Used to be in_app processable_frame.set_cache_value([_ignored, symbolicated_frames]) else: # processable_frame.cache_value is present _ignored, symbolicated_frames = processable_frame.cache_value new_frames = [] for sfrm in symbolicated_frames: new_frame = dict(raw_frame) merge_symbolicated_frame(new_frame, sfrm) new_frames.append(new_frame) return new_frames, [raw_frame], []
def merge_symbolicator_minidump_response(data, response): sdk_info = get_sdk_from_event(data) data['platform'] = 'native' if response.get('crashed') is not None: data['level'] = 'fatal' if response['crashed'] else 'info' if response.get('timestamp'): data['timestamp'] = float(response['timestamp']) if response.get('system_info'): merge_symbolicator_minidump_system_info(data, response['system_info']) images = [] set_path(data, 'debug_meta', 'images', value=images) for complete_image in response['modules']: image = {} merge_symbolicator_image( image, complete_image, sdk_info, lambda e: handle_symbolication_failed(e, data=data)) images.append(image) # Extract the crash reason and infos data_exception = get_path(data, 'exception', 'values', 0) exc_value = ('Assertion Error: %s' % response.get('assertion') if response.get('assertion') else 'Fatal Error: %s' % response.get('crash_reason')) data_exception['value'] = exc_value data_exception['type'] = response.get('crash_reason') data_threads = [] if response['stacktraces']: data['threads'] = {'values': data_threads} else: error = SymbolicationFailed(message='minidump has no thread list', type=EventError.NATIVE_SYMBOLICATOR_FAILED) handle_symbolication_failed(error, data=data) for complete_stacktrace in response['stacktraces']: is_requesting = complete_stacktrace.get('is_requesting') thread_id = complete_stacktrace.get('thread_id') data_thread = { 'id': thread_id, 'crashed': is_requesting, } data_threads.append(data_thread) if is_requesting: data_exception['thread_id'] = thread_id data_stacktrace = data_exception.setdefault('stacktrace', {}) # Make exemption specifically for unreal portable callstacks # TODO(markus): Allow overriding stacktrace more generically # (without looking into unreal context) once we no longer parse # minidump in the endpoint (right now we can't distinguish that # from user json). if data_stacktrace.get( 'frames') and is_unreal_exception_stacktrace(data): continue data_stacktrace['frames'] = [] else: data_thread['stacktrace'] = data_stacktrace = {'frames': []} if complete_stacktrace.get('registers'): data_stacktrace['registers'] = complete_stacktrace['registers'] for complete_frame in reversed(complete_stacktrace['frames']): new_frame = {} merge_symbolicated_frame(new_frame, complete_frame) data_stacktrace['frames'].append(new_frame)
def merge_symbolicator_minidump_response(data, response): data['platform'] = 'native' if response.get('crashed') is not None: data['level'] = 'fatal' if response['crashed'] else 'info' validate_and_set_timestamp(data, response.get('timestamp')) if response.get('system_info'): merge_symbolicator_minidump_system_info(data, response['system_info']) sdk_info = get_sdk_from_event(data) images = [] set_path(data, 'debug_meta', 'images', value=images) for complete_image in response['modules']: image = {} merge_symbolicator_image( image, complete_image, sdk_info, lambda e: write_error(e, data) ) images.append(image) # Extract the crash reason and infos data_exception = get_path(data, 'exception', 'values', 0) exc_value = ( 'Assertion Error: %s' % response.get('assertion') if response.get('assertion') else 'Fatal Error: %s' % response.get('crash_reason') ) data_exception['value'] = exc_value data_exception['type'] = response.get('crash_reason') data_threads = [] if response['stacktraces']: data['threads'] = {'values': data_threads} else: error = SymbolicationFailed(message='minidump has no thread list', type=EventError.NATIVE_SYMBOLICATOR_FAILED) write_error(error, data) for complete_stacktrace in response['stacktraces']: is_requesting = complete_stacktrace.get('is_requesting') thread_id = complete_stacktrace.get('thread_id') data_thread = { 'id': thread_id, 'crashed': is_requesting, } data_threads.append(data_thread) if is_requesting: data_exception['thread_id'] = thread_id data_stacktrace = data_exception.setdefault('stacktrace', {}) data_stacktrace['frames'] = [] else: data_thread['stacktrace'] = data_stacktrace = {'frames': []} if complete_stacktrace.get('registers'): data_stacktrace['registers'] = complete_stacktrace['registers'] for complete_frame in reversed(complete_stacktrace['frames']): new_frame = {} merge_symbolicated_frame(new_frame, complete_frame) data_stacktrace['frames'].append(new_frame)
def process_payload(data): project = Project.objects.get_from_cache(id=data['project']) task_id_cache_key = task_id_cache_key_for_event(data) symbolicator = Symbolicator( project=project, task_id_cache_key=task_id_cache_key ) stacktrace_infos = [ stacktrace for stacktrace in find_stacktraces_in_data(data) if any(is_native_platform(x) for x in stacktrace.platforms) ] stacktraces = [ { 'registers': sinfo.stacktrace.get('registers') or {}, 'frames': [ f for f in reversed(sinfo.stacktrace.get('frames') or ()) if _handles_frame(data, f) ] } for sinfo in stacktrace_infos ] if not any(stacktrace['frames'] for stacktrace in stacktraces): return modules = native_images_from_data(data) response = symbolicator.process_payload(stacktraces=stacktraces, modules=modules) assert len(modules) == len(response['modules']), (modules, response) sdk_info = get_sdk_from_event(data) for raw_image, complete_image in zip(modules, response['modules']): merge_symbolicator_image( raw_image, complete_image, sdk_info, lambda e: write_error( e, data)) assert len(stacktraces) == len(response['stacktraces']), (stacktraces, response) for sinfo, complete_stacktrace in zip(stacktrace_infos, response['stacktraces']): complete_frames_by_idx = {} for complete_frame in complete_stacktrace.get('frames') or (): complete_frames_by_idx \ .setdefault(complete_frame['original_index'], []) \ .append(complete_frame) new_frames = [] native_frames_idx = 0 for raw_frame in reversed(sinfo.stacktrace['frames']): if not _handles_frame(data, raw_frame): new_frames.append(raw_frame) continue for complete_frame in complete_frames_by_idx.get(native_frames_idx) or (): merged_frame = dict(raw_frame) merge_symbolicated_frame(merged_frame, complete_frame) if merged_frame.get('package'): raw_frame['package'] = merged_frame['package'] new_frames.append(merged_frame) native_frames_idx += 1 if sinfo.container is not None and native_frames_idx > 0: sinfo.container['raw_stacktrace'] = { 'frames': list(sinfo.stacktrace['frames']), 'registers': sinfo.stacktrace.get('registers') } new_frames.reverse() sinfo.stacktrace['frames'] = new_frames return data