def test_merge_apple_crash_report(self): with open(get_unreal_crash_apple_file(), 'rb') as f: event = {'event_id': MOCK_EVENT_ID} unreal_crash = process_unreal_crash(f.read(), None, None, event) merge_apple_crash_report(unreal_crash.get_apple_crash_report(), event) self.insta_snapshot(event)
def test_merge_apple_crash_report(self): with open(get_unreal_crash_apple_file(), 'rb') as f: event = {} unreal_crash = process_unreal_crash(f.read(), None, None, event) merge_apple_crash_report(unreal_crash.get_apple_crash_report(), event) assert event['platform'] == 'native' assert event['timestamp'] == '2019-01-09T17:44:22Z' assert event['level'] == 'fatal' assert event['contexts']['os'][ 'raw_description'] == 'Mac OS X 10.14.0 (18A391)' assert event['contexts']['device']['model'] == 'MacBookPro14,3' assert len(event['threads']) == 55 assert event['threads'][5]['crashed'] assert event['threads'][5]['id'] == 5 assert event['threads'][5]['stacktrace']['frames'][0][ 'instruction_addr'] == '0x7fff61c7f425' assert event['threads'][5]['stacktrace']['frames'][0][ 'package'] == 'libsystem_pthread.dylib' assert event['threads'][5]['stacktrace']['registers'][ 'r14'] == '0x1' assert len(event['debug_meta']['images']) == 272 assert event['debug_meta']['images'][0]['type'] == 'symbolic' assert event['debug_meta']['images'][0][ 'id'] == '2d903291-397d-3d14-bfca-52c7fb8c5e00' assert event['debug_meta']['images'][0][ 'image_addr'] == '0x10864e000' assert event['debug_meta']['images'][0]['image_size'] == 108797951 assert event['debug_meta']['images'][0]['arch'] == 'x86_64' assert event['debug_meta']['images'][0][ 'name'] == '/Users/bruno/Documents/Unreal Projects/YetAnotherMac/MacNoEditor/YetAnotherMac.app/Contents/MacOS/YetAnotherMac'
def post(self, request, project, **kwargs): attachments_enabled = features.has('organizations:event-attachments', project.organization, actor=request.user) attachments = [] try: event = {} unreal = process_unreal_crash(request.body, request.GET.get('UserID'), request.GET.get('AppEnvironment'), event) process_state = unreal.process_minidump() if process_state: merge_process_state_event(event, process_state) else: apple_crash_report = unreal.get_apple_crash_report() if apple_crash_report: merge_apple_crash_report(apple_crash_report, event) else: raise APIError("missing minidump in unreal crash report") except (ProcessMinidumpError, Unreal4Error) as e: minidumps_logger.exception(e) raise APIError(e.message.split('\n', 1)[0]) try: unreal_context = unreal.get_context() if unreal_context is not None: merge_unreal_context_event(unreal_context, event, project) except Unreal4Error as e: # we'll continue without the context data minidumps_logger.exception(e) try: unreal_logs = unreal.get_logs() if unreal_logs is not None: merge_unreal_logs_event(unreal_logs, event) except Unreal4Error as e: # we'll continue without the breadcrumbs minidumps_logger.exception(e) for file in unreal.files(): # Always store the minidump in attachments so we can access it during # processing, regardless of the event-attachments feature. This will # allow us to stack walk again with CFI once symbols are loaded. if file.type == "minidump" or attachments_enabled: attachments.append( CachedAttachment( name=file.name, data=file.open_stream().read(), type=unreal_attachment_type(file), )) response_or_event_id = self.process(request, attachments=attachments, data=event, project=project, **kwargs) # The return here is only useful for consistency # because the UE4 crash reporter doesn't care about it. if isinstance(response_or_event_id, HttpResponse): return response_or_event_id return HttpResponse(six.text_type(uuid.UUID(response_or_event_id)), content_type='text/plain')
def post(self, request, project, relay_config, **kwargs): attachments_enabled = features.has('organizations:event-attachments', project.organization, actor=request.user) is_apple_crash_report = False attachments = [] event = {'event_id': uuid.uuid4().hex} try: unreal = process_unreal_crash(request.body, request.GET.get('UserID'), request.GET.get('AppEnvironment'), event) apple_crash_report = unreal.get_apple_crash_report() if apple_crash_report: merge_apple_crash_report(apple_crash_report, event) is_apple_crash_report = True except (ProcessMinidumpError, Unreal4Error) as e: minidumps_logger.exception(e) track_outcome(relay_config.organization_id, relay_config.project_id, None, Outcome.INVALID, "process_minidump_unreal") raise APIError(e.message.split('\n', 1)[0]) try: unreal_context = unreal.get_context() if unreal_context is not None: merge_unreal_context_event(unreal_context, event, project) except Unreal4Error as e: # we'll continue without the context data minidumps_logger.exception(e) try: unreal_logs = unreal.get_logs() if unreal_logs is not None: merge_unreal_logs_event(unreal_logs, event) except Unreal4Error as e: # we'll continue without the breadcrumbs minidumps_logger.exception(e) is_minidump = False for file in unreal.files(): # Known attachment: msgpack event if file.name == "__sentry-event": merge_attached_event(file.open_stream(), event) continue if file.name in ("__sentry-breadcrumb1", "__sentry-breadcrumb2"): merge_attached_breadcrumbs(file.open_stream(), event) continue if file.type == "minidump" and not is_apple_crash_report: is_minidump = True # Always store the minidump in attachments so we can access it during # processing, regardless of the event-attachments feature. This will # allow us to stack walk again with CFI once symbols are loaded. if file.type == "minidump" or attachments_enabled: attachments.append( CachedAttachment( name=file.name, data=file.open_stream().read(), type=unreal_attachment_type(file), )) if is_minidump: write_minidump_placeholder(event) event_id = self.process(request, attachments=attachments, data=event, project=project, relay_config=relay_config, **kwargs) # The return here is only useful for consistency # because the UE4 crash reporter doesn't care about it. return HttpResponse(six.text_type(uuid.UUID(event_id)), content_type='text/plain')
def post(self, request, project, **kwargs): attachments_enabled = features.has('organizations:event-attachments', project.organization, actor=request.user) attachments = [] event = {'event_id': uuid.uuid4().hex} try: unreal = process_unreal_crash(request.body, request.GET.get( 'UserID'), request.GET.get('AppEnvironment'), event) process_state = unreal.process_minidump() if process_state: merge_process_state_event(event, process_state) else: apple_crash_report = unreal.get_apple_crash_report() if apple_crash_report: merge_apple_crash_report(apple_crash_report, event) else: track_outcome(project.organization_id, project.id, None, Outcome.INVALID, "missing_minidump_unreal") raise APIError("missing minidump in unreal crash report") except (ProcessMinidumpError, Unreal4Error) as e: minidumps_logger.exception(e) track_outcome( project.organization_id, project.id, None, Outcome.INVALID, "process_minidump_unreal") raise APIError(e.message.split('\n', 1)[0]) try: unreal_context = unreal.get_context() if unreal_context is not None: merge_unreal_context_event(unreal_context, event, project) except Unreal4Error as e: # we'll continue without the context data minidumps_logger.exception(e) try: unreal_logs = unreal.get_logs() if unreal_logs is not None: merge_unreal_logs_event(unreal_logs, event) except Unreal4Error as e: # we'll continue without the breadcrumbs minidumps_logger.exception(e) for file in unreal.files(): # Known attachment: msgpack event if file.name == "__sentry-event": merge_attached_event(file.open_stream(), event) continue if file.name in ("__sentry-breadcrumb1", "__sentry-breadcrumb2"): merge_attached_breadcrumbs(file.open_stream(), event) continue # Always store the minidump in attachments so we can access it during # processing, regardless of the event-attachments feature. This will # allow us to stack walk again with CFI once symbols are loaded. if file.type == "minidump" or attachments_enabled: attachments.append(CachedAttachment( name=file.name, data=file.open_stream().read(), type=unreal_attachment_type(file), )) event_id = self.process( request, attachments=attachments, data=event, project=project, **kwargs) # The return here is only useful for consistency # because the UE4 crash reporter doesn't care about it. return HttpResponse( six.text_type(uuid.UUID(event_id)), content_type='text/plain' )