diff --git a/CHANGELOG.md b/CHANGELOG.md index 6987a217..5d0cb361 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Backtrace Unity Release Notes +## Version 3.1.1 +- Prevent erroneously extending backtraceClient attributes with backtraceReport attributes. +- Removed randomly generated path to assembly from callstacks. +- Prevent client from multi initialization. + ## Version 3.1.0 This release adds an ability to capture native NDK crashes from Unity games deployed on Android. The Backtrace Configuration now exposes a setting for games being prepared for Android OS to choose `Capture native crashes`. When enabled, Backtrace will capture and symbolicate native stack traces from crashes impacting the Unity Engine or any Unity Engine Plugin. diff --git a/README.md b/README.md index 1bd66554..84b8ce57 100644 --- a/README.md +++ b/README.md @@ -235,11 +235,7 @@ backtraceClient.BeforeSend = ## Reporting unhandled application exceptions -`BacktraceClient` supports reporting of unhandled application exceptions not captured by your try-catch blocks. To enable reporting of unhandled exceptions even if you don't set this option in `Backtrace configuration window` please use code below: - -```csharp -backtraceClient.HandleApplicationException(); -``` +`BacktraceClient` supports reporting of unhandled application exceptions not captured by your try-catch blocks. To enable reporting of unhandled exceptions please use Backtrace configuration UI available in the Unity IDE. ## Filtering a report Report filtering is enabled by using the `Filter reports` option in the user interface or for more advanced use-cases, the `SkipReport` delegate available in the BacktraceClient. diff --git a/Runtime/BacktraceClient.cs b/Runtime/BacktraceClient.cs index b5c702c6..6b6f4a8b 100644 --- a/Runtime/BacktraceClient.cs +++ b/Runtime/BacktraceClient.cs @@ -39,7 +39,7 @@ public string this[string index] set { _clientAttributes[index] = value; - if(_nativeClient != null) + if (_nativeClient != null) { _nativeClient.SetAttribute(index, value); } @@ -58,6 +58,14 @@ public void SetAttributes(Dictionary attributes) } } + /// + /// Number of client attributes + /// + public int GetAttributesCount() + { + return _clientAttributes.Count; + } + /// /// Backtrace client instance. /// @@ -261,6 +269,11 @@ public void Refresh() return; } + if (Instance != null) + { + return; + } + Enabled = true; CaptureUnityMessages(); @@ -528,7 +541,8 @@ private BacktraceData SetupBacktraceData(BacktraceReport report) ? _clientAttributes : _nativeClient.GetAttributes().Merge(_clientAttributes); - return report.ToBacktraceData(reportAttributes, GameObjectDepth); + // pass copy of dictionary to prevent overriding client attributes + return report.ToBacktraceData(new Dictionary(reportAttributes), GameObjectDepth); } #if UNITY_ANDROID diff --git a/Runtime/BacktraceDatabase.cs b/Runtime/BacktraceDatabase.cs index ebefd357..b13123a5 100644 --- a/Runtime/BacktraceDatabase.cs +++ b/Runtime/BacktraceDatabase.cs @@ -111,6 +111,10 @@ public void Reload() { Configuration = GetComponent().Configuration; } + if (Instance != null) + { + return; + } if (Configuration == null || !Configuration.IsValid()) { Enable = false; diff --git a/Runtime/Model/BacktraceData.cs b/Runtime/Model/BacktraceData.cs index 99c844cc..a5757cc5 100644 --- a/Runtime/Model/BacktraceData.cs +++ b/Runtime/Model/BacktraceData.cs @@ -45,7 +45,7 @@ public class BacktraceData /// /// Version of the C# library /// - public const string AgentVersion = "3.1.0"; + public const string AgentVersion = "3.1.1"; /// /// Application thread details diff --git a/Runtime/Model/BacktraceStackFrame.cs b/Runtime/Model/BacktraceStackFrame.cs index 566c5df6..ebb2bf3e 100644 --- a/Runtime/Model/BacktraceStackFrame.cs +++ b/Runtime/Model/BacktraceStackFrame.cs @@ -70,9 +70,13 @@ public BacktraceJObject ToJson() ["il"] = Il, ["metadata_token"] = MemberInfo, ["address"] = ILOffset, - ["library"] = Library, ["assembly"] = Assembly }; + + if (!string.IsNullOrEmpty(Library) && !(Library.StartsWith("<") && Library.EndsWith(">"))) + { + stackFrame["library"] = Library; + } if (Line != 0) { diff --git a/Runtime/Model/BacktraceUnhandledException.cs b/Runtime/Model/BacktraceUnhandledException.cs index ba05d316..0388c690 100644 --- a/Runtime/Model/BacktraceUnhandledException.cs +++ b/Runtime/Model/BacktraceUnhandledException.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; namespace Backtrace.Unity.Model { @@ -43,7 +42,7 @@ public override string StackTrace /// /// Unhandled exception stack frames /// - public List StackFrames = new List(); + public readonly List StackFrames = new List(); public BacktraceUnhandledException(string message, string stacktrace) : base(message) diff --git a/Tests/Runtime/BacktraceAttributeTests.cs b/Tests/Runtime/BacktraceAttributeTests.cs index f81047fa..8d3555f8 100644 --- a/Tests/Runtime/BacktraceAttributeTests.cs +++ b/Tests/Runtime/BacktraceAttributeTests.cs @@ -43,6 +43,28 @@ public IEnumerator TesClientAttributeAccessor_BacktraceDataShouldIncludeClientAt yield return null; } + [UnityTest] + public IEnumerator TesClientAttributes_ReprotShouldntExtendClientAttributes_ClientAttributesWontStoreReportAttributes() + { + var key = "foo"; + var value = "bar"; + BacktraceClient[key] = value; + BacktraceData data = null; + BacktraceClient.BeforeSend = (BacktraceData reportData) => + { + data = reportData; + return null; + }; + BacktraceClient.Send(new Exception("foo")); + yield return new WaitForEndOfFrame(); + Assert.IsNotNull(data); + Assert.AreEqual(data.Attributes.Attributes[key], value); + Assert.AreEqual(1, BacktraceClient.GetAttributesCount()); + BacktraceClient.Send(new Exception("bar")); + Assert.AreEqual(1, BacktraceClient.GetAttributesCount()); + yield return null; + } + [UnityTest] public IEnumerator TesClientAttributesMethod_BacktraceDataShouldIncludeClientAttributes_ClientAttributesAreAvailableInDiagnosticData() @@ -80,8 +102,8 @@ public IEnumerator TestAttributesGeneration_CreateCorrectAttributes_WithDiffrent yield return null; } - [UnityTest] - public IEnumerator TestCorrectDictionaryGeneration_CreateCorrectAttributesDictionary_WithDiffrentClientAttributes() + [Test] + public void TestCorrectDictionaryGeneration_CreateCorrectAttributesDictionary_WithDiffrentClientAttributes() { var exception = new FileNotFoundException(); var reportAttributeKey = "report_attr"; @@ -98,19 +120,6 @@ public IEnumerator TestCorrectDictionaryGeneration_CreateCorrectAttributesDictio Assert.IsTrue(testObject.Attributes.Keys.Any(n => n == reportAttributeKey)); Assert.IsTrue(testObject.Attributes[clientAttributeKey] == clientAttributeValue); Assert.IsTrue(testObject.Attributes[reportAttributeKey] == reportAttributeValue); - yield return null; - } - - [UnityTest] - public IEnumerator TestCorrectDictionaryGeneration_ReplaceAttributes_TheSameDictionaryAttributes() - { - var reportAttributeKey = "report_attr"; - var reportAttributeValue = string.Format("{0}-value", reportAttributeKey); - var clientAttributes = new Dictionary() { { reportAttributeKey, - string.Format("{0}-client", reportAttributeValue) - } }; - Assert.IsFalse(clientAttributes[reportAttributeKey] == reportAttributeValue); - yield return null; } } } diff --git a/package.json b/package.json index b47c8b4f..d319e8ea 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "io.backtrace.unity", "displayName": "Backtrace", - "version": "3.1.0", + "version": "3.1.1", "unity": "2017.1", "description": "Backtrace's integration with Unity games allows customers to capture and report handled and unhandled Unity exceptions to their Backtrace instance, instantly offering the ability to prioritize and debug software errors.", "keywords": [