From e088b0db105a5a28c5df056419098ae82e7549e2 Mon Sep 17 00:00:00 2001
From: Richard Elms <richardelms@gmail.com>
Date: Fri, 24 Jan 2025 09:46:20 +0100
Subject: [PATCH 1/4] automatic Android and Xcode symbol upload (#871)

---
 .buildkite/unity.2020.yml                     |  36 +--
 .buildkite/unity.2021.yml                     |  39 +--
 .buildkite/unity.2022.yml                     |  36 +--
 .buildkite/unity.6000.yml                     |  36 +--
 .gitignore                                    |   2 +
 .../Editor/BugsnagAddScriptingSymbol.cs       |   5 +-
 .../Bugsnag/Editor/BugsnagEditor.EDM.cs       |   2 +-
 .../Assets/Bugsnag/Editor/BugsnagEditor.cs    |  21 +-
 .../Editor/BugsnagPlayerSettingsCompat.cs     |   9 +
 .../Assets/Bugsnag/Editor/SymbolUpload.meta   |   8 +
 .../AutoSymbolUploadToggleMenu.cs             |  46 +++
 .../AutoSymbolUploadToggleMenu.cs.meta        |  11 +
 .../Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs | 206 ++++++++++++
 .../Editor/SymbolUpload/BugsnagCLI.cs.meta    |  11 +
 .../SymbolUpload/BugsnagSymbolUploader.cs     | 168 ++++++++++
 .../BugsnagSymbolUploader.cs.meta             |  11 +
 .../Bugsnag/Runtime/BugsnagSettingsObject.cs  |  20 ++
 .../Runtime/Native/Android/NativeInterface.cs |   2 +-
 Bugsnag/Assets/Plugins.meta                   |   8 +
 Bugsnag/Assets/Plugins/MacOS.meta             |   8 +
 .../Plugins/MacOS/NativeCrashy.bundle.meta    | 109 +++++++
 .../MacOS/NativeCrashy.bundle/Contents.meta   |   8 +
 .../NativeCrashy.bundle/Contents/Headers.meta |   8 +
 .../Contents/Headers/very_crashy.h            |   7 +
 .../Contents/Headers/very_crashy.h.meta       |   7 +
 .../NativeCrashy.bundle/Contents/Info.plist   |  48 +++
 .../Contents/Info.plist.meta                  |   7 +
 .../NativeCrashy.bundle/Contents/MacOS.meta   |   8 +
 .../Contents/MacOS/NativeCrashy               | Bin 0 -> 151728 bytes
 .../Contents/MacOS/NativeCrashy.meta          |   7 +
 .../Contents/_CodeSignature.meta              |   8 +
 .../Contents/_CodeSignature/CodeResources     | 123 +++++++
 .../_CodeSignature/CodeResources.meta         |   7 +
 Bugsnag/Assets/Plugins/iOS.meta               |   8 +
 Bugsnag/Assets/Plugins/iOS/native_code.mm     |  23 ++
 .../Assets/Plugins/iOS/native_code.mm.meta    |  90 ++++++
 .../Bugsnag/BugsnagSettingsObject.asset       |   3 +
 Bugsnag/Assets/Scenes/SampleScene.unity       | 305 +++++++++++++++++-
 Bugsnag/Assets/Scripts/Testing.cs             |  40 ++-
 Bugsnag/Packages/manifest.json                |   6 +-
 CHANGELOG.md                                  |  10 +-
 Gemfile                                       |   1 -
 features/build/build_android.feature          |  24 ++
 features/build/build_ios.feature              |   9 +
 features/csharp/csharp_events.feature         |   2 +-
 .../maze_runner/Assets/Editor/Builder.cs      |  48 ++-
 .../maze_runner/Assets/Resources.meta         |   8 +
 .../Bugsnag/BugsnagSettingsObject.asset       |  68 ++++
 .../Bugsnag/BugsnagSettingsObject.asset.meta  |   8 +
 features/scripts/build_android.sh             |   2 +-
 features/scripts/build_ios.sh                 |  53 +--
 features/scripts/generate_xcode_project.sh    |   2 +-
 features/steps/unity_steps.rb                 |  25 +-
 features/support/env.rb                       |  14 +-
 54 files changed, 1598 insertions(+), 183 deletions(-)
 create mode 100644 Bugsnag/Assets/Bugsnag/Editor/SymbolUpload.meta
 create mode 100644 Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/AutoSymbolUploadToggleMenu.cs
 create mode 100644 Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/AutoSymbolUploadToggleMenu.cs.meta
 create mode 100644 Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs
 create mode 100644 Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs.meta
 create mode 100644 Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagSymbolUploader.cs
 create mode 100644 Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagSymbolUploader.cs.meta
 create mode 100644 Bugsnag/Assets/Plugins.meta
 create mode 100644 Bugsnag/Assets/Plugins/MacOS.meta
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle.meta
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents.meta
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers.meta
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers/very_crashy.h
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers/very_crashy.h.meta
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Info.plist
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Info.plist.meta
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/MacOS.meta
 create mode 100755 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/MacOS/NativeCrashy
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/MacOS/NativeCrashy.meta
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature.meta
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature/CodeResources
 create mode 100644 Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature/CodeResources.meta
 create mode 100644 Bugsnag/Assets/Plugins/iOS.meta
 create mode 100644 Bugsnag/Assets/Plugins/iOS/native_code.mm
 create mode 100644 Bugsnag/Assets/Plugins/iOS/native_code.mm.meta
 create mode 100644 features/build/build_android.feature
 create mode 100644 features/build/build_ios.feature
 create mode 100644 features/fixtures/maze_runner/Assets/Resources.meta
 create mode 100644 features/fixtures/maze_runner/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset
 create mode 100644 features/fixtures/maze_runner/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset.meta

diff --git a/.buildkite/unity.2020.yml b/.buildkite/unity.2020.yml
index d69060fc8..c3d3032d2 100644
--- a/.buildkite/unity.2020.yml
+++ b/.buildkite/unity.2020.yml
@@ -19,9 +19,9 @@ steps:
             upload:
               - features/fixtures/maze_runner/mazerunner_2020.apk
               - features/fixtures/build_android_apk.log
-        commands:
-          - bundle install
-          - rake test:android:build
+        command:
+              - "bundle install"
+              - "bundle exec maze-runner --os macos features/build/build_android.feature"
         retry:
           automatic:
             - exit_status: "*"
@@ -30,31 +30,9 @@ steps:
       #
       # Build iOS test fixtures
       #
-      - label: ":ios: Generate Xcode project - Unity 2020"
-        timeout_in_minutes: 20
-        key: "generate-fixture-project-2020"
-        env:
-          UNITY_VERSION: *2020
-        plugins:
-          artifacts#v1.9.0:
-            download:
-              - Bugsnag.unitypackage
-            upload:
-              - features/fixtures/unity.log
-              - project_2020.tgz
-        commands:
-          - bundle install
-          - rake test:ios:generate_xcode
-          - tar -zvcf project_2020.tgz features/fixtures/maze_runner/mazerunner_xcode
-        retry:
-          automatic:
-            - exit_status: "*"
-              limit: 1
-
       - label: ":ios: Build iOS test fixture for Unity 2020"
         timeout_in_minutes: 10
         key: "build-ios-fixture-2020"
-        depends_on: "generate-fixture-project-2020"
         env:
           XCODE_VERSION: "15.3.0"
           UNITY_VERSION: *2020
@@ -62,14 +40,12 @@ steps:
           artifacts#v1.9.0:
             download:
               - Bugsnag.unitypackage
-              - project_2020.tgz
             upload:
               - features/fixtures/maze_runner/mazerunner_2020.ipa
               - features/fixtures/unity.log
-        commands:
-          - bundle install
-          - tar -zxf project_2020.tgz features/fixtures/maze_runner
-          - rake test:ios:build_xcode
+        command:
+              - "bundle install"
+              - "bundle exec maze-runner --os macos features/build/build_ios.feature"
         retry:
           automatic:
             - exit_status: "*"
diff --git a/.buildkite/unity.2021.yml b/.buildkite/unity.2021.yml
index 59528c7b0..8c3c78b6d 100644
--- a/.buildkite/unity.2021.yml
+++ b/.buildkite/unity.2021.yml
@@ -19,33 +19,9 @@ steps:
             upload:
               - features/fixtures/maze_runner/mazerunner_2021.apk
               - features/fixtures/build_android_apk.log
-        commands:
-          - bundle install
-          - rake test:android:build
-        retry:
-          automatic:
-            - exit_status: "*"
-              limit: 1
-
-      #
-      # Build iOS test fixtures
-      #
-      - label: ":ios: Generate Xcode project - Unity 2021"
-        timeout_in_minutes: 20
-        key: "generate-fixture-project-2021"
-        env:
-          UNITY_VERSION: *2021
-        plugins:
-          artifacts#v1.5.0:
-            download:
-              - Bugsnag.unitypackage
-            upload:
-              - features/fixtures/unity.log
-              - project_2021.tgz
-        commands:
-          - bundle install
-          - rake test:ios:generate_xcode
-          - tar -zvcf project_2021.tgz features/fixtures/maze_runner/mazerunner_xcode
+        command:
+              - "bundle install"
+              - "bundle exec maze-runner --os macos features/build/build_android.feature"
         retry:
           automatic:
             - exit_status: "*"
@@ -54,7 +30,6 @@ steps:
       - label: ":ios: Build iOS test fixture for Unity 2021"
         timeout_in_minutes: 10
         key: "build-ios-fixture-2021"
-        depends_on: "generate-fixture-project-2021"
         env:
           UNITY_VERSION: *2021
           XCODE_VERSION: "15.3.0"
@@ -62,14 +37,12 @@ steps:
           artifacts#v1.5.0:
             download:
               - Bugsnag.unitypackage
-              - project_2021.tgz
             upload:
               - features/fixtures/maze_runner/mazerunner_2021.ipa
               - features/fixtures/unity.log
-        commands:
-          - bundle install
-          - tar -zxf project_2021.tgz features/fixtures/maze_runner
-          - rake test:ios:build_xcode
+        command:
+              - "bundle install"
+              - "bundle exec maze-runner --os macos features/build/build_ios.feature"
         retry:
           automatic:
             - exit_status: "*"
diff --git a/.buildkite/unity.2022.yml b/.buildkite/unity.2022.yml
index 99c2b40ee..65004ac98 100644
--- a/.buildkite/unity.2022.yml
+++ b/.buildkite/unity.2022.yml
@@ -19,30 +19,9 @@ steps:
             upload:
               - features/fixtures/maze_runner/mazerunner_2022.apk
               - features/fixtures/build_android_apk.log
-        commands:
-          - bundle install
-          - rake test:android:build
-        retry:
-          automatic:
-            - exit_status: "*"
-              limit: 1
-
-      - label: ":ios: Generate Xcode project - Unity 2022"
-        timeout_in_minutes: 10
-        key: "generate-fixture-project-2022"
-        env:
-          UNITY_VERSION: *2022
-        plugins:
-          artifacts#v1.9.0:
-            download:
-              - Bugsnag.unitypackage
-            upload:
-              - features/fixtures/unity.log
-              - project_2022.tgz
-        commands:
-          - bundle install
-          - rake test:ios:generate_xcode
-          - tar -zvcf project_2022.tgz features/fixtures/maze_runner/mazerunner_xcode
+        command:
+              - "bundle install"
+              - "bundle exec maze-runner --os macos features/build/build_android.feature"
         retry:
           automatic:
             - exit_status: "*"
@@ -51,7 +30,6 @@ steps:
       - label: ":ios: Build iOS test fixture for Unity 2022"
         timeout_in_minutes: 10
         key: "build-ios-fixture-2022"
-        depends_on: "generate-fixture-project-2022"
         env:
           UNITY_VERSION: *2022
           XCODE_VERSION: "15.3.0"
@@ -59,14 +37,12 @@ steps:
           artifacts#v1.9.0:
             download:
               - Bugsnag.unitypackage
-              - project_2022.tgz
             upload:
               - features/fixtures/maze_runner/mazerunner_2022.ipa
               - features/fixtures/unity.log
-        commands:
-          - bundle install
-          - tar -zxf project_2022.tgz features/fixtures/maze_runner
-          - rake test:ios:build_xcode
+        command:
+              - "bundle install"
+              - "bundle exec maze-runner --os macos features/build/build_ios.feature"
         retry:
           automatic:
             - exit_status: "*"
diff --git a/.buildkite/unity.6000.yml b/.buildkite/unity.6000.yml
index 17abbcd98..2659b9ec7 100644
--- a/.buildkite/unity.6000.yml
+++ b/.buildkite/unity.6000.yml
@@ -19,30 +19,9 @@ steps:
             upload:
               - features/fixtures/maze_runner/mazerunner_6000.apk
               - features/fixtures/build_android_apk.log
-        commands:
-          - bundle install
-          - rake test:android:build
-        retry:
-          automatic:
-            - exit_status: "*"
-              limit: 1
-
-      - label: ":ios: Generate Xcode project - Unity 6000"
-        timeout_in_minutes: 10
-        key: "generate-fixture-project-6000"
-        env:
-          UNITY_VERSION: *6000
-        plugins:
-          artifacts#v1.9.0:
-            download:
-              - Bugsnag.unitypackage
-            upload:
-              - features/fixtures/unity.log
-              - project_6000.tgz
-        commands:
-          - bundle install
-          - rake test:ios:generate_xcode
-          - tar -zvcf project_6000.tgz features/fixtures/maze_runner/mazerunner_xcode
+        command:
+              - "bundle install"
+              - "bundle exec maze-runner --os macos features/build/build_android.feature"
         retry:
           automatic:
             - exit_status: "*"
@@ -51,7 +30,6 @@ steps:
       - label: ":ios: Build iOS test fixture for Unity 6000"
         timeout_in_minutes: 10
         key: "build-ios-fixture-6000"
-        depends_on: "generate-fixture-project-6000"
         env:
           UNITY_VERSION: *6000
           XCODE_VERSION: "16.0.0"
@@ -59,14 +37,12 @@ steps:
           artifacts#v1.9.0:
             download:
               - Bugsnag.unitypackage
-              - project_6000.tgz
             upload:
               - features/fixtures/maze_runner/mazerunner_6000.ipa
               - features/fixtures/unity.log
-        commands:
-          - bundle install
-          - tar -zxf project_6000.tgz features/fixtures/maze_runner
-          - rake test:ios:build_xcode
+        command:
+              - "bundle install"
+              - "bundle exec maze-runner --os macos features/build/build_ios.feature"
         retry:
           automatic:
             - exit_status: "*"
diff --git a/.gitignore b/.gitignore
index 739813160..e6d5de1e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,3 +65,5 @@ upm/UPMImportProject/Library
 upm-package
 upm/UPMImportProject/.vscode
 UPMImportProject.sln
+!features/build/
+
diff --git a/Bugsnag/Assets/Bugsnag/Editor/BugsnagAddScriptingSymbol.cs b/Bugsnag/Assets/Bugsnag/Editor/BugsnagAddScriptingSymbol.cs
index ad634716d..3ffa36c2d 100644
--- a/Bugsnag/Assets/Bugsnag/Editor/BugsnagAddScriptingSymbol.cs
+++ b/Bugsnag/Assets/Bugsnag/Editor/BugsnagAddScriptingSymbol.cs
@@ -1,9 +1,8 @@
 using UnityEditor;
-using UnityEngine;
 namespace BugsnagUnity.Editor
 {
     [InitializeOnLoad]
-    public class BugsnagAddScriptingSymbol : MonoBehaviour
+    public class BugsnagAddScriptingSymbol
     {
         private const string DEFINE_SYMBOL = "BUGSNAG_UNITY_WEB_REQUEST";
 
@@ -38,4 +37,4 @@ static void SetScriptingSymbol(BuildTargetGroup buildTargetGroup)
             BugsnagPlayerSettingsCompat.SetScriptingDefineSymbols(buildTargetGroup, existingSymbols);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/Bugsnag/Assets/Bugsnag/Editor/BugsnagEditor.EDM.cs b/Bugsnag/Assets/Bugsnag/Editor/BugsnagEditor.EDM.cs
index 47aef9c77..efde79da4 100644
--- a/Bugsnag/Assets/Bugsnag/Editor/BugsnagEditor.EDM.cs
+++ b/Bugsnag/Assets/Bugsnag/Editor/BugsnagEditor.EDM.cs
@@ -20,7 +20,7 @@ public partial class BugsnagEditor : EditorWindow
 
         private static string KotlinLibsDirPath = "/Bugsnag/Plugins/Android/Kotlin";
 
-        [MenuItem(EDM_MENU_ITEM, false, 1)]
+        [MenuItem(EDM_MENU_ITEM, false, 51)]
         private static void ToggleEDM()
         {
             if (IsEDMEnabled())
diff --git a/Bugsnag/Assets/Bugsnag/Editor/BugsnagEditor.cs b/Bugsnag/Assets/Bugsnag/Editor/BugsnagEditor.cs
index dc070068b..4490d3211 100644
--- a/Bugsnag/Assets/Bugsnag/Editor/BugsnagEditor.cs
+++ b/Bugsnag/Assets/Bugsnag/Editor/BugsnagEditor.cs
@@ -15,7 +15,7 @@ public partial class BugsnagEditor : EditorWindow
 
         private bool _showBasicConfig = true;
 
-        private bool _showAdvancedSettings, _showAppInformation, _showEndpoints, _showEnabledErrorTypes, _showSwitch;
+        private bool _showAdvancedSettings, _showAppInformation, _showEndpoints, _showEnabledErrorTypes, _showSwitch, _showSymbolUpload;
 
         public Texture DarkIcon, LightIcon;
 
@@ -116,6 +116,13 @@ private void DrawSettingsEditorWindow()
                 DrawSwitchOptions(so);
             }
 
+            GUILayout.Space(5);
+            _showSymbolUpload = EditorGUILayout.Foldout(_showSymbolUpload, new GUIContent("Automatic Symbol Upload ⓘ", "Android and Xcode builds only"), true);
+            if (_showSymbolUpload)
+            {
+                DrawSymbolUploadOptions(so);
+            }
+
             GUILayout.Space(10);
 
             GUILayout.EndVertical();
@@ -141,12 +148,14 @@ private void DrawEndpoints(SerializedObject so)
             EditorGUI.indentLevel++;
             EditorGUILayout.PropertyField(so.FindProperty("NotifyEndpoint"));
             EditorGUILayout.PropertyField(so.FindProperty("SessionEndpoint"));
+            EditorGUILayout.PropertyField(so.FindProperty("UploadEndpoint"));
             EditorGUI.indentLevel--;
         }
 
         private void DrawAppInfo(SerializedObject so, BugsnagSettingsObject settings)
         {
             EditorGUI.indentLevel++;
+            EditorGUIUtility.labelWidth = 270;
             EditorGUILayout.PropertyField(so.FindProperty("AppType"));
             EditorGUILayout.PropertyField(so.FindProperty("AppVersion"));
             EditorGUILayout.PropertyField(so.FindProperty("ReleaseStage"));
@@ -196,6 +205,7 @@ private void DrawAdvancedSettings(SerializedObject so, BugsnagSettingsObject set
         private void DrawSwitchOptions(SerializedObject so)
         {
             EditorGUI.indentLevel++;
+            EditorGUIUtility.labelWidth = 270;
             EditorGUILayout.PropertyField(so.FindProperty("SwitchCacheIndex"));
             EditorGUILayout.PropertyField(so.FindProperty("SwitchCacheMaxSize"));
             EditorGUILayout.PropertyField(so.FindProperty("SwitchCacheMountName"));
@@ -203,6 +213,15 @@ private void DrawSwitchOptions(SerializedObject so)
             EditorGUI.indentLevel--;
         }
 
+        private void DrawSymbolUploadOptions(SerializedObject so)
+        {
+            EditorGUI.indentLevel++;
+            EditorGUIUtility.labelWidth = 270;
+            EditorGUILayout.PropertyField(so.FindProperty("AutoUploadSymbols"));
+            EditorGUILayout.PropertyField(so.FindProperty("BugsnagCLIExecutablePath"));
+            EditorGUI.indentLevel--;
+        }
+
         private void DrawEnabledErrorTypesDropdown(BugsnagSettingsObject settings)
         {
 
diff --git a/Bugsnag/Assets/Bugsnag/Editor/BugsnagPlayerSettingsCompat.cs b/Bugsnag/Assets/Bugsnag/Editor/BugsnagPlayerSettingsCompat.cs
index 759a5ae2a..140e30749 100644
--- a/Bugsnag/Assets/Bugsnag/Editor/BugsnagPlayerSettingsCompat.cs
+++ b/Bugsnag/Assets/Bugsnag/Editor/BugsnagPlayerSettingsCompat.cs
@@ -16,6 +16,15 @@ public static ScriptingImplementation GetScriptingBackend(BuildTargetGroup build
 #endif
         }
 
+        public static string GetApplicationIdentifier(BuildTargetGroup buildTargetGroup)
+        {
+#if UNITY_6000_0_OR_NEWER
+                return PlayerSettings.GetApplicationIdentifier(NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup));
+#else
+                return PlayerSettings.GetApplicationIdentifier(buildTargetGroup);
+#endif
+        }
+
         // Get Scripting Define Symbols
         public static string GetScriptingDefineSymbols(BuildTargetGroup buildTargetGroup)
         {
diff --git a/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload.meta b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload.meta
new file mode 100644
index 000000000..47c556265
--- /dev/null
+++ b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3755067830dfc4b978446dae96fd6f4e
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/AutoSymbolUploadToggleMenu.cs b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/AutoSymbolUploadToggleMenu.cs
new file mode 100644
index 000000000..3ff1cd007
--- /dev/null
+++ b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/AutoSymbolUploadToggleMenu.cs
@@ -0,0 +1,46 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace BugsnagUnity.Editor
+{
+
+    public class AutoSymbolUploadToggleMenu
+    {
+        private const string MENU_PATH = "Window/BugSnag/Enable Symbol Uploads";
+
+        [MenuItem(MENU_PATH,false,50)]
+        private static void ToggleAutoUpload()
+        {
+            SetEnabled(!IsEnabled());
+        }
+
+        [MenuItem(MENU_PATH, true)]
+        private static bool ToggleAutoUploadValidate()
+        {
+            Menu.SetChecked(MENU_PATH, IsEnabled());
+            return true;
+        }
+
+        static bool IsEnabled()
+        {   
+            var settings = GetSettingsObject();
+            return settings != null && settings.AutoUploadSymbols;
+        }
+
+        static void SetEnabled(bool enabled)
+        {
+            var settings = GetSettingsObject();
+            if(settings != null)
+            {
+                settings.AutoUploadSymbols = enabled;
+                EditorUtility.SetDirty(settings);
+            }
+        }
+
+        private static BugsnagSettingsObject GetSettingsObject()
+        {
+            var config = Resources.Load<BugsnagSettingsObject>("Bugsnag/BugsnagSettingsObject");
+            return config;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/AutoSymbolUploadToggleMenu.cs.meta b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/AutoSymbolUploadToggleMenu.cs.meta
new file mode 100644
index 000000000..0de830e07
--- /dev/null
+++ b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/AutoSymbolUploadToggleMenu.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b8e80cdd98acc4474a34c3bbce86be9f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs
new file mode 100644
index 000000000..88aaeed73
--- /dev/null
+++ b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs
@@ -0,0 +1,206 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using UnityEngine;
+
+namespace BugsnagUnity.Editor
+{
+    internal class BugsnagCLI
+    {
+        private const string DOWNLOADED_CLI_VERSION = "2.8.0";
+        private readonly string DOWNLOADED_CLI_PATH = Path.Combine(Application.dataPath, "../bugsnag/bin/bugsnag_cli");
+        private readonly string DOWNLOADED_CLI_URL = $"https://github.com/bugsnag/bugsnag-cli/releases/download/v{DOWNLOADED_CLI_VERSION}/";
+        private readonly string _cliExecutablePath;
+        public BugsnagCLI()
+        {
+            var config = BugsnagSettingsObject.LoadBuildTimeSettingsObject();
+
+            if (string.IsNullOrEmpty(config.BugsnagCLIExecutablePath))
+            {
+                _cliExecutablePath = DownloadBugsnagCLI();
+            }
+            else
+            {
+                _cliExecutablePath = config.BugsnagCLIExecutablePath;
+            }
+            if (!File.Exists(_cliExecutablePath))
+            {
+                throw new Exception($"BugSnag CLI not found at path: {_cliExecutablePath}");
+            }
+        }
+
+        public void UploadAndroidSymbols(string buildOutputPath, string apiKey, string versionName, int versionCode, string uploadEndpoint, string bundleId)
+        {
+            string args = $"upload unity-android --api-key={apiKey} --verbose --project-root={Application.dataPath} {buildOutputPath}";
+
+            if (!string.IsNullOrEmpty(versionName))
+            {
+                args += $" --version-name={versionName}";
+            }
+            if (versionCode > -1)
+            {
+                args += $" --version-code={versionCode}";
+            }
+            if (!string.IsNullOrEmpty(uploadEndpoint))
+            {
+                args += $" --upload-api-root-url={uploadEndpoint}";
+            }
+            if (!string.IsNullOrEmpty(bundleId))
+            {
+                args += $" --application-id={bundleId}";
+            }
+            int exitCode = StartProcess(_cliExecutablePath, args, out string output, out string error);
+
+            if (exitCode != 0)
+            {
+                throw new Exception($"Error uploading symbols: {error}\nOutput: {output}");
+            }
+        }
+
+        public string DownloadBugsnagCLI()
+        {
+            EnsureDirectoryExists();
+            if (File.Exists(DOWNLOADED_CLI_PATH) && GetCurrentCliVersion() == DOWNLOADED_CLI_VERSION)
+            {
+                return DOWNLOADED_CLI_PATH;
+            }
+            DownloadCLI();
+            MakeFileExecutable(DOWNLOADED_CLI_PATH);
+            return DOWNLOADED_CLI_PATH;
+        }
+
+        private void EnsureDirectoryExists()
+        {
+            var directory = Path.GetDirectoryName(DOWNLOADED_CLI_PATH);
+            if (!Directory.Exists(directory))
+            {
+                Directory.CreateDirectory(directory);
+            }
+        }
+
+        private void DownloadCLI()
+        {
+            string url = GetDownloadUrl();
+            if (string.IsNullOrEmpty(url))
+            {
+                throw new InvalidOperationException($"Unsupported platform: {RuntimeInformation.OSDescription}");
+            }
+
+            string tempPath = DOWNLOADED_CLI_PATH + ".tmp";
+
+            try
+            {
+                int exitCode = StartProcess("curl", $"-L {url} --output {tempPath}", out string output, out string error);
+                if (exitCode != 0)
+                {
+                    throw new InvalidOperationException($"Download failed: {error}");
+                }
+
+                if (File.Exists(DOWNLOADED_CLI_PATH))
+                {
+                    File.Delete(DOWNLOADED_CLI_PATH);
+                }
+
+                File.Move(tempPath, DOWNLOADED_CLI_PATH);
+            }
+            finally
+            {
+                if (File.Exists(tempPath))
+                {
+                    File.Delete(tempPath);
+                }
+            }
+        }
+
+        private string GetDownloadUrl()
+        {
+            string fileName = null;
+
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+            {
+                fileName = RuntimeInformation.OSArchitecture == Architecture.Arm64
+                    ? "arm64-macos-bugsnag-cli"
+                    : "x86_64-macos-bugsnag-cli";
+            }
+            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+            {
+                fileName = RuntimeInformation.OSArchitecture == Architecture.X86
+                    ? "i386-windows-bugsnag-cli.exe"
+                    : "x86_64-windows-bugsnag-cli.exe";
+            }
+            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+            {
+                fileName = RuntimeInformation.OSArchitecture == Architecture.X86
+                    ? "i386-linux-bugsnag-cli"
+                    : "x86_64-linux-bugsnag-cli";
+            }
+
+            return fileName != null ? DOWNLOADED_CLI_URL + fileName : null;
+        }
+
+        private void MakeFileExecutable(string path)
+        {
+            if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
+            {
+                int exitCode = StartProcess("chmod", $"+x {path}", out _, out _);
+                if (exitCode != 0)
+                {
+                    throw new InvalidOperationException($"Failed to make file at {path} executable");
+                }
+            }
+        }
+
+        private string GetCurrentCliVersion()
+        {
+            if (!File.Exists(DOWNLOADED_CLI_PATH))
+            {
+                UnityEngine.Debug.LogError($"BugSnag CLI not found at {DOWNLOADED_CLI_PATH}");
+                return null;
+            }
+
+            int exitCode = StartProcess(DOWNLOADED_CLI_PATH, "--version", out string output, out string error);
+            if (exitCode != 0)
+            {
+                UnityEngine.Debug.LogError($"Error checking CLI version: {error}");
+                return null;
+            }
+
+            return output.Trim();
+        }
+
+        private int StartProcess(string fileName, string arguments, out string standardOutput, out string standardError)
+        {
+            var process = new Process
+            {
+                StartInfo = new ProcessStartInfo
+                {
+                    FileName = fileName,
+                    Arguments = arguments,
+                    RedirectStandardOutput = true,
+                    RedirectStandardError = true,
+                    UseShellExecute = false,
+                    CreateNoWindow = true
+                }
+            };
+
+            process.Start();
+            standardOutput = process.StandardOutput.ReadToEnd();
+            standardError = process.StandardError.ReadToEnd();
+            process.WaitForExit();
+            return process.ExitCode;
+        }
+
+        public string GetIosDsymUploadCommand(string apiKey, string uploadEndpoint)
+        {
+            var command = $"{_cliExecutablePath} upload xcode-build --api-key={apiKey} $DWARF_DSYM_FOLDER_PATH";
+            if (!string.IsNullOrEmpty(uploadEndpoint))
+            {
+                command += $" --upload-api-root-url={uploadEndpoint}";
+            }
+            return command;
+        }
+
+    }
+}
+
diff --git a/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs.meta b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs.meta
new file mode 100644
index 000000000..a005fa954
--- /dev/null
+++ b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 25157365d8631442b8dafca4ae99c601
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagSymbolUploader.cs b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagSymbolUploader.cs
new file mode 100644
index 000000000..769da1f33
--- /dev/null
+++ b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagSymbolUploader.cs
@@ -0,0 +1,168 @@
+using System.IO;
+using UnityEditor;
+using UnityEditor.Build;
+using UnityEditor.Build.Reporting;
+#if UNITY_IOS || UNITY_STANDALONE_OSX
+using UnityEditor.iOS.Xcode;
+#endif
+#if UNITY_6000_0_OR_NEWER && UNITY_ANDROID
+using UnityEditor.Android;
+#endif
+using UnityEngine;
+
+namespace BugsnagUnity.Editor
+{
+
+    internal class BugsnagSymbolUploader : IPostprocessBuildWithReport
+    {
+        public int callbackOrder => 1;
+
+        private const string DSYM_UPLOAD_SCRIPT_TEMPLATE = @"#!/bin/bash
+if [ ""$ACTION"" == ""install"" ]; then
+    if ! <CLI_COMMAND>; then
+        echo ""Failed to upload dSYMs to BugSnag.""
+    else
+        echo ""Successfully uploaded dSYMs to BugSnag.""
+    fi
+fi
+";
+
+        private const string DSYM_UPLOAD_BUILD_PHASE_NAME = "BugSnag dSYM Upload";
+        private const string DSYM_UPLOAD_SHELL_NAME = "/bin/sh";
+
+        public void OnPostprocessBuild(BuildReport report)
+        {
+            if (!IsSupportedPlatform(report.summary.platform))
+            {
+                return;
+            }
+
+            var config = BugsnagSettingsObject.LoadBuildTimeSettingsObject();
+            if (config == null || !config.AutoUploadSymbols)
+            {
+                return;
+            }
+            var buildOutputPath = Path.GetDirectoryName(report.summary.outputPath);
+
+#if UNITY_ANDROID
+            EditorUtility.DisplayProgressBar("BugSnag Symbol Upload", "Uploading Android symbol files", 0.0f);
+            try
+            {
+                var bundleId = BugsnagPlayerSettingsCompat.GetApplicationIdentifier(report.summary.platformGroup);
+                UploadAndroidSymbols(buildOutputPath, config, bundleId);
+            }
+            catch (System.Exception e)
+            {
+                Debug.LogError($"Failed to upload Android symbol files to BugSnag. Error: {e.Message}");
+            }
+            EditorUtility.ClearProgressBar();
+#elif UNITY_IOS || UNITY_STANDALONE_OSX
+            AddXcodePostBuildScript(report.summary.outputPath , config);
+#endif
+
+        }
+
+        private bool IsSupportedPlatform(BuildTarget platform)
+        {
+            return platform == BuildTarget.Android || platform == BuildTarget.iOS || platform == BuildTarget.StandaloneOSX;
+        }
+
+        private void UploadAndroidSymbols(string buildOutputPath, BugsnagSettingsObject config, string bundleId)
+        {
+            if (!IsAndroidSymbolCreationEnabled())
+            {
+                Debug.LogError("Cannot upload Android symbols to BugSnag because Android symbol creation is disabled in the Unity Build Settings.");
+                return;
+            }
+            var cli = new BugsnagCLI();
+            cli.UploadAndroidSymbols(buildOutputPath, config.ApiKey, config.AppVersion, config.VersionCode, config.UploadEndpoint, bundleId);
+        }
+
+        private bool IsAndroidSymbolCreationEnabled()
+        {
+#if UNITY_ANDROID
+#if UNITY_6000_0_OR_NEWER
+    return  UserBuildSettings.DebugSymbols.level == Unity.Android.Types.DebugSymbolLevel.SymbolTable ||
+            UserBuildSettings.DebugSymbols.level == Unity.Android.Types.DebugSymbolLevel.Full;
+#elif UNITY_2021_1_OR_NEWER
+            return EditorUserBuildSettings.androidCreateSymbols == AndroidCreateSymbols.Public ||
+                   EditorUserBuildSettings.androidCreateSymbols == AndroidCreateSymbols.Debugging;
+#else
+            return EditorUserBuildSettings.androidCreateSymbolsZip;
+#endif
+#endif
+#pragma warning disable CS0162 // Unreachable code detected
+            return false;
+#pragma warning restore CS0162 // Unreachable code detected
+        }
+
+        private void AddXcodePostBuildScript(string pathToBuiltProject, BugsnagSettingsObject config)
+        {
+#if UNITY_IOS || UNITY_STANDALONE_OSX
+
+#if UNITY_IOS
+            var pbxProjectPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
+#endif
+#if UNITY_STANDALONE_OSX
+            var pbxProjectPath = GetMacosXcodeProjectPath(pathToBuiltProject);
+             if (!File.Exists(pbxProjectPath))
+            {
+                //Xcode export not enabled, do nothing
+                return;
+            }
+#endif
+            PBXProject pbxProject = new PBXProject();
+            pbxProject.ReadFromFile(pbxProjectPath);
+#if UNITY_IOS
+
+            var targetGuid = pbxProject.GetUnityMainTargetGuid();
+#endif
+#if UNITY_STANDALONE_OSX
+            var targetGuid = pbxProject.TargetGuidByName(Application.productName);
+#endif
+
+            foreach (var guid in pbxProject.GetAllBuildPhasesForTarget(targetGuid))
+            {
+                if (DSYM_UPLOAD_BUILD_PHASE_NAME == pbxProject.GetBuildPhaseName(guid))
+                {
+                    var editedProject = RemoveShellScriptPhase(pbxProject.WriteToString(), guid);
+                    pbxProject.ReadFromString(editedProject);
+                }
+            }
+
+            var uploadScript = GetDsymUploadCommand(config);
+            pbxProject.AddShellScriptBuildPhase(targetGuid, DSYM_UPLOAD_BUILD_PHASE_NAME, DSYM_UPLOAD_SHELL_NAME, uploadScript);
+            pbxProject.WriteToFile(pbxProjectPath);
+#endif
+        }
+
+        // The PBX library is built to expect the layout of a unity iphone xcode project, so we have to manually find the macos xcode project path
+        string GetMacosXcodeProjectPath(string outputPath)
+        {
+            string[] parts = outputPath.Split('/');
+            string xcprojFile = parts[parts.Length - 1] + ".xcodeproj";
+            return outputPath + "/" + xcprojFile + "/project.pbxproj";
+        }
+
+        private string RemoveShellScriptPhase(string project, string guid)
+        {
+            // Search for and remove the phase object from the XML. only match the guid followed by the braces
+            var matches = System.Text.RegularExpressions.Regex.Matches(project, guid + @"\s*\/\*\s*\w+\s*\*\/\s*=\s*\{([\s\S]*?)\};");
+            foreach (System.Text.RegularExpressions.Match match in matches)
+            {
+                if (match.Groups[1].Value.Contains(guid))
+                {
+                    project = project.Replace(match.Groups[0].Value, "");
+                }
+            }
+            return project;
+        }
+
+        private string GetDsymUploadCommand(BugsnagSettingsObject config)
+        {
+            var cli = new BugsnagCLI();
+            var command = cli.GetIosDsymUploadCommand(config.ApiKey, config.UploadEndpoint);
+            return DSYM_UPLOAD_SCRIPT_TEMPLATE.Replace("<CLI_COMMAND>", command);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagSymbolUploader.cs.meta b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagSymbolUploader.cs.meta
new file mode 100644
index 000000000..076e25704
--- /dev/null
+++ b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagSymbolUploader.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a240efcadfd144d44ad32d2c6ca9f17d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Bugsnag/Runtime/BugsnagSettingsObject.cs b/Bugsnag/Assets/Bugsnag/Runtime/BugsnagSettingsObject.cs
index dbf1f9b91..4b9f70361 100644
--- a/Bugsnag/Assets/Bugsnag/Runtime/BugsnagSettingsObject.cs
+++ b/Bugsnag/Assets/Bugsnag/Runtime/BugsnagSettingsObject.cs
@@ -2,6 +2,8 @@
 using UnityEngine;
 using BugsnagUnity.Payload;
 using System;
+using System.Runtime.CompilerServices;
+[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("BugsnagEditor")]
 
 namespace BugsnagUnity
 {
@@ -9,6 +11,14 @@ namespace BugsnagUnity
     public class BugsnagSettingsObject : ScriptableObject
     {
 
+        // Build time settings
+
+        public bool AutoUploadSymbols;
+        public string BugsnagCLIExecutablePath;
+        public string UploadEndpoint;
+
+        // Runtime Settings
+
         public bool StartAutomaticallyAtLaunch = true;
         public bool AutoDetectErrors = true;
         public bool AutoTrackSessions = true;
@@ -48,6 +58,16 @@ public class BugsnagSettingsObject : ScriptableObject
         public int SwitchCacheIndex = 0;
         public int SwitchCacheMaxSize = 10485760;
 
+        public static BugsnagSettingsObject LoadBuildTimeSettingsObject()
+        {
+            var settings = Resources.Load<BugsnagSettingsObject>("Bugsnag/BugsnagSettingsObject");
+            if (settings == null)
+            {
+                throw new Exception("No BugsnagSettingsObject found.");
+            }
+            return settings;
+        }
+
         public static Configuration LoadConfiguration()
         {
             var settings = Resources.Load<BugsnagSettingsObject>("Bugsnag/BugsnagSettingsObject");
diff --git a/Bugsnag/Assets/Bugsnag/Runtime/Native/Android/NativeInterface.cs b/Bugsnag/Assets/Bugsnag/Runtime/Native/Android/NativeInterface.cs
index 7db1bd811..e7106b2b5 100644
--- a/Bugsnag/Assets/Bugsnag/Runtime/Native/Android/NativeInterface.cs
+++ b/Bugsnag/Assets/Bugsnag/Runtime/Native/Android/NativeInterface.cs
@@ -1140,7 +1140,7 @@ internal static bool IsUnity2019OrNewer()
                         return true;
                     }
                 }
-                catch (System.Exception _)
+                catch
                 { // use legacy API on older versions
                     return false;
                 }
diff --git a/Bugsnag/Assets/Plugins.meta b/Bugsnag/Assets/Plugins.meta
new file mode 100644
index 000000000..7437daf1c
--- /dev/null
+++ b/Bugsnag/Assets/Plugins.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: dd78a52fe8f4944e0a2c189c2b714a47
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/MacOS.meta b/Bugsnag/Assets/Plugins/MacOS.meta
new file mode 100644
index 000000000..9bc823f19
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f8c9c4421b26f4c8da2aad5169c85b2c
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle.meta b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle.meta
new file mode 100644
index 000000000..cd2decdbb
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle.meta
@@ -0,0 +1,109 @@
+fileFormatVersion: 2
+guid: 731d6752cd77e428c8372840906bc55f
+folderAsset: yes
+PluginImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  iconMap: {}
+  executionOrder: {}
+  defineConstraints: []
+  isPreloaded: 0
+  isOverridable: 0
+  isExplicitlyReferenced: 0
+  validateReferences: 1
+  platformData:
+  - first:
+      '': Any
+    second:
+      enabled: 0
+      settings:
+        Exclude Android: 1
+        Exclude Editor: 1
+        Exclude Linux: 1
+        Exclude Linux64: 1
+        Exclude LinuxUniversal: 1
+        Exclude OSXUniversal: 0
+        Exclude WebGL: 1
+        Exclude Win: 1
+        Exclude Win64: 1
+        Exclude iOS: 1
+        Exclude tvOS: 1
+  - first:
+      Android: Android
+    second:
+      enabled: 0
+      settings:
+        CPU: ARMv7
+  - first:
+      Any: 
+    second:
+      enabled: 0
+      settings: {}
+  - first:
+      Editor: Editor
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+        DefaultValueInitialized: true
+        OS: AnyOS
+  - first:
+      Facebook: Win
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+  - first:
+      Facebook: Win64
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+  - first:
+      Standalone: Linux
+    second:
+      enabled: 0
+      settings:
+        CPU: x86
+  - first:
+      Standalone: Linux64
+    second:
+      enabled: 0
+      settings:
+        CPU: x86_64
+  - first:
+      Standalone: OSXUniversal
+    second:
+      enabled: 1
+      settings:
+        CPU: AnyCPU
+  - first:
+      Standalone: Win
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+  - first:
+      Standalone: Win64
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+  - first:
+      iPhone: iOS
+    second:
+      enabled: 0
+      settings:
+        AddToEmbeddedBinaries: false
+        CompileFlags: 
+        FrameworkDependencies: 
+  - first:
+      tvOS: tvOS
+    second:
+      enabled: 0
+      settings:
+        CompileFlags: 
+        FrameworkDependencies: 
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents.meta b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents.meta
new file mode 100644
index 000000000..f949434c9
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 81ac556d5793e40a599e060c17ac1a65
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers.meta b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers.meta
new file mode 100644
index 000000000..7ecae758e
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 5e26d5f5e43d84082b74d9d1886d1dd5
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers/very_crashy.h b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers/very_crashy.h
new file mode 100644
index 000000000..8c3867f6e
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers/very_crashy.h
@@ -0,0 +1,7 @@
+
+#ifndef very_crashy_h
+#define very_crashy_h
+
+extern "C" void crashy_signal_runner(float num);
+
+#endif
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers/very_crashy.h.meta b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers/very_crashy.h.meta
new file mode 100644
index 000000000..2c48c3d2e
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Headers/very_crashy.h.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: b407dafcd31304c4c8b5900c3c1041fa
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Info.plist b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Info.plist
new file mode 100644
index 000000000..448f452d1
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Info.plist
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>BuildMachineOSBuild</key>
+	<string>20G527</string>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>NativeCrashy</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.bugsnag.NativeCrashy</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>NativeCrashy</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSupportedPlatforms</key>
+	<array>
+		<string>MacOSX</string>
+	</array>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>DTCompiler</key>
+	<string>com.apple.compilers.llvm.clang.1_0</string>
+	<key>DTPlatformBuild</key>
+	<string>13C100</string>
+	<key>DTPlatformName</key>
+	<string>macosx</string>
+	<key>DTPlatformVersion</key>
+	<string>12.1</string>
+	<key>DTSDKBuild</key>
+	<string>21C46</string>
+	<key>DTSDKName</key>
+	<string>macosx12.1</string>
+	<key>DTXcode</key>
+	<string>1321</string>
+	<key>DTXcodeBuild</key>
+	<string>13C100</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.13</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>Copyright © 2019 Bugsnag, Inc. All rights reserved.</string>
+</dict>
+</plist>
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Info.plist.meta b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Info.plist.meta
new file mode 100644
index 000000000..b1ee91f1c
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/Info.plist.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 642c1fd1bfc0042cba34bd8b650eceff
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/MacOS.meta b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/MacOS.meta
new file mode 100644
index 000000000..e5dc4a6d7
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/MacOS.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 315b8733c81194a4f8f409d5880598d1
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/MacOS/NativeCrashy b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/MacOS/NativeCrashy
new file mode 100755
index 0000000000000000000000000000000000000000..0b6cf63fb1d2b2a2a25997dd7d82717dff517076
GIT binary patch
literal 151728
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

literal 0
HcmV?d00001

diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/MacOS/NativeCrashy.meta b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/MacOS/NativeCrashy.meta
new file mode 100644
index 000000000..4a4e6f663
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/MacOS/NativeCrashy.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 1aa3f3f0baf9245f3af51594e3ea5105
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature.meta b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature.meta
new file mode 100644
index 000000000..89b6649e8
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e543b388a25684f51b6e648c8cb3be21
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature/CodeResources b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature/CodeResources
new file mode 100644
index 000000000..b03490c68
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature/CodeResources
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>files</key>
+	<dict/>
+	<key>files2</key>
+	<dict>
+		<key>Headers/very_crashy.h</key>
+		<dict>
+			<key>hash2</key>
+			<data>
+			IUut7ssTkaX2do6LywMHBan/n92fPldPHdw/EV557hA=
+			</data>
+		</dict>
+	</dict>
+	<key>rules</key>
+	<dict>
+		<key>^Resources/</key>
+		<true/>
+		<key>^Resources/.*\.lproj/</key>
+		<dict>
+			<key>optional</key>
+			<true/>
+			<key>weight</key>
+			<real>1000</real>
+		</dict>
+		<key>^Resources/.*\.lproj/locversion.plist$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>1100</real>
+		</dict>
+		<key>^Resources/Base\.lproj/</key>
+		<dict>
+			<key>weight</key>
+			<real>1010</real>
+		</dict>
+		<key>^version.plist$</key>
+		<true/>
+	</dict>
+	<key>rules2</key>
+	<dict>
+		<key>.*\.dSYM($|/)</key>
+		<dict>
+			<key>weight</key>
+			<real>11</real>
+		</dict>
+		<key>^(.*/)?\.DS_Store$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>2000</real>
+		</dict>
+		<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
+		<dict>
+			<key>nested</key>
+			<true/>
+			<key>weight</key>
+			<real>10</real>
+		</dict>
+		<key>^.*</key>
+		<true/>
+		<key>^Info\.plist$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+		<key>^PkgInfo$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+		<key>^Resources/</key>
+		<dict>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+		<key>^Resources/.*\.lproj/</key>
+		<dict>
+			<key>optional</key>
+			<true/>
+			<key>weight</key>
+			<real>1000</real>
+		</dict>
+		<key>^Resources/.*\.lproj/locversion.plist$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>1100</real>
+		</dict>
+		<key>^Resources/Base\.lproj/</key>
+		<dict>
+			<key>weight</key>
+			<real>1010</real>
+		</dict>
+		<key>^[^/]+$</key>
+		<dict>
+			<key>nested</key>
+			<true/>
+			<key>weight</key>
+			<real>10</real>
+		</dict>
+		<key>^embedded\.provisionprofile$</key>
+		<dict>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+		<key>^version\.plist$</key>
+		<dict>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+	</dict>
+</dict>
+</plist>
diff --git a/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature/CodeResources.meta b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature/CodeResources.meta
new file mode 100644
index 000000000..a47c675ed
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/MacOS/NativeCrashy.bundle/Contents/_CodeSignature/CodeResources.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: ac48d5276982145a78ecf1f6aed49dde
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/iOS.meta b/Bugsnag/Assets/Plugins/iOS.meta
new file mode 100644
index 000000000..8f8bf5876
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/iOS.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: fa30e2757ef824a25a43ea814cf117a1
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Plugins/iOS/native_code.mm b/Bugsnag/Assets/Plugins/iOS/native_code.mm
new file mode 100644
index 000000000..24c23b14e
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/iOS/native_code.mm
@@ -0,0 +1,23 @@
+#include <stdexcept>
+#include <stdlib.h>
+
+extern "C" {
+  void RaiseCocoaSignal();
+  void TriggerCocoaCppException();
+  void TriggerCocoaAppHang();
+}
+
+void RaiseCocoaSignal() {
+    abort();
+}
+
+void TriggerCocoaCppException() {
+    throw std::runtime_error("CocoaCppException");
+}
+
+void TriggerCocoaAppHang() {
+    dispatch_async(dispatch_get_main_queue(), ^{
+        sleep(10000); //unit is seconds
+    });
+}
+
diff --git a/Bugsnag/Assets/Plugins/iOS/native_code.mm.meta b/Bugsnag/Assets/Plugins/iOS/native_code.mm.meta
new file mode 100644
index 000000000..fa0112114
--- /dev/null
+++ b/Bugsnag/Assets/Plugins/iOS/native_code.mm.meta
@@ -0,0 +1,90 @@
+fileFormatVersion: 2
+guid: e23a968953c794cd1a6a2cd8c8ee86f9
+PluginImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  iconMap: {}
+  executionOrder: {}
+  defineConstraints: []
+  isPreloaded: 0
+  isOverridable: 0
+  isExplicitlyReferenced: 0
+  validateReferences: 1
+  platformData:
+  - first:
+      : Any
+    second:
+      enabled: 0
+      settings:
+        Exclude Android: 1
+        Exclude Editor: 1
+        Exclude Linux64: 1
+        Exclude OSXUniversal: 1
+        Exclude WebGL: 1
+        Exclude Win: 1
+        Exclude Win64: 1
+        Exclude iOS: 0
+        Exclude tvOS: 1
+  - first:
+      Android: Android
+    second:
+      enabled: 0
+      settings:
+        CPU: ARMv7
+  - first:
+      Any: 
+    second:
+      enabled: 0
+      settings: {}
+  - first:
+      Editor: Editor
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+        DefaultValueInitialized: true
+        OS: AnyOS
+  - first:
+      Standalone: Linux64
+    second:
+      enabled: 0
+      settings:
+        CPU: None
+  - first:
+      Standalone: OSXUniversal
+    second:
+      enabled: 0
+      settings:
+        CPU: None
+  - first:
+      Standalone: Win
+    second:
+      enabled: 0
+      settings:
+        CPU: None
+  - first:
+      Standalone: Win64
+    second:
+      enabled: 0
+      settings:
+        CPU: None
+  - first:
+      iPhone: iOS
+    second:
+      enabled: 1
+      settings:
+        AddToEmbeddedBinaries: false
+        CPU: AnyCPU
+        CompileFlags: 
+        FrameworkDependencies: 
+  - first:
+      tvOS: tvOS
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+        CompileFlags: 
+        FrameworkDependencies: 
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Bugsnag/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset b/Bugsnag/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset
index 8b391db30..c96a16f74 100644
--- a/Bugsnag/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset
+++ b/Bugsnag/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset
@@ -12,6 +12,9 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 3e0efee821abb422baf5bb3728925f09, type: 3}
   m_Name: BugsnagSettingsObject
   m_EditorClassIdentifier: 
+  AutoUploadSymbols: 1
+  BugsnagCLIExecutablePath: 
+  UploadEndpoint: 
   StartAutomaticallyAtLaunch: 1
   AutoDetectErrors: 1
   AutoTrackSessions: 1
diff --git a/Bugsnag/Assets/Scenes/SampleScene.unity b/Bugsnag/Assets/Scenes/SampleScene.unity
index 4bc852e91..bf1a88c38 100644
--- a/Bugsnag/Assets/Scenes/SampleScene.unity
+++ b/Bugsnag/Assets/Scenes/SampleScene.unity
@@ -308,6 +308,140 @@ Transform:
   m_Father: {fileID: 0}
   m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &726503136
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 726503137}
+  - component: {fileID: 726503140}
+  - component: {fileID: 726503139}
+  - component: {fileID: 726503138}
+  m_Layer: 5
+  m_Name: CocoaCPPException
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &726503137
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 726503136}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 1572721881}
+  m_Father: {fileID: 1173133381}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &726503138
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 726503136}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_WrapAround: 0
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Selected
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 726503139}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 1303533345}
+        m_TargetAssemblyTypeName: Testing, Assembly-CSharp
+        m_MethodName: DoTriggerCocoaCppException
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+--- !u!114 &726503139
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 726503136}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &726503140
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 726503136}
+  m_CullTransparentMesh: 1
 --- !u!1 &854009149
 GameObject:
   m_ObjectHideFlags: 0
@@ -366,7 +500,7 @@ MonoBehaviour:
   m_OnCullStateChanged:
     m_PersistentCalls:
       m_Calls: []
-  m_text: TEST
+  m_text: C# Exception
   m_isRightToLeft: 0
   m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
   m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
@@ -454,6 +588,7 @@ GameObject:
   - component: {fileID: 1173133381}
   - component: {fileID: 1173133383}
   - component: {fileID: 1173133382}
+  - component: {fileID: 1173133384}
   m_Layer: 5
   m_Name: Panel
   m_TagString: Untagged
@@ -474,6 +609,7 @@ RectTransform:
   m_ConstrainProportionsScale: 0
   m_Children:
   - {fileID: 1840475927}
+  - {fileID: 726503137}
   m_Father: {fileID: 494610504}
   m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -520,6 +656,30 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 1173133380}
   m_CullTransparentMesh: 1
+--- !u!114 &1173133384
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1173133380}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Padding:
+    m_Left: 0
+    m_Right: 0
+    m_Top: 0
+    m_Bottom: 0
+  m_ChildAlignment: 4
+  m_StartCorner: 0
+  m_StartAxis: 0
+  m_CellSize: {x: 400, y: 200}
+  m_Spacing: {x: 0, y: 20}
+  m_Constraint: 1
+  m_ConstraintCount: 1
 --- !u!1 &1255953785
 GameObject:
   m_ObjectHideFlags: 0
@@ -632,6 +792,141 @@ Transform:
   m_Father: {fileID: 0}
   m_RootOrder: 3
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1572721880
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1572721881}
+  - component: {fileID: 1572721883}
+  - component: {fileID: 1572721882}
+  m_Layer: 5
+  m_Name: Text (TMP)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1572721881
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1572721880}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 726503137}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1572721882
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1572721880}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_text: CocoaCPPException
+  m_isRightToLeft: 0
+  m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
+  m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
+  m_fontSharedMaterials: []
+  m_fontMaterial: {fileID: 0}
+  m_fontMaterials: []
+  m_fontColor32:
+    serializedVersion: 2
+    rgba: 4281479730
+  m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_enableVertexGradient: 0
+  m_colorMode: 3
+  m_fontColorGradient:
+    topLeft: {r: 1, g: 1, b: 1, a: 1}
+    topRight: {r: 1, g: 1, b: 1, a: 1}
+    bottomLeft: {r: 1, g: 1, b: 1, a: 1}
+    bottomRight: {r: 1, g: 1, b: 1, a: 1}
+  m_fontColorGradientPreset: {fileID: 0}
+  m_spriteAsset: {fileID: 0}
+  m_tintAllSprites: 0
+  m_StyleSheet: {fileID: 0}
+  m_TextStyleHashCode: -1183493901
+  m_overrideHtmlColors: 0
+  m_faceColor:
+    serializedVersion: 2
+    rgba: 4294967295
+  m_fontSize: 24
+  m_fontSizeBase: 24
+  m_fontWeight: 400
+  m_enableAutoSizing: 0
+  m_fontSizeMin: 0
+  m_fontSizeMax: 0
+  m_fontStyle: 0
+  m_HorizontalAlignment: 2
+  m_VerticalAlignment: 512
+  m_textAlignment: 65535
+  m_characterSpacing: 0
+  m_wordSpacing: 0
+  m_lineSpacing: 0
+  m_lineSpacingMax: 0
+  m_paragraphSpacing: 0
+  m_charWidthMaxAdj: 0
+  m_enableWordWrapping: 0
+  m_wordWrappingRatios: 0.4
+  m_overflowMode: 0
+  m_linkedTextComponent: {fileID: 0}
+  parentLinkedComponent: {fileID: 0}
+  m_enableKerning: 0
+  m_enableExtraPadding: 0
+  checkPaddingRequired: 0
+  m_isRichText: 1
+  m_parseCtrlCharacters: 1
+  m_isOrthographic: 1
+  m_isCullingEnabled: 0
+  m_horizontalMapping: 0
+  m_verticalMapping: 0
+  m_uvLineOffset: 0
+  m_geometrySortingOrder: 0
+  m_IsTextObjectScaleStatic: 0
+  m_VertexBufferAutoSizeReduction: 0
+  m_useMaxVisibleDescender: 1
+  m_pageToDisplay: 1
+  m_margin: {x: 0, y: 0, z: 0, w: 0}
+  m_isUsingLegacyAnimationComponent: 0
+  m_isVolumetricText: 0
+  m_hasFontAssetChanged: 0
+  m_baseMaterial: {fileID: 0}
+  m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
+--- !u!222 &1572721883
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1572721880}
+  m_CullTransparentMesh: 1
 --- !u!1 &1840475926
 GameObject:
   m_ObjectHideFlags: 0
@@ -645,7 +940,7 @@ GameObject:
   - component: {fileID: 1840475929}
   - component: {fileID: 1840475928}
   m_Layer: 5
-  m_Name: Button
+  m_Name: csharpException
   m_TagString: Untagged
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
@@ -667,10 +962,10 @@ RectTransform:
   m_Father: {fileID: 1173133381}
   m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
-  m_AnchorMin: {x: 0.5, y: 0.5}
-  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
   m_AnchoredPosition: {x: 0, y: 0}
-  m_SizeDelta: {x: 472.4227, y: 254.04}
+  m_SizeDelta: {x: 0, y: 0}
   m_Pivot: {x: 0.5, y: 0.5}
 --- !u!114 &1840475928
 MonoBehaviour:
diff --git a/Bugsnag/Assets/Scripts/Testing.cs b/Bugsnag/Assets/Scripts/Testing.cs
index 91e64edff..b8cfe4707 100644
--- a/Bugsnag/Assets/Scripts/Testing.cs
+++ b/Bugsnag/Assets/Scripts/Testing.cs
@@ -1,11 +1,45 @@
 using System.Collections;
 using System.Collections.Generic;
+#if UNITY_IOS || UNITY_STANDALONE_OSX 
+
+using System.Runtime.InteropServices;
+#endif
 using UnityEngine;
 
 public class Testing : MonoBehaviour
 {
-    // Start is called before the first frame update
-   public void Throw(){
-    throw new System.Exception("This is an exception");
+   // Start is called before the first frame update
+   public void Throw()
+   {
+      throw new System.Exception("This is an exception");
    }
+
+   public void DoTriggerCocoaCppException()
+   {
+#if UNITY_IOS 
+      TriggerCocoaCppException();
+#endif
+
+#if UNITY_STANDALONE_OSX
+    crashy_signal_runner(8);
+#endif
+   }
+
+#if UNITY_STANDALONE_OSX
+
+    [DllImport("NativeCrashy")]
+    private static extern void crashy_signal_runner(float num);
+
+#endif
+
+#if UNITY_IOS 
+   [DllImport("__Internal")]
+   private static extern void RaiseCocoaSignal();
+
+   [DllImport("__Internal")]
+   private static extern void TriggerCocoaCppException();
+
+   [DllImport("__Internal")]
+   private static extern void TriggerCocoaAppHang();
+#endif
 }
diff --git a/Bugsnag/Packages/manifest.json b/Bugsnag/Packages/manifest.json
index 8ea1d9280..d31652864 100644
--- a/Bugsnag/Packages/manifest.json
+++ b/Bugsnag/Packages/manifest.json
@@ -1,14 +1,10 @@
 {
   "dependencies": {
-    "com.unity.collab-proxy": "2.5.1",
-    "com.unity.ide.rider": "3.0.31",
     "com.unity.ide.visualstudio": "2.0.22",
     "com.unity.ide.vscode": "1.2.5",
     "com.unity.test-framework": "1.1.33",
-    "com.unity.textmeshpro": "3.0.6",
-    "com.unity.timeline": "1.6.5",
+    "com.unity.textmeshpro": "3.0.9",
     "com.unity.ugui": "1.0.0",
-    "com.unity.visualscripting": "1.9.4",
     "com.unity.modules.ai": "1.0.0",
     "com.unity.modules.androidjni": "1.0.0",
     "com.unity.modules.animation": "1.0.0",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f50e1df62..cbf1ca930 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,14 @@
 # Changelog
 
-## 8.4.0 (2025-12-10)
+## TBD
+
+You can now automatically upload all your Android and iOS files for stacktrace symbolication in a few simple steps. Please see our online docs for information on how to enable this feature or script it yourself: https://docs.bugsnag.com/platforms/unity/showing-full-stacktraces/
+
+### Enhancements
+
+- Add auto symbol uploads for Android and Xcode builds. [#871](https://github.com/bugsnag/bugsnag-unity/pull/871)
+
+## 8.4.0 (2025-12-1)
 
 ### Enhancements
 
diff --git a/Gemfile b/Gemfile
index 51eb06ffb..717dfe443 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,7 +4,6 @@ gem 'rake'
 gem 'xcpretty'
 gem 'xcodeproj'
 gem 'cocoapods'
-gem 'rake'
 gem 'danger'
 
 unless Gem.win_platform?
diff --git a/features/build/build_android.feature b/features/build/build_android.feature
new file mode 100644
index 000000000..ed988ef78
--- /dev/null
+++ b/features/build/build_android.feature
@@ -0,0 +1,24 @@
+Feature: Build Android
+
+  @skip_unity_2020 # Unity 2020 only produces 4 symbol files
+  Scenario: Auto Symbol Upload
+  	When I run the script "features/scripts/prepare_fixture.sh" synchronously
+  	When I run the script "features/scripts/build_android.sh release" synchronously
+  	Then I wait to receive 6 sourcemaps
+    Then the sourcemaps Content-Type header is valid multipart form-data
+    And the sourcemap payload field "apiKey" equals "a35a2a72bd230ac0aa0f52715bbdc6aa"
+    And the sourcemap payload field "versionCode" equals "123"
+    And the sourcemap payload field "versionName" equals "1.2.3"
+    And the sourcemap payload field "appId" equals "com.bugsnag.fixtures.unity.notifier.android"
+    
+
+  @unity_2020_only
+  Scenario: Auto Symbol Upload Unity 2020
+    When I run the script "features/scripts/prepare_fixture.sh" synchronously
+    When I run the script "features/scripts/build_android.sh release" synchronously
+    Then I wait to receive 4 sourcemaps
+    Then the sourcemaps Content-Type header is valid multipart form-data
+    And the sourcemap payload field "apiKey" equals "a35a2a72bd230ac0aa0f52715bbdc6aa"
+    And the sourcemap payload field "versionCode" equals "123"
+    And the sourcemap payload field "versionName" equals "1.2.3"
+    And the sourcemap payload field "appId" equals "com.bugsnag.fixtures.unity.notifier.android"
diff --git a/features/build/build_ios.feature b/features/build/build_ios.feature
new file mode 100644
index 000000000..ac9eb3a38
--- /dev/null
+++ b/features/build/build_ios.feature
@@ -0,0 +1,9 @@
+Feature: Build iOS
+
+  Scenario: Auto Symbol Upload
+  	When I run the script "features/scripts/prepare_fixture.sh" synchronously
+    When I run the script "features/scripts/generate_xcode_project.sh release" synchronously
+  	When I run the script "features/scripts/build_ios.sh release" synchronously
+  	Then I wait to receive 2 sourcemaps
+    Then the sourcemaps Content-Type header is valid multipart form-data
+    And the sourcemap payload field "apiKey" equals "a35a2a72bd230ac0aa0f52715bbdc6aa"
diff --git a/features/csharp/csharp_events.feature b/features/csharp/csharp_events.feature
index d59918e0d..9ce1a2010 100644
--- a/features/csharp/csharp_events.feature
+++ b/features/csharp/csharp_events.feature
@@ -12,7 +12,7 @@ Feature: csharp events
     And the event "unhandled" is false
     And custom metadata is included in the event
     And the stack frame methods should match:
-      | NotifySmokeTest.Run()                                                       | Main+<RunNextMazeCommand>d__8.MoveNext() |
+      | NotifySmokeTest.Run()                                                       | Main+<RunNextMazeCommand>d__8.MoveNext() | BugsnagUnity.Client.Notify(Exception exception, HandledState handledState, Func<T, TResult> callback) |
     And expected device metadata is included in the event
     And expected app metadata is included in the event
     And the error payload field "events.0.severityReason.unhandledOverridden" is false
diff --git a/features/fixtures/maze_runner/Assets/Editor/Builder.cs b/features/fixtures/maze_runner/Assets/Editor/Builder.cs
index 59eea7505..7c37d4467 100644
--- a/features/fixtures/maze_runner/Assets/Editor/Builder.cs
+++ b/features/fixtures/maze_runner/Assets/Editor/Builder.cs
@@ -1,12 +1,9 @@
 using System.Linq;
 using UnityEngine;
-using BugsnagUnity.Editor;
-
-#if UNITY_EDITOR
+using BugsnagUnity;
 using UnityEditor;
-using UnityEditor.Callbacks;
-
-public class Builder : MonoBehaviour {
+public class Builder : MonoBehaviour
+{
 
     static void BuildStandalone(string folder, BuildTarget target, bool dev)
     {
@@ -72,14 +69,37 @@ public static void AndroidDev()
         BuildAndroid(true);
     }
 
+    private static void EnableAndroidSymbolUpload()
+    {
+#if UNITY_ANDROID
+        #if UNITY_2020_1_OR_NEWER
+        EditorUserBuildSettings.androidCreateSymbolsZip = true;
+        #else
+        EditorUserBuildSettings.androidCreateSymbols = AndroidCreateSymbols.Public;
+        #endif
+#endif
+        var settingsObject = BugsnagSettingsObject.LoadBuildTimeSettingsObject();
+        settingsObject.ApiKey = "a35a2a72bd230ac0aa0f52715bbdc6aa";
+        settingsObject.StartAutomaticallyAtLaunch = false;
+        settingsObject.AutoUploadSymbols = true;
+        settingsObject.UploadEndpoint = "http://localhost:9339";
+        settingsObject.AppVersion = "1.2.3";
+        settingsObject.VersionCode = 123;
+        EditorUtility.SetDirty(settingsObject);
+    }
+
     public static void AndroidRelease()
     {
+        EnableAndroidSymbolUpload();
         BuildAndroid(false);
     }
     // Generates the Mazerunner APK
     static void BuildAndroid(bool dev)
     {
+#if UNITY_ANDROID
+
         Debug.Log("Building Android app...");
+        PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARMv7 | AndroidArchitecture.ARM64;
         PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, "com.bugsnag.fixtures.unity.notifier.android");
         var opts = CommonMobileBuildOptions(dev ? "mazerunner_dev.apk" : "mazerunner.apk", dev);
         opts.target = BuildTarget.Android;
@@ -90,6 +110,7 @@ static void BuildAndroid(bool dev)
 
         var result = BuildPipeline.BuildPlayer(opts);
         Debug.Log("Result: " + result);
+#endif
     }
 
 
@@ -102,8 +123,20 @@ public static void IosDev()
 
     public static void IosRelease()
     {
+        EnableIosSymbolUpload();
         IosBuild(false);
     }
+
+    private static void EnableIosSymbolUpload()
+    {
+        var settingsObject = BugsnagSettingsObject.LoadBuildTimeSettingsObject();
+        settingsObject.ApiKey = "a35a2a72bd230ac0aa0f52715bbdc6aa";
+        settingsObject.StartAutomaticallyAtLaunch = false;
+        settingsObject.AutoUploadSymbols = true;
+        settingsObject.UploadEndpoint = "http://localhost:9339";
+        settingsObject.AppVersion = "1.2.3";
+        EditorUtility.SetDirty(settingsObject);
+    }
     static void IosBuild(bool dev)
     {
         Debug.Log("Building iOS app...");
@@ -121,7 +154,7 @@ public static void SwitchBuild()
     {
         Debug.Log("Building Switch app...");
         PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Switch, "com.bugsnag.fixtures.unity.notifier.ios");
-        var opts = CommonMobileBuildOptions("mazerunner.nspd",false);
+        var opts = CommonMobileBuildOptions("mazerunner.nspd", false);
         opts.target = BuildTarget.Switch;
         opts.options = BuildOptions.Development;
 
@@ -145,4 +178,3 @@ private static BuildPlayerOptions CommonMobileBuildOptions(string outputFile, bo
         return opts;
     }
 }
-#endif
diff --git a/features/fixtures/maze_runner/Assets/Resources.meta b/features/fixtures/maze_runner/Assets/Resources.meta
new file mode 100644
index 000000000..037476e64
--- /dev/null
+++ b/features/fixtures/maze_runner/Assets/Resources.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ecdc2c24362b642e49c8f2cc8485e7d7
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/features/fixtures/maze_runner/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset b/features/fixtures/maze_runner/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset
new file mode 100644
index 000000000..dbdac0529
--- /dev/null
+++ b/features/fixtures/maze_runner/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset
@@ -0,0 +1,68 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 3e0efee821abb422baf5bb3728925f09, type: 3}
+  m_Name: BugsnagSettingsObject
+  m_EditorClassIdentifier: 
+  AutoUploadSymbols: 0
+  BugsnagCLIExecutablePath: 
+  UploadEndpoint: 
+  StartAutomaticallyAtLaunch: 1
+  AutoDetectErrors: 1
+  AutoTrackSessions: 1
+  ApiKey: 
+  AppType: 
+  AppHangThresholdMillis: 0
+  AppVersion: 
+  BundleVersion: 
+  BreadcrumbLogLevel: 4
+  Context: 
+  DiscardClasses: []
+  EnabledReleaseStages: []
+  EnabledErrorTypes:
+    ANRs: 1
+    AppHangs: 1
+    OOMs: 1
+    Crashes: 1
+    ThermalKills: 1
+    UnityLog: 1
+  EnabledBreadcrumbTypes:
+    Error: 1
+    Log: 1
+    Navigation: 1
+    Process: 1
+    Request: 1
+    State: 1
+    User: 1
+  LaunchDurationMillis: 5000
+  MaximumBreadcrumbs: 100
+  MaxPersistedEvents: 32
+  MaxPersistedSessions: 128
+  MaxReportedThreads: 200
+  MaxStringValueLength: 10000
+  NotifyEndpoint: https://notify.bugsnag.com
+  NotifyLogLevel: 0
+  PersistUser: 1
+  SessionEndpoint: https://sessions.bugsnag.com
+  SendThreads: 1
+  RedactedKeys:
+  - .*password.*
+  ReleaseStage: 
+  ReportExceptionLogsAsHandled: 1
+  SendLaunchCrashesSynchronously: 1
+  SecondsPerUniqueLog: 5
+  Telemetry: 0000000001000000
+  VersionCode: -1
+  GenerateAnonymousId: 1
+  SwitchCacheType: 1
+  SwitchCacheMountName: BugsnagCache
+  SwitchCacheIndex: 0
+  SwitchCacheMaxSize: 10485760
diff --git a/features/fixtures/maze_runner/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset.meta b/features/fixtures/maze_runner/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset.meta
new file mode 100644
index 000000000..05532b6d7
--- /dev/null
+++ b/features/fixtures/maze_runner/Assets/Resources/Bugsnag/BugsnagSettingsObject.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 46b8a9d872bd745bfb19dfdd85908faa
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/features/scripts/build_android.sh b/features/scripts/build_android.sh
index 0fcad6229..4c1417a33 100755
--- a/features/scripts/build_android.sh
+++ b/features/scripts/build_android.sh
@@ -23,7 +23,7 @@ popd
 pushd "$script_path/../fixtures"
 
 # Run unity and immediately exit afterwards, log all output
-DEFAULT_CLI_ARGS="-quit -batchmode -nographics -logFile build_android_apk.log"
+DEFAULT_CLI_ARGS="-quit -batchmode -nographics -logFile build_android_apk.log -buildTarget Android"
 
 project_path=`pwd`/maze_runner
 
diff --git a/features/scripts/build_ios.sh b/features/scripts/build_ios.sh
index bece9a7b1..95ed299f6 100755
--- a/features/scripts/build_ios.sh
+++ b/features/scripts/build_ios.sh
@@ -14,15 +14,17 @@ fi
 
 BUILD_TYPE=$1
 
-pushd "${0%/*}"
-  script_path=`pwd`
-popd
-pushd "$script_path/../fixtures"
-project_path=`pwd`/maze_runner
+pushd "${0%/*}" >/dev/null
+  script_path=$(pwd)
+popd >/dev/null
+pushd "$script_path/../fixtures" >/dev/null
+  project_path="$(pwd)/maze_runner"
+popd >/dev/null
 
 # Clean any previous builds
-find $project_path/output/ -name "*.ipa" -exec rm '{}' \;
+find "$project_path/output/" -name "*.ipa" -exec rm '{}' \;
 
+# Determine which Xcode project and IPA name to use
 if [ "$BUILD_TYPE" == "dev" ]; then
   XCODE_PROJECT="mazerunner_dev_xcode/Unity-iPhone.xcodeproj"
   OUTPUT_IPA="mazerunner_dev_${UNITY_VERSION:0:4}.ipa"
@@ -34,33 +36,36 @@ else
   exit 1
 fi
 
-# Archive and export the project
-xcrun xcodebuild -project $project_path/$XCODE_PROJECT \
-                 -scheme Unity-iPhone \
-                 -configuration Debug \
-                 -archivePath $project_path/archive/Unity-iPhone.xcarchive \
-                 -allowProvisioningUpdates \
-                 -allowProvisioningDeviceRegistration \
-                 -quiet \
-                 GCC_WARN_INHIBIT_ALL_WARNINGS=YES \
-                 archive
+# ARCHIVE (equivalent to Product > Archive)
+xcrun xcodebuild \
+  -project "$project_path/$XCODE_PROJECT" \
+  -scheme Unity-iPhone \
+  -configuration Release \
+  clean archive \
+  -archivePath "$project_path/archive/Unity-iPhone.xcarchive" \
+  -allowProvisioningUpdates \
+  -allowProvisioningDeviceRegistration \
+  -quiet \
+  GCC_WARN_INHIBIT_ALL_WARNINGS=YES
 
-if [ $? -ne 0 ]
-then
+if [ $? -ne 0 ]; then
   echo "Failed to archive project"
   exit 1
 fi
 
+# EXPORT ARCHIVE
 xcrun xcodebuild -exportArchive \
-                 -archivePath $project_path/archive/Unity-iPhone.xcarchive \
-                 -exportPath $project_path/output/ \
-                 -quiet \
-                 -exportOptionsPlist $script_path/exportOptions.plist
+  -archivePath "$project_path/archive/Unity-iPhone.xcarchive" \
+  -exportPath "$project_path/output/" \
+  -exportOptionsPlist "$script_path/exportOptions.plist" \
+  -quiet
 
 if [ $? -ne 0 ]; then
   echo "Failed to export app"
   exit 1
 fi
 
-# Move to known location for running (note - the name of the .ipa differs between Xcode versions)
-find $project_path/output/ -name "*.ipa" -exec mv '{}' $project_path/$OUTPUT_IPA \;
+# MOVE IPA TO A KNOWN LOCATION
+find "$project_path/output/" -name "*.ipa" -exec mv '{}' "$project_path/$OUTPUT_IPA" \;
+
+echo "Successfully built and exported: $OUTPUT_IPA"
\ No newline at end of file
diff --git a/features/scripts/generate_xcode_project.sh b/features/scripts/generate_xcode_project.sh
index 6dc9462af..cb637e697 100755
--- a/features/scripts/generate_xcode_project.sh
+++ b/features/scripts/generate_xcode_project.sh
@@ -22,7 +22,7 @@ popd
 
 pushd "$script_path/../fixtures"
 
-DEFAULT_CLI_ARGS="-quit -nographics -batchmode -logFile unity.log"
+DEFAULT_CLI_ARGS="-quit -nographics -batchmode -logFile unity.log -buildTarget iOS"
 
 project_path=`pwd`/maze_runner
 
diff --git a/features/steps/unity_steps.rb b/features/steps/unity_steps.rb
index 45b7bb6d5..aea18add7 100644
--- a/features/steps/unity_steps.rb
+++ b/features/steps/unity_steps.rb
@@ -19,6 +19,12 @@ def execute_command(action, scenario_name = '')
   raise 'Test fixture did not GET /command' unless Maze::Server.commands.remaining.empty?
 end
 
+Then('the sourcemaps Content-Type header is valid multipart form-data') do
+  expected = /^multipart\/form-data; boundary=([^;]+)/
+  actual = Maze::Server.sourcemaps.current[:request]['content-type']
+  Maze.check.match(expected, actual)
+end
+
 When('I clear the Bugsnag cache') do
   case Maze::Helper.get_current_platform
   when 'macos', 'webgl'
@@ -151,18 +157,33 @@ def check_error_reporting_api(notifier_name)
   stacktrace = Maze::Helper.read_key_path(Maze::Server.errors.current[:body], 'events.0.exceptions.0.stacktrace')
   expected_frame_values = expected_values.raw
 
-  flunk('The stacktrace is empty') if stacktrace.length == 0
+  flunk('The stacktrace is empty') if stacktrace.empty?
 
+  # Extract just the method names from the stacktrace
   methods = stacktrace.map { |item| item['method'] }
 
+  # For each set of expected frames, check if at least one method matches
   expected_frame_values.each do |expected_frames|
     method_index = 0
     frame_matches = false
+
+    # Keep iterating over `methods` until we find a match or exhaust all
     until frame_matches || method_index.eql?(methods.size)
       method = methods[method_index]
-      frame_matches = expected_frames.any? { |frame| frame == method }
+
+      # Sanitize the actual method to ignore any numeric portion in 'd__<number>'
+      sanitized_method = method.gsub(/d__\d+/, 'd__REPLACEMENT')
+
+      # Check each expected frame for a match by also sanitizing it
+      frame_matches = expected_frames.any? do |frame|
+        sanitized_frame = frame.gsub(/d__\d+/, 'd__REPLACEMENT')
+        sanitized_method == sanitized_frame
+      end
+
       method_index += 1
     end
+
+    # Fail if we didn't find a match for this set of expected frames
     Maze.check.true(frame_matches, "None of the methods match the expected frames #{expected_frames}")
   end
 end
diff --git a/features/support/env.rb b/features/support/env.rb
index ded754708..343e58aed 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -18,6 +18,14 @@
   end
 end
 
+Before('@unity_2020_only') do
+  if ENV['UNITY_VERSION']
+    unity_version = ENV['UNITY_VERSION'][0..3].to_i
+    if unity_version != 2020
+      skip_this_scenario('Skipping scenario, this scenario is only for Unity 2020')
+    end
+  end
+end
 
 Before('@skip_webgl') do |_scenario|
   skip_this_scenario('Skipping scenario') unless Maze.config.browser.nil?
@@ -180,7 +188,9 @@
 AfterAll do
   case Maze::Helper.get_current_platform
   when 'macos'
-    app_name = Maze.config.app.gsub /\.app$/, ''
-    Maze::Runner.run_command("log show --predicate '(process == \"#{app_name}\")' --style syslog --start '#{Maze.start_time}' > #{app_name}.log")
+    if !Maze.config.app.nil?
+      app_name = Maze.config.app.gsub /\.app$/, ''
+      Maze::Runner.run_command("log show --predicate '(process == \"#{app_name}\")' --style syslog --start '#{Maze.start_time}' > #{app_name}.log")
+    end
   end
 end

From 63a59b107ed8f2ffb5d909cf34261a5be613bcd1 Mon Sep 17 00:00:00 2001
From: Richard Elms <richardelms@gmail.com>
Date: Mon, 27 Jan 2025 10:25:41 +0100
Subject: [PATCH 2/4] Update BugsnagCLI.cs (#872)

bump the cli version used in symbol upload to 2.9.1
---
 Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs
index 88aaeed73..99b4cb2f9 100644
--- a/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs
+++ b/Bugsnag/Assets/Bugsnag/Editor/SymbolUpload/BugsnagCLI.cs
@@ -8,7 +8,7 @@ namespace BugsnagUnity.Editor
 {
     internal class BugsnagCLI
     {
-        private const string DOWNLOADED_CLI_VERSION = "2.8.0";
+        private const string DOWNLOADED_CLI_VERSION = "2.9.1";
         private readonly string DOWNLOADED_CLI_PATH = Path.Combine(Application.dataPath, "../bugsnag/bin/bugsnag_cli");
         private readonly string DOWNLOADED_CLI_URL = $"https://github.com/bugsnag/bugsnag-cli/releases/download/v{DOWNLOADED_CLI_VERSION}/";
         private readonly string _cliExecutablePath;

From 5c448f6b152e2c31df866d5b46a9e833f1a5b193 Mon Sep 17 00:00:00 2001
From: richard elms <richardelms@gmail.com>
Date: Mon, 27 Jan 2025 11:03:50 +0100
Subject: [PATCH 3/4] Release v8.4.0

---
 Bugsnag/Assets/Bugsnag/Runtime/AssemblyInfo.cs | 2 +-
 CHANGELOG.md                                   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Bugsnag/Assets/Bugsnag/Runtime/AssemblyInfo.cs b/Bugsnag/Assets/Bugsnag/Runtime/AssemblyInfo.cs
index e427edf37..9dcda8eb6 100644
--- a/Bugsnag/Assets/Bugsnag/Runtime/AssemblyInfo.cs
+++ b/Bugsnag/Assets/Bugsnag/Runtime/AssemblyInfo.cs
@@ -1,2 +1,2 @@
 using System.Reflection;
-[assembly: AssemblyVersion("8.4.0.0")]
\ No newline at end of file
+[assembly: AssemblyVersion("8.5.0.0")]
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cbf1ca930..aa9515517 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,6 @@
 # Changelog
 
-## TBD
+## 8.5.0 (2025-27-01)
 
 You can now automatically upload all your Android and iOS files for stacktrace symbolication in a few simple steps. Please see our online docs for information on how to enable this feature or script it yourself: https://docs.bugsnag.com/platforms/unity/showing-full-stacktraces/
 
@@ -8,7 +8,7 @@ You can now automatically upload all your Android and iOS files for stacktrace s
 
 - Add auto symbol uploads for Android and Xcode builds. [#871](https://github.com/bugsnag/bugsnag-unity/pull/871)
 
-## 8.4.0 (2025-12-1)
+## 8.4.0 (2025-12-01)
 
 ### Enhancements
 

From a5ac2ddd1adbc89d3a12a1a6a5a857f16cc8dc54 Mon Sep 17 00:00:00 2001
From: Richard Elms <richardelms@gmail.com>
Date: Mon, 27 Jan 2025 11:11:41 +0100
Subject: [PATCH 4/4] Update CHANGELOG.md

Co-authored-by: Tom Longridge <tom@bugsnag.com>
---
 CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index aa9515517..3342e531e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,6 @@
 # Changelog
 
-## 8.5.0 (2025-27-01)
+## 8.5.0 (2025-01-27)
 
 You can now automatically upload all your Android and iOS files for stacktrace symbolication in a few simple steps. Please see our online docs for information on how to enable this feature or script it yourself: https://docs.bugsnag.com/platforms/unity/showing-full-stacktraces/