Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified Android/lib/arm64-v8a/libbacktrace-native.so
Binary file not shown.
Binary file modified Android/lib/armeabi-v7a/libbacktrace-native.so
Binary file not shown.
Binary file modified Android/lib/x86/libbacktrace-native.so
Binary file not shown.
2 changes: 1 addition & 1 deletion Editor/BacktraceClientConfigurationEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public override void OnInspectorGUI()
#else
settings.IgnoreSslValidation = false;
#endif
#if UNITY_ANDROID
#if UNITY_ANDROID || UNITY_IOS
settings.HandleANR = EditorGUILayout.Toggle(BacktraceConfigurationLabels.LABEL_HANDLE_ANR, settings.HandleANR);
#endif
settings.GameObjectDepth = EditorGUILayout.IntField(BacktraceConfigurationLabels.LABEL_GAME_OBJECT_DEPTH, settings.GameObjectDepth);
Expand Down
10 changes: 5 additions & 5 deletions Editor/BacktraceConfigurationEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ public override void OnInspectorGUI()
serializedObject.FindProperty("IgnoreSslValidation"),
new GUIContent(BacktraceConfigurationLabels.LABEL_IGNORE_SSL_VALIDATION));
#endif
#if UNITY_ANDROID
#if UNITY_ANDROID || UNITY_IOS
EditorGUILayout.PropertyField(
serializedObject.FindProperty("HandleANR"),
new GUIContent(BacktraceConfigurationLabels.LABEL_HANDLE_ANR));

#if UNITY_2019_2_OR_NEWER
EditorGUILayout.PropertyField(
serializedObject.FindProperty("SymbolsUploadToken"),
new GUIContent(BacktraceConfigurationLabels.LABEL_SYMBOLS_UPLOAD_TOKEN));
#if UNITY_2019_2_OR_NEWER && UNITY_ANDROID
EditorGUILayout.PropertyField(
serializedObject.FindProperty("SymbolsUploadToken"),
new GUIContent(BacktraceConfigurationLabels.LABEL_SYMBOLS_UPLOAD_TOKEN));
#endif
#endif
EditorGUILayout.PropertyField(
Expand Down
64 changes: 55 additions & 9 deletions Runtime/BacktraceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,12 @@ public static BacktraceClient Initialize(BacktraceConfiguration configuration, D
}
var backtrackGameObject = new GameObject(gameObjectName, typeof(BacktraceClient), typeof(BacktraceDatabase));
BacktraceClient backtraceClient = backtrackGameObject.GetComponent<BacktraceClient>();
BacktraceDatabase backtraceDatabase = backtrackGameObject.GetComponent<BacktraceDatabase>();

backtraceDatabase.Configuration = configuration;
backtraceClient.Configuration = configuration;
if (configuration.Enabled)
{
BacktraceDatabase backtraceDatabase = backtrackGameObject.GetComponent<BacktraceDatabase>();
backtraceDatabase.Configuration = configuration;
}
backtrackGameObject.SetActive(true);
backtraceClient.Refresh();
backtraceClient.SetAttributes(attributes);
Expand Down Expand Up @@ -371,12 +373,15 @@ public void Refresh()
DontDestroyOnLoad(gameObject);
_instance = this;
}
Database = GetComponent<BacktraceDatabase>();
if (Database != null)
if (Configuration.Enabled)
{
Database.Reload();
Database.SetApi(BacktraceApi);
Database.SetReportWatcher(_reportLimitWatcher);
Database = GetComponent<BacktraceDatabase>();
if (Database != null)
{
Database.Reload();
Database.SetApi(BacktraceApi);
Database.SetReportWatcher(_reportLimitWatcher);
}
}

_nativeClient = NativeClientFactory.GetNativeClient(Configuration, name);
Expand All @@ -400,10 +405,23 @@ private void Awake()
Refresh();
}

/// <summary>
/// Update native client internal ANR timer.
/// </summary>
private void Update()
{
_nativeClient?.UpdateClientTime(Time.time);
}

private void OnDestroy()
{
Enabled = false;
Application.logMessageReceived -= HandleUnityMessage;
#if UNITY_ANDROID || UNITY_IOS
Application.lowMemory -= HandleLowMemory;
_nativeClient?.Disable();
#endif

}

/// <summary>
Expand Down Expand Up @@ -520,7 +538,7 @@ private IEnumerator CollectDataAndSend(BacktraceReport report, Action<BacktraceR
}
BacktraceDatabaseRecord record = null;

if (Database != null)
if (Database != null && Database.Enabled())
{
yield return new WaitForEndOfFrame();
if (EnablePerformanceStatistics)
Expand Down Expand Up @@ -569,6 +587,10 @@ record = Database.Add(data);
queryAttributes["performance.json"] = stopWatch.GetMicroseconds();
}
yield return new WaitForEndOfFrame();
if (string.IsNullOrEmpty(json))
{
yield break;
}

//backward compatibility
if (RequestHandler != null)
Expand Down Expand Up @@ -673,9 +695,33 @@ private void CaptureUnityMessages()
if (Configuration.HandleUnhandledExceptions || Configuration.NumberOfLogs != 0)
{
Application.logMessageReceived += HandleUnityMessage;
#if UNITY_ANDROID || UNITY_IOS
Application.lowMemory += HandleLowMemory;
#endif
}
}

#if UNITY_ANDROID || UNITY_IOS
internal void HandleLowMemory()
{
if (!Enabled)
{
Debug.LogWarning("Please enable BacktraceClient first.");
return;
}
const string lowMemoryMessage = "OOMException: Out of memory detected.";
_backtraceLogManager.Enqueue(new BacktraceUnityMessage(lowMemoryMessage, string.Empty, LogType.Error));

// try to send report about OOM from managed layer if native layer is disabled.
bool nativeSendResult = _nativeClient != null ? _nativeClient.OnOOM() : false;
if (!nativeSendResult)
{
var oom = new BacktraceUnhandledException(lowMemoryMessage, string.Empty);
SendUnhandledException(oom);
}
}
#endif

/// <summary>
/// Catch Unity logger data and create Backtrace reports for log type that represents exception or error
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions Runtime/BacktraceDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,15 @@ public void SetApi(IBacktraceApi backtraceApi)
BacktraceApi = backtraceApi;
}

/// <summary>
/// Validate if BacktraceDatabase is enabled
/// </summary>
/// <returns>true if BacktraceDatabase is enabled. Otherwise false.</returns>
public bool Enabled()
{
return Enable;
}

/// <summary>
/// Get settings
/// </summary>
Expand Down
6 changes: 6 additions & 0 deletions Runtime/Interfaces/IBacktraceDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,11 @@ public interface IBacktraceDatabase
/// <param name="lock">Lock report - default true</param>
/// <returns>Backtrace record</returns>
BacktraceDatabaseRecord Add(BacktraceData data, bool @lock = true);

/// <summary>
/// Validate if BacktraceDatabase is enabled
/// </summary>
/// <returns>true if BacktraceDatabase is enabled. Otherwise false.</returns>
bool Enabled();
}
}
4 changes: 2 additions & 2 deletions Runtime/Model/BacktraceConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public class BacktraceConfiguration : ScriptableObject
/// </summary>
[Tooltip("Capture native NDK Crashes (ANDROID API 21+)")]
#elif UNITY_IOS
/// <summary>
/// <summary>
/// Capture native iOS Crashes.
/// </summary>
[Tooltip("Capture native Crashes")]
Expand All @@ -106,7 +106,7 @@ public class BacktraceConfiguration : ScriptableObject
public bool CaptureNativeCrashes = true;
#endif

#if UNITY_ANDROID
#if UNITY_ANDROID || UNITY_IOS
/// <summary>
/// Handle ANR events - Application not responding
/// </summary>
Expand Down
43 changes: 41 additions & 2 deletions Runtime/Model/BacktraceStackFrame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public string FileName
return string.IsNullOrEmpty(Library)
? GetFileNameFromFunctionName()
: Library.IndexOfAny(Path.GetInvalidPathChars()) == -1 && Path.HasExtension(Path.GetFileName(Library))
? Path.GetFileName(Library).Trim()
? GetFileNameFromLibraryName()
: GetFileNameFromFunctionName();
}
}
Expand Down Expand Up @@ -186,6 +186,31 @@ private string GetMethodName(MethodBase method)
return string.Format("{0}.{1}()", method.DeclaringType == null ? null : method.DeclaringType.ToString(), methodName);
}

private string GetFileNameFromLibraryName()
{
var libraryName = Path.GetFileName(Library).Trim();

// detect namespace
var lastSeparatorIndex = libraryName.LastIndexOf(".");
if (lastSeparatorIndex == -1 || libraryName.IndexOf(".") == lastSeparatorIndex)
{
// detected full path to source code
return libraryName;
}

// omit '.' character that substring will return based on lastSeparatorIndex
libraryName = libraryName.Substring(lastSeparatorIndex + 1);
switch (StackFrameType)
{
case BacktraceStackFrameType.Dotnet:
return string.Format("{0}.cs", libraryName);
case BacktraceStackFrameType.Android:
return string.Format("{0}.java", libraryName);
default:
return libraryName;
}
}

/// <summary>
/// Generate file name based on full functiom name
/// </summary>
Expand Down Expand Up @@ -219,7 +244,21 @@ private string GetFileNameFromFunctionName()
}

var libraryPath = FunctionName.Substring(0, separatorIndex).Split(new char[] { '.' });
var fileName = libraryPath[libraryPath.Length - 1];
// handle situation when function name is a constructor path or specific module path
var currentIndex = libraryPath.Length - 1;
string fileName = libraryPath[currentIndex];

while (string.IsNullOrEmpty(fileName) && currentIndex > 0)
{
fileName = libraryPath[currentIndex - 1];
currentIndex--;

}
if (string.IsNullOrEmpty(fileName))
{
return Library;
}

if (fileName.IndexOfAny(Path.GetInvalidPathChars()) == -1 && Path.HasExtension(fileName) || StackFrameType == BacktraceStackFrameType.Unknown)
{
return fileName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Backtrace.Unity.Common;
using Backtrace.Unity.Types;
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
Expand Down
7 changes: 6 additions & 1 deletion Runtime/Model/JsonData/BacktraceAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,15 @@ internal void SetExceptionAttributes(BacktraceReport report)
}
if (report.Exception is BacktraceUnhandledException)
{
if ((report.Exception as BacktraceUnhandledException).Classifier == "ANRException")
var classifier = (report.Exception as BacktraceUnhandledException).Classifier;
if (classifier == "ANRException")
{
Attributes[errorType] = "Hang";
}
else if (classifier == "OOMException")
{
Attributes[errorType] = "oom";
}
else
{
Attributes[errorType] = "Unhandled exception";
Expand Down
Loading