prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Culprit not shown for iOS
  For some iOS events the culprit is not shown in the UI.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/sentry/lang/native/plugin.py`
  Content:
  ```
  1 from __future__ import absolute_import, print_function
  2 
  3 import logging
  4 import posixpath
  5 
  6 from sentry.models import Project, EventError
  7 from sentry.plugins import Plugin2
  8 from sentry.lang.native.symbolizer import Symbolizer, have_symsynd
  9 from sentry.models.dsymfile import SDK_MAPPING
  10 
  11 
  12 logger = logging.getLogger(__name__)
  13 
  14 
  15 def append_error(data, err):
  16     data.setdefault('errors', []).append(err)
  17 
  18 
  19 def exception_from_apple_error_or_diagnosis(error, diagnosis=None):
  20     error = error or {}
  21 
  22     if error:
  23         nsexception = error.get('nsexception')
  24         if nsexception:
  25             return {
  26                 'type': nsexception['name'],
  27                 'value': error['reason'],
  28             }
  29 
  30     if diagnosis:
  31         return {
  32             'type': 'Error',
  33             'value': diagnosis
  34         }
  35 
  36 
  37 def inject_apple_backtrace(data, frames, diagnosis=None, error=None,
  38                            system=None):
  39     # TODO:
  40     #   user report stacktraces from unity
  41 
  42     app_uuid = None
  43     if system:
  44         app_uuid = system.get('app_uuid')
  45         if app_uuid is not None:
  46             app_uuid = app_uuid.lower()
  47 
  48     converted_frames = []
  49     longest_addr = 0
  50     for frame in reversed(frames):
  51         fn = frame.get('filename')
  52         in_app = False
  53 
  54         if app_uuid is not None:
  55             frame_uuid = frame.get('uuid')
  56             if frame_uuid == app_uuid:
  57                 in_app = True
  58 
  59         # We only record the offset if we found a symbol but we did not
  60         # find a line number.  In that case it's the offset in bytes from
  61         # the beginning of the symbol.
  62         function = frame['symbol_name'] or '<unknown>'
  63         lineno = frame.get('line')
  64         offset = None
  65         if not lineno:
  66             offset = frame['instruction_addr'] - frame['symbol_addr']
  67 
  68         cframe = {
  69             'in_app': in_app,
  70             'abs_path': fn,
  71             'filename': fn and posixpath.basename(fn) or None,
  72             # This can come back as `None` from the symbolizer, in which
  73             # case we need to fill something else in or we will fail
  74             # later fulfill the interface requirements which say that a
  75             # function needs to be provided.
  76             'function': function,
  77             'package': frame['object_name'],
  78             'symbol_addr': '%x' % frame['symbol_addr'],
  79             'instruction_addr': '%x' % frame['instruction_addr'],
  80             'instruction_offset': offset,
  81             'lineno': lineno,
  82         }
  83         converted_frames.append(cframe)
  84         longest_addr = max(longest_addr, len(cframe['symbol_addr']),
  85                            len(cframe['instruction_addr']))
  86 
  87     # Pad out addresses to be of the same length and add prefix
  88     for frame in converted_frames:
  89         for key in 'symbol_addr', 'instruction_addr':
  90             frame[key] = '0x' + frame[key][2:].rjust(longest_addr, '0')
  91 
  92     stacktrace = {'frames': converted_frames}
  93 
  94     if error or diagnosis:
  95         error = error or {}
  96         exc = exception_from_apple_error_or_diagnosis(error, diagnosis)
  97         if exc is not None:
  98             exc['stacktrace'] = stacktrace
  99             data['sentry.interfaces.Exception'] = exc
  100             return
  101 
  102     data['sentry.interfaces.Stacktrace'] = stacktrace
  103 
  104 
  105 def inject_apple_device_data(data, system):
  106     container = data.setdefault('device', {})
  107     try:
  108         container['name'] = SDK_MAPPING[system['system_name']]
  109     except LookupError:
  110         container['name'] = system.get('system_name') or 'Generic Apple'
  111 
  112     if 'system_version' in system:
  113         container['version'] = system['system_version']
  114     if 'os_version' in system:
  115         container['build'] = system['os_version']
  116 
  117     extra = container.setdefault('data', {})
  118     if 'cpu_arch' in system:
  119         extra['cpu_arch'] = system['cpu_arch']
  120     if 'model' in system:
  121         extra['device_model_id'] = system['model']
  122     if 'machine' in system:
  123         extra['device_model'] = system['machine']
  124     if 'kernel_version' in system:
  125         extra['kernel_version'] = system['kernel_version']
  126 
  127 
  128 def preprocess_apple_crash_event(data):
  129     crash_report = data.get('sentry.interfaces.AppleCrashReport')
  130     if crash_report is None:
  131         return
  132 
  133     project = Project.objects.get_from_cache(
  134         id=data['project'],
  135     )
  136 
  137     crash = crash_report['crash']
  138     crashed_thread = None
  139     for thread in crash['threads']:
  140         if thread['crashed']:
  141             crashed_thread = thread
  142     if crashed_thread is None:
  143         append_error(data, {
  144             'type': EventError.NATIVE_NO_CRASHED_THREAD,
  145         })
  146 
  147     else:
  148         system = crash_report.get('system')
  149         try:
  150             sym = Symbolizer(project, crash_report['binary_images'],
  151                              threads=[crashed_thread])
  152             with sym:
  153                 bt = sym.symbolize_backtrace(
  154                     crashed_thread['backtrace']['contents'], system)
  155                 inject_apple_backtrace(data, bt, crash.get('diagnosis'),
  156                                        crash.get('error'), system)
  157         except Exception as e:
  158             logger.exception('Failed to symbolicate')
  159             append_error(data, {
  160                 'type': EventError.NATIVE_INTERNAL_FAILURE,
  161                 'error': '%s: %s' % (e.__class__.__name__, str(e)),
  162             })
  163             return
  164 
  165     if system:
  166         inject_apple_device_data(data, system)
  167 
  168     return data
  169 
  170 
  171 class NativePlugin(Plugin2):
  172     can_disable = False
  173 
  174     def get_event_preprocessors(self, **kwargs):
  175         if not have_symsynd:
  176             return []
  177         return [preprocess_apple_crash_event]
  178
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/sentry/lang/native/plugin.py b/src/sentry/lang/native/plugin.py
  --- a/src/sentry/lang/native/plugin.py
  +++ b/src/sentry/lang/native/plugin.py
  @@ -96,7 +96,11 @@
           exc = exception_from_apple_error_or_diagnosis(error, diagnosis)
           if exc is not None:
               exc['stacktrace'] = stacktrace
  -            data['sentry.interfaces.Exception'] = exc
  +            data['sentry.interfaces.Exception'] = {'values': [exc]}
  +            # Since we inject the exception late we need to make sure that
  +            # we set the event type to error as it would be set to
  +            # 'default' otherwise.
  +            data['type'] = 'error'
               return
   
       data['sentry.interfaces.Stacktrace'] = stacktrace
  
verification_info: {"golden_diff": "diff --git a/src/sentry/lang/native/plugin.py b/src/sentry/lang/native/plugin.py\n--- a/src/sentry/lang/native/plugin.py\n+++ b/src/sentry/lang/native/plugin.py\n@@ -96,7 +96,11 @@\n         exc = exception_from_apple_error_or_diagnosis(error, diagnosis)\n         if exc is not None:\n             exc['stacktrace'] = stacktrace\n-            data['sentry.interfaces.Exception'] = exc\n+            data['sentry.interfaces.Exception'] = {'values': [exc]}\n+            # Since we inject the exception late we need to make sure that\n+            # we set the event type to error as it would be set to\n+            # 'default' otherwise.\n+            data['type'] = 'error'\n             return\n \n     data['sentry.interfaces.Stacktrace'] = stacktrace\n", "issue": "Culprit not shown for iOS\nFor some iOS events the culprit is not shown in the UI.\n\n", "before_files": [{"content": "from __future__ import absolute_import, print_function\n\nimport logging\nimport posixpath\n\nfrom sentry.models import Project, EventError\nfrom sentry.plugins import Plugin2\nfrom sentry.lang.native.symbolizer import Symbolizer, have_symsynd\nfrom sentry.models.dsymfile import SDK_MAPPING\n\n\nlogger = logging.getLogger(__name__)\n\n\ndef append_error(data, err):\n    data.setdefault('errors', []).append(err)\n\n\ndef exception_from_apple_error_or_diagnosis(error, diagnosis=None):\n    error = error or {}\n\n    if error:\n        nsexception = error.get('nsexception')\n        if nsexception:\n            return {\n                'type': nsexception['name'],\n                'value': error['reason'],\n            }\n\n    if diagnosis:\n        return {\n            'type': 'Error',\n            'value': diagnosis\n        }\n\n\ndef inject_apple_backtrace(data, frames, diagnosis=None, error=None,\n                           system=None):\n    # TODO:\n    #   user report stacktraces from unity\n\n    app_uuid = None\n    if system:\n        app_uuid = system.get('app_uuid')\n        if app_uuid is not None:\n            app_uuid = app_uuid.lower()\n\n    converted_frames = []\n    longest_addr = 0\n    for frame in reversed(frames):\n        fn = frame.get('filename')\n        in_app = False\n\n        if app_uuid is not None:\n            frame_uuid = frame.get('uuid')\n            if frame_uuid == app_uuid:\n                in_app = True\n\n        # We only record the offset if we found a symbol but we did not\n        # find a line number.  In that case it's the offset in bytes from\n        # the beginning of the symbol.\n        function = frame['symbol_name'] or '<unknown>'\n        lineno = frame.get('line')\n        offset = None\n        if not lineno:\n            offset = frame['instruction_addr'] - frame['symbol_addr']\n\n        cframe = {\n            'in_app': in_app,\n            'abs_path': fn,\n            'filename': fn and posixpath.basename(fn) or None,\n            # This can come back as `None` from the symbolizer, in which\n            # case we need to fill something else in or we will fail\n            # later fulfill the interface requirements which say that a\n            # function needs to be provided.\n            'function': function,\n            'package': frame['object_name'],\n            'symbol_addr': '%x' % frame['symbol_addr'],\n            'instruction_addr': '%x' % frame['instruction_addr'],\n            'instruction_offset': offset,\n            'lineno': lineno,\n        }\n        converted_frames.append(cframe)\n        longest_addr = max(longest_addr, len(cframe['symbol_addr']),\n                           len(cframe['instruction_addr']))\n\n    # Pad out addresses to be of the same length and add prefix\n    for frame in converted_frames:\n        for key in 'symbol_addr', 'instruction_addr':\n            frame[key] = '0x' + frame[key][2:].rjust(longest_addr, '0')\n\n    stacktrace = {'frames': converted_frames}\n\n    if error or diagnosis:\n        error = error or {}\n        exc = exception_from_apple_error_or_diagnosis(error, diagnosis)\n        if exc is not None:\n            exc['stacktrace'] = stacktrace\n            data['sentry.interfaces.Exception'] = exc\n            return\n\n    data['sentry.interfaces.Stacktrace'] = stacktrace\n\n\ndef inject_apple_device_data(data, system):\n    container = data.setdefault('device', {})\n    try:\n        container['name'] = SDK_MAPPING[system['system_name']]\n    except LookupError:\n        container['name'] = system.get('system_name') or 'Generic Apple'\n\n    if 'system_version' in system:\n        container['version'] = system['system_version']\n    if 'os_version' in system:\n        container['build'] = system['os_version']\n\n    extra = container.setdefault('data', {})\n    if 'cpu_arch' in system:\n        extra['cpu_arch'] = system['cpu_arch']\n    if 'model' in system:\n        extra['device_model_id'] = system['model']\n    if 'machine' in system:\n        extra['device_model'] = system['machine']\n    if 'kernel_version' in system:\n        extra['kernel_version'] = system['kernel_version']\n\n\ndef preprocess_apple_crash_event(data):\n    crash_report = data.get('sentry.interfaces.AppleCrashReport')\n    if crash_report is None:\n        return\n\n    project = Project.objects.get_from_cache(\n        id=data['project'],\n    )\n\n    crash = crash_report['crash']\n    crashed_thread = None\n    for thread in crash['threads']:\n        if thread['crashed']:\n            crashed_thread = thread\n    if crashed_thread is None:\n        append_error(data, {\n            'type': EventError.NATIVE_NO_CRASHED_THREAD,\n        })\n\n    else:\n        system = crash_report.get('system')\n        try:\n            sym = Symbolizer(project, crash_report['binary_images'],\n                             threads=[crashed_thread])\n            with sym:\n                bt = sym.symbolize_backtrace(\n                    crashed_thread['backtrace']['contents'], system)\n                inject_apple_backtrace(data, bt, crash.get('diagnosis'),\n                                       crash.get('error'), system)\n        except Exception as e:\n            logger.exception('Failed to symbolicate')\n            append_error(data, {\n                'type': EventError.NATIVE_INTERNAL_FAILURE,\n                'error': '%s: %s' % (e.__class__.__name__, str(e)),\n            })\n            return\n\n    if system:\n        inject_apple_device_data(data, system)\n\n    return data\n\n\nclass NativePlugin(Plugin2):\n    can_disable = False\n\n    def get_event_preprocessors(self, **kwargs):\n        if not have_symsynd:\n            return []\n        return [preprocess_apple_crash_event]\n", "path": "src/sentry/lang/native/plugin.py"}], "after_files": [{"content": "from __future__ import absolute_import, print_function\n\nimport logging\nimport posixpath\n\nfrom sentry.models import Project, EventError\nfrom sentry.plugins import Plugin2\nfrom sentry.lang.native.symbolizer import Symbolizer, have_symsynd\nfrom sentry.models.dsymfile import SDK_MAPPING\n\n\nlogger = logging.getLogger(__name__)\n\n\ndef append_error(data, err):\n    data.setdefault('errors', []).append(err)\n\n\ndef exception_from_apple_error_or_diagnosis(error, diagnosis=None):\n    error = error or {}\n\n    if error:\n        nsexception = error.get('nsexception')\n        if nsexception:\n            return {\n                'type': nsexception['name'],\n                'value': error['reason'],\n            }\n\n    if diagnosis:\n        return {\n            'type': 'Error',\n            'value': diagnosis\n        }\n\n\ndef inject_apple_backtrace(data, frames, diagnosis=None, error=None,\n                           system=None):\n    # TODO:\n    #   user report stacktraces from unity\n\n    app_uuid = None\n    if system:\n        app_uuid = system.get('app_uuid')\n        if app_uuid is not None:\n            app_uuid = app_uuid.lower()\n\n    converted_frames = []\n    longest_addr = 0\n    for frame in reversed(frames):\n        fn = frame.get('filename')\n        in_app = False\n\n        if app_uuid is not None:\n            frame_uuid = frame.get('uuid')\n            if frame_uuid == app_uuid:\n                in_app = True\n\n        # We only record the offset if we found a symbol but we did not\n        # find a line number.  In that case it's the offset in bytes from\n        # the beginning of the symbol.\n        function = frame['symbol_name'] or '<unknown>'\n        lineno = frame.get('line')\n        offset = None\n        if not lineno:\n            offset = frame['instruction_addr'] - frame['symbol_addr']\n\n        cframe = {\n            'in_app': in_app,\n            'abs_path': fn,\n            'filename': fn and posixpath.basename(fn) or None,\n            # This can come back as `None` from the symbolizer, in which\n            # case we need to fill something else in or we will fail\n            # later fulfill the interface requirements which say that a\n            # function needs to be provided.\n            'function': function,\n            'package': frame['object_name'],\n            'symbol_addr': '%x' % frame['symbol_addr'],\n            'instruction_addr': '%x' % frame['instruction_addr'],\n            'instruction_offset': offset,\n            'lineno': lineno,\n        }\n        converted_frames.append(cframe)\n        longest_addr = max(longest_addr, len(cframe['symbol_addr']),\n                           len(cframe['instruction_addr']))\n\n    # Pad out addresses to be of the same length and add prefix\n    for frame in converted_frames:\n        for key in 'symbol_addr', 'instruction_addr':\n            frame[key] = '0x' + frame[key][2:].rjust(longest_addr, '0')\n\n    stacktrace = {'frames': converted_frames}\n\n    if error or diagnosis:\n        error = error or {}\n        exc = exception_from_apple_error_or_diagnosis(error, diagnosis)\n        if exc is not None:\n            exc['stacktrace'] = stacktrace\n            data['sentry.interfaces.Exception'] = {'values': [exc]}\n            # Since we inject the exception late we need to make sure that\n            # we set the event type to error as it would be set to\n            # 'default' otherwise.\n            data['type'] = 'error'\n            return\n\n    data['sentry.interfaces.Stacktrace'] = stacktrace\n\n\ndef inject_apple_device_data(data, system):\n    container = data.setdefault('device', {})\n    try:\n        container['name'] = SDK_MAPPING[system['system_name']]\n    except LookupError:\n        container['name'] = system.get('system_name') or 'Generic Apple'\n\n    if 'system_version' in system:\n        container['version'] = system['system_version']\n    if 'os_version' in system:\n        container['build'] = system['os_version']\n\n    extra = container.setdefault('data', {})\n    if 'cpu_arch' in system:\n        extra['cpu_arch'] = system['cpu_arch']\n    if 'model' in system:\n        extra['device_model_id'] = system['model']\n    if 'machine' in system:\n        extra['device_model'] = system['machine']\n    if 'kernel_version' in system:\n        extra['kernel_version'] = system['kernel_version']\n\n\ndef preprocess_apple_crash_event(data):\n    crash_report = data.get('sentry.interfaces.AppleCrashReport')\n    if crash_report is None:\n        return\n\n    project = Project.objects.get_from_cache(\n        id=data['project'],\n    )\n\n    crash = crash_report['crash']\n    crashed_thread = None\n    for thread in crash['threads']:\n        if thread['crashed']:\n            crashed_thread = thread\n    if crashed_thread is None:\n        append_error(data, {\n            'type': EventError.NATIVE_NO_CRASHED_THREAD,\n        })\n\n    else:\n        system = crash_report.get('system')\n        try:\n            sym = Symbolizer(project, crash_report['binary_images'],\n                             threads=[crashed_thread])\n            with sym:\n                bt = sym.symbolize_backtrace(\n                    crashed_thread['backtrace']['contents'], system)\n                inject_apple_backtrace(data, bt, crash.get('diagnosis'),\n                                       crash.get('error'), system)\n        except Exception as e:\n            logger.exception('Failed to symbolicate')\n            append_error(data, {\n                'type': EventError.NATIVE_INTERNAL_FAILURE,\n                'error': '%s: %s' % (e.__class__.__name__, str(e)),\n            })\n            return\n\n    if system:\n        inject_apple_device_data(data, system)\n\n    return data\n\n\nclass NativePlugin(Plugin2):\n    can_disable = False\n\n    def get_event_preprocessors(self, **kwargs):\n        if not have_symsynd:\n            return []\n        return [preprocess_apple_crash_event]\n", "path": "src/sentry/lang/native/plugin.py"}]}