def _handle_symbolication_failed(self, e, errors=None): # User fixable but fatal errors are reported as processing # issues if e.is_user_fixable and e.is_fatal: report_processing_issue( self.data, scope='native', object='dsym:%s' % e.image_uuid, type=e.type, data=e.get_data() ) # This in many ways currently does not really do anything. # The reason is that once a processing issue is reported # the event will only be stored as a raw event and no # group will be generated. As a result it also means that # we will not have any user facing event or error showing # up at all. We want to keep this here though in case we # do not want to report some processing issues (eg: # optional difs) if errors is None: errors = self.data.setdefault('errors', []) if e.is_user_fixable or e.is_sdk_failure: errors.append(e.get_data()) else: logger.debug('Failed to symbolicate with native backend', exc_info=True)
def handle_symbolication_failed(e, data, errors=None): # User fixable but fatal errors are reported as processing # issues if e.is_user_fixable and e.is_fatal: report_processing_issue( data, scope='native', object='dsym:%s' % e.image_uuid, type=e.type, data=e.get_data() ) # This in many ways currently does not really do anything. # The reason is that once a processing issue is reported # the event will only be stored as a raw event and no # group will be generated. As a result it also means that # we will not have any user facing event or error showing # up at all. We want to keep this here though in case we # do not want to report some processing issues (eg: # optional difs) if e.is_user_fixable or e.is_sdk_failure: if errors is None: errors = data.setdefault('errors', []) errors.append(e.get_data()) else: logger.debug('Failed to symbolicate with native backend', exc_info=True)
def write_error(e, data, errors=None): # User fixable but fatal errors are reported as processing # issues. We skip this for minidumps, as reprocessing is not # possible without persisting minidumps. if e.is_user_fixable and e.is_fatal and not is_minidump_event(data): report_processing_issue(data, scope="native", object="dsym:%s" % e.image_uuid, type=e.type, data=e.get_data()) # This in many ways currently does not really do anything. # The reason is that once a processing issue is reported # the event will only be stored as a raw event and no # group will be generated. As a result it also means that # we will not have any user facing event or error showing # up at all. We want to keep this here though in case we # do not want to report some processing issues (eg: # optional difs) if e.is_user_fixable or e.is_sdk_failure: if errors is None: errors = data.setdefault("errors", []) errors.append(e.get_data()) else: logger.debug("Failed to symbolicate with native backend", exc_info=True)
def preprocess_step(self, processing_task): if not self.available: return False dif_paths = ProjectDebugFile.difcache.fetch_difs(self.project, self.images, features=["mapping"]) self.mapping_views = [] for debug_id in self.images: error_type = None dif_path = dif_paths.get(debug_id) if dif_path is None: error_type = EventError.PROGUARD_MISSING_MAPPING else: view = ProguardMapper.open(dif_path) if not view.has_line_info: error_type = EventError.PROGUARD_MISSING_LINENO else: self.mapping_views.append(view) if error_type is None: continue self.data.setdefault("_metrics", {})["flag.processing.error"] = True self.data.setdefault("errors", []).append({ "type": error_type, "mapping_uuid": debug_id }) report_processing_issue( self.data, scope="proguard", object="mapping:%s" % debug_id, type=error_type, data={"mapping_uuid": debug_id}, ) return True
def preprocess_step(self, processing_task): if not self.available: return False dif_paths = ProjectDebugFile.difcache.fetch_difs( self.project, self.images, features=['mapping']) self.mapping_views = [] for debug_id in self.images: error_type = None dif_path = dif_paths.get(debug_id) if dif_path is None: error_type = EventError.PROGUARD_MISSING_MAPPING else: view = ProguardMappingView.from_path(dif_path) if not view.has_line_info: error_type = EventError.PROGUARD_MISSING_LINENO else: self.mapping_views.append(view) if error_type is None: continue self.data.setdefault('errors', []).append({ 'type': error_type, 'mapping_uuid': debug_id, }) report_processing_issue( self.data, scope='proguard', object='mapping:%s' % debug_id, type=error_type, data={ 'mapping_uuid': debug_id, } ) return True
def preprocess_step(self, processing_task): if not self.available: return False dsym_paths = ProjectDSymFile.dsymcache.fetch_dsyms( self.project, self.images) self.mapping_views = [] for image_uuid in self.images: error_type = None dsym_path = dsym_paths.get(image_uuid) if dsym_path is None: error_type = EventError.PROGUARD_MISSING_MAPPING else: view = ProguardMappingView.from_path(dsym_path) if not view.has_line_info: error_type = EventError.PROGUARD_MISSING_LINENO else: self.mapping_views.append(view) if error_type is None: continue self.data.setdefault('errors', []).append({ 'type': error_type, 'mapping_uuid': six.text_type(image_uuid), }) report_processing_issue(self.data, scope='proguard', object='mapping:%s' % image_uuid, type=error_type, data={ 'mapping_uuid': six.text_type(image_uuid), }) return True
def preprocess_step(self, processing_task): if not self.available: return False dif_paths = ProjectDebugFile.difcache.fetch_difs( self.project, self.images, features=['mapping']) self.mapping_views = [] for debug_id in self.images: error_type = None dif_path = dif_paths.get(debug_id) if dif_path is None: error_type = EventError.PROGUARD_MISSING_MAPPING else: view = ProguardMappingView.open(dif_path) if not view.has_line_info: error_type = EventError.PROGUARD_MISSING_LINENO else: self.mapping_views.append(view) if error_type is None: continue self.data.setdefault('errors', []).append({ 'type': error_type, 'mapping_uuid': debug_id, }) report_processing_issue( self.data, scope='proguard', object='mapping:%s' % debug_id, type=error_type, data={ 'mapping_uuid': debug_id, } ) return True
def process_frame(self, processable_frame, processing_task): frame = processable_frame.frame raw_frame = dict(frame) errors = [] 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'] in_app = self.sym.is_in_app(instruction_addr, sdk_info=self.sdk_info) if in_app and raw_frame.get('function') is not None: in_app = not self.sym.is_internal_function( raw_frame['function']) if raw_frame.get('in_app') is None: raw_frame['in_app'] = in_app 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']) if not symbolicated_frames: return None, [raw_frame], [] except SymbolicationFailed as e: # User fixable but fatal errors are reported as processing # issues if e.is_user_fixable and e.is_fatal: report_processing_issue(self.data, scope='native', object='dsym:%s' % e.image_uuid, type=e.type, data=e.get_data()) # This in many ways currently does not really do anything. # The reason is that once a processing issue is reported # the event will only be stored as a raw event and no # group will be generated. As a result it also means that # we will not have any user facing event or error showing # up at all. We want to keep this here though in case we # do not want to report some processing issues (eg: # optional difs) errors = [] if e.is_user_fixable or e.is_sdk_failure: errors.append(e.get_data()) else: logger.debug('Failed to symbolicate with native backend', exc_info=True) return [raw_frame], [raw_frame], errors processable_frame.set_cache_value([in_app, symbolicated_frames]) else: # processable_frame.cache_value is present in_app, symbolicated_frames = processable_frame.cache_value raw_frame['in_app'] = in_app new_frames = [] for sfrm in symbolicated_frames: new_frame = dict(frame) new_frame['function'] = sfrm['function'] if sfrm.get('symbol'): new_frame['symbol'] = sfrm['symbol'] new_frame['abs_path'] = sfrm['abs_path'] new_frame['filename'] = sfrm.get('filename') or \ (sfrm['abs_path'] and posixpath.basename(sfrm['abs_path'])) or \ None if sfrm.get('lineno'): new_frame['lineno'] = sfrm['lineno'] if sfrm.get('colno'): new_frame['colno'] = sfrm['colno'] if sfrm.get( 'package') or processable_frame.data['obj'] is not None: new_frame['package'] = sfrm.get( 'package', processable_frame.data['obj'].name) if new_frame.get('in_app') is None: new_frame['in_app'] = in_app and \ not self.sym.is_internal_function(new_frame['function']) 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 = [] 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'] in_app = self.sym.is_in_app( instruction_addr, sdk_info=self.sdk_info ) if in_app and raw_frame.get('function') is not None: in_app = not self.sym.is_internal_function( raw_frame['function']) if raw_frame.get('in_app') is None: raw_frame['in_app'] = in_app obj_uuid = processable_frame.data['obj_uuid'] if obj_uuid is not None: self.dsyms_referenced.add(obj_uuid) try: symbolicated_frames = self.sym.symbolize_frame( instruction_addr, self.sdk_info, symbolserver_match=processable_frame.data['symbolserver_match'] ) if not symbolicated_frames: return None, [raw_frame], [] except SymbolicationFailed as e: # User fixable but fatal errors are reported as processing # issues if e.is_user_fixable and e.is_fatal: report_processing_issue( self.data, scope='native', object='dsym:%s' % e.image_uuid, type=e.type, data=e.get_data() ) # This in many ways currently does not really do anything. # The reason is that once a processing issue is reported # the event will only be stored as a raw event and no # group will be generated. As a result it also means that # we will not have any user facing event or error showing # up at all. We want to keep this here though in case we # do not want to report some processing issues (eg: # optional dsyms) errors = [] if e.is_user_fixable or e.is_sdk_failure: errors.append(e.get_data()) else: logger.debug('Failed to symbolicate with native backend', exc_info=True) return [raw_frame], [raw_frame], errors processable_frame.set_cache_value([in_app, symbolicated_frames]) else: # processable_frame.cache_value is present in_app, symbolicated_frames = processable_frame.cache_value raw_frame['in_app'] = in_app new_frames = [] for sfrm in symbolicated_frames: new_frame = dict(frame) new_frame['function'] = sfrm['function'] if sfrm.get('symbol'): new_frame['symbol'] = sfrm['symbol'] new_frame['abs_path'] = sfrm['abs_path'] new_frame['filename'] = sfrm.get('filename') or \ (sfrm['abs_path'] and posixpath.basename(sfrm['abs_path'])) or \ None if sfrm.get('lineno'): new_frame['lineno'] = sfrm['lineno'] if sfrm.get('colno'): new_frame['colno'] = sfrm['colno'] if sfrm.get('package') or processable_frame.data['obj'] is not None: new_frame['package'] = sfrm.get( 'package', processable_frame.data['obj'].name) if new_frame.get('in_app') is None: new_frame['in_app'] = in_app and \ not self.sym.is_internal_function(new_frame['function']) new_frames.append(new_frame) return new_frames, [raw_frame], []
def process_frame(self, processable_frame, processing_task): frame = processable_frame.frame errors = [] new_frames = [] raw_frame = dict(frame) 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. sym_input_frame = { 'object_name': frame.get('package'), 'instruction_addr': processable_frame.data['instruction_addr'], 'symbol_name': frame.get('function'), } in_app = self.sym.is_in_app(sym_input_frame) raw_frame['in_app'] = in_app try: symbolicated_frames = self.sym.symbolize_frame( sym_input_frame, self.sdk_info, symbolserver_match=processable_frame.data['symbolserver_match'], symbolize_inlined=True) if not symbolicated_frames: return None, [raw_frame], [] except SymbolicationFailed as e: reprocessing_active = False if self.project: reprocessing_active = bool( self.project.get_option('sentry:reprocessing_active', False) ) # User fixable but fatal errors are reported as processing # issues but only if the feature is activated. if reprocessing_active and e.is_user_fixable and e.is_fatal: report_processing_issue(self.data, scope='native', object='dsym:%s' % e.image_uuid, type=e.type, data={ 'image_path': e.image_path, 'image_uuid': e.image_uuid, 'image_arch': e.image_arch, 'message': e.message, } ) # This in many ways currently does not really do anything. # The reason is that once a processing issue is reported # the event will only be stored as a raw event and no # group will be generated. As a result it also means that # we will not have any user facing event or error showing # up at all. We want to keep this here though in case we # do not want to report some processing issues (eg: # optional dsyms) errors = [] if e.is_user_fixable or e.is_sdk_failure: errors.append({ 'type': e.type, 'image_uuid': e.image_uuid, 'image_path': e.image_path, 'image_arch': e.image_arch, 'message': e.message, }) else: logger.debug('Failed to symbolicate with native backend', exc_info=True) return [raw_frame], [raw_frame], errors processable_frame.set_cache_value([in_app, symbolicated_frames]) else: in_app, symbolicated_frames = processable_frame.cache_value raw_frame['in_app'] = in_app for sfrm in symbolicated_frames: symbol = sfrm.get('symbol_name') or \ frame.get('function') or NATIVE_UNKNOWN_STRING function = demangle_symbol(symbol, simplified=True) new_frame = dict(frame) 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'] 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['in_app'] = in_app new_frames.append(new_frame) return new_frames, [raw_frame], []
def process_frame(self, processable_frame, processing_task): frame = processable_frame.frame errors = [] new_frames = [] raw_frame = dict(frame) 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. sym_input_frame = { 'object_name': frame.get('package'), 'instruction_addr': processable_frame.data['instruction_addr'], 'symbol_name': frame.get('function'), } in_app = self.sym.is_in_app(sym_input_frame) raw_frame['in_app'] = in_app img_uuid = processable_frame.data['image_uuid'] if img_uuid is not None: self.dsyms_referenced.add(img_uuid) try: symbolicated_frames = self.sym.symbolize_frame( sym_input_frame, self.sdk_info, symbolserver_match=processable_frame. data['symbolserver_match'], symbolize_inlined=True) if not symbolicated_frames: return None, [raw_frame], [] except SymbolicationFailed as e: reprocessing_active = False if self.project: reprocessing_active = bool( self.project.get_option('sentry:reprocessing_active', False)) # User fixable but fatal errors are reported as processing # issues but only if the feature is activated. if reprocessing_active and e.is_user_fixable and e.is_fatal: report_processing_issue(self.data, scope='native', object='dsym:%s' % e.image_uuid, type=e.type, data={ 'image_path': e.image_path, 'image_uuid': e.image_uuid, 'image_arch': e.image_arch, 'message': e.message, }) # This in many ways currently does not really do anything. # The reason is that once a processing issue is reported # the event will only be stored as a raw event and no # group will be generated. As a result it also means that # we will not have any user facing event or error showing # up at all. We want to keep this here though in case we # do not want to report some processing issues (eg: # optional dsyms) errors = [] if e.is_user_fixable or e.is_sdk_failure: errors.append({ 'type': e.type, 'image_uuid': e.image_uuid, 'image_path': e.image_path, 'image_arch': e.image_arch, 'message': e.message, }) else: logger.debug('Failed to symbolicate with native backend', exc_info=True) return [raw_frame], [raw_frame], errors processable_frame.set_cache_value([in_app, symbolicated_frames]) else: in_app, symbolicated_frames = processable_frame.cache_value raw_frame['in_app'] = in_app for sfrm in symbolicated_frames: symbol = sfrm.get('symbol_name') or \ frame.get('function') or NATIVE_UNKNOWN_STRING function = demangle_symbol(symbol, simplified=True) new_frame = dict(frame) 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'] 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['in_app'] = in_app new_frames.append(new_frame) return new_frames, [raw_frame], []