|
|
@@ -1,2237 +0,0 @@
|
|
|
-// ----------------------------------------
|
|
|
-//
|
|
|
-// CrashSightAgent.cs
|
|
|
-//
|
|
|
-// Author:
|
|
|
-// Yeelik,
|
|
|
-//
|
|
|
-// Copyright (c) 2015 CrashSight. All rights reserved.
|
|
|
-//
|
|
|
-// ----------------------------------------
|
|
|
-//
|
|
|
-using UnityEngine;
|
|
|
-
|
|
|
-using System;
|
|
|
-using System.Collections.Generic;
|
|
|
-using System.Diagnostics;
|
|
|
-using System.Reflection;
|
|
|
-using System.Text;
|
|
|
-using System.Text.RegularExpressions;
|
|
|
-using System.Threading;
|
|
|
-using System.Globalization;
|
|
|
-
|
|
|
-using GCloud.UQM;
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// [EN] Defines the logType<br/>
|
|
|
-/// [ZH] 定义日志的级别
|
|
|
-/// </summary>
|
|
|
-/// <remarks>
|
|
|
-/// [EN] We dont use LogType enum in Unity as the numerical order doesnt suit our purposes<br/>
|
|
|
-/// [ZH] 我们未使用 Unity 的 LogType 枚举,因其数值顺序不符合需求
|
|
|
-/// </remarks>
|
|
|
-public enum CSLogSeverity
|
|
|
-{
|
|
|
- LogSilent,
|
|
|
- LogError,
|
|
|
- LogWarning,
|
|
|
- LogInfo,
|
|
|
- LogDebug,
|
|
|
- LogVerbose
|
|
|
-}
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// [EN] Defines the output type of the log report<br/>
|
|
|
-/// [ZH] 定义日志报告的输出方式类型
|
|
|
-/// </summary>
|
|
|
-public enum CSReportType
|
|
|
-{
|
|
|
- InterfaceReport,
|
|
|
- LogCallback,
|
|
|
- LogCallbackThreaded
|
|
|
-}
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// [EN] Defines information options for jank report<br/>
|
|
|
-/// [ZH] 定义卡顿报告的信息选项
|
|
|
-/// </summary>
|
|
|
-public enum JankReportInfoOption
|
|
|
-{
|
|
|
- JankOnlyBasicInfo = 0,
|
|
|
- JankSystemLog = 1,
|
|
|
- JankCustomLog = 2,
|
|
|
- JankCustomKv = 4,
|
|
|
- JankCallbackInfo = 8,
|
|
|
- JankAutoDumpStack = 16,
|
|
|
- JankAndroidAllJavaStack = 32
|
|
|
-}
|
|
|
-
|
|
|
-/// <summary>
|
|
|
-/// CrashSight agent.
|
|
|
-/// </summary>
|
|
|
-public sealed class CrashSightAgent
|
|
|
-{
|
|
|
- private static string crashUploadUrl = string.Empty;
|
|
|
-
|
|
|
- public static List<int> callbackThreads = new List<int>();
|
|
|
-
|
|
|
- public static object callbackThreadsLock = new object();
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Defines the log callback delegate<br/>
|
|
|
- /// [ZH] 定义日志回调委托
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Defines delegate support multicasting to replace the 'Application.LogCallback'<br/>
|
|
|
- /// [ZH] 定义支持多播的委托,用于替换'Application.LogCallback'
|
|
|
- /// </remarks>
|
|
|
- public delegate void LogCallbackDelegate(string condition, string stackTrace, LogType type);
|
|
|
-
|
|
|
- private static event LogCallbackDelegate _LogCallbackEventHandler;
|
|
|
-
|
|
|
- private static bool _isInitialized = false;
|
|
|
-
|
|
|
- private static LogType _autoReportLogLevel = LogType.Error;
|
|
|
-
|
|
|
-#pragma warning disable 414
|
|
|
- private static bool _debugMode = false;
|
|
|
-
|
|
|
- private static bool _autoQuitApplicationAfterReport = false;
|
|
|
-
|
|
|
- private static Func<Dictionary<string, string>> _LogCallbackExtrasHandler;
|
|
|
-
|
|
|
- private static bool _uncaughtAutoReportOnce = false;
|
|
|
-
|
|
|
-
|
|
|
- /************************************全平台接口************************************/
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Initializes CrashSight<br/>
|
|
|
- /// [ZH] 初始化CrashSight
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Initializes as early as possible to enable crash detection and reporting features<br/>
|
|
|
- /// [ZH] 在尽可能早的位置进行初始化以开启崩溃捕获和上报功能
|
|
|
- /// </remarks>
|
|
|
- /// <param name="appId">
|
|
|
- /// [EN] APPID of registered projects<br/>
|
|
|
- /// [ZH] 已注册项目的APPID
|
|
|
- /// </param>
|
|
|
- public static void InitWithAppId(string appId, bool forceOnUiThread = false)
|
|
|
- {
|
|
|
- if (IsInitialized)
|
|
|
- {
|
|
|
- DebugLog(null, "CrashSightAgent has already been initialized.");
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (string.IsNullOrEmpty(appId))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // init the sdk with app id
|
|
|
- UQMCrash.InitWithAppId(appId, forceOnUiThread);
|
|
|
- DebugLog(null, "Initialized with app id: " + appId + " crashUploadUrl: " + crashUploadUrl);
|
|
|
-
|
|
|
- // Register the LogCallbackHandler by Application.RegisterLogCallback(Application.LogCallback)
|
|
|
- _RegisterExceptionHandler();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Actively reports errors<br/>
|
|
|
- /// [ZH] 主动上报错误
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Used to report captured C# exceptions<br/>
|
|
|
- /// [ZH] 用于上报捕获的c#异常
|
|
|
- /// </remarks>
|
|
|
- /// <param name="e">
|
|
|
- /// [EN] Caught exception<br/>
|
|
|
- /// [ZH] 捕获到的异常
|
|
|
- /// </param>
|
|
|
- /// <param name="message">
|
|
|
- /// [EN] Exception message<br/>
|
|
|
- /// [ZH] 异常信息</param>
|
|
|
- public static void ReportException(System.Exception e, string message)
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- DebugLog(null, "Report exception: " + message + "\n------------\n" + e + "\n------------");
|
|
|
-
|
|
|
- _HandleException(e, message, false);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Actively reports errors<br/>
|
|
|
- /// [ZH] 主动上报错误
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Can be called manually when an error is caught or needs to be reported, multi-threaded calls are supported<br/>
|
|
|
- /// [ZH] 可以在捕获到错误或者需要上报的时候手动调用,支持多线程调用
|
|
|
- /// </remarks>
|
|
|
- /// <param name="name">
|
|
|
- /// [EN] Exception Name, cannot be null<br/>
|
|
|
- /// [ZH] 异常名称,不能为null
|
|
|
- /// </param>
|
|
|
- /// <param name="message">
|
|
|
- /// [EN] Exception message, cannot be null<br/>
|
|
|
- /// [ZH] 异常信息,不能为null
|
|
|
- /// </param>
|
|
|
- /// <param name="stackTrace">
|
|
|
- /// [EN] Stack, cannot be null<br/>
|
|
|
- /// [ZH] 堆栈,不能为null
|
|
|
- /// </param>
|
|
|
- public static void ReportException(string name, string message, string stackTrace)
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- DebugLog(null, "Report exception: " + name + " " + message + " \n" + stackTrace);
|
|
|
-
|
|
|
- _HandleException(LogType.Exception, name, message, stackTrace, false, CSReportType.InterfaceReport);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Actively reports errors<br/>
|
|
|
- /// [ZH] 主动上报错误
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Can be called manually when an error is caught or needs to be reported, multi-threaded calls are supported<br/>
|
|
|
- /// [ZH] 可以在捕获到错误或者需要上报的时候手动调用,支持多线程调用<br/>
|
|
|
- /// </remarks>
|
|
|
- /// <param name="type">
|
|
|
- /// [EN] Exception Type, 0~3 are internal reserved types and are invalid if passed in<br/>
|
|
|
- /// [ZH] 异常类型, 0~3为内部保留类型传入无效, C#: 4, js: 5, lua: 6
|
|
|
- /// </param>
|
|
|
- /// <param name="exceptionName">
|
|
|
- /// [EN] Exception Name, cannot be null<br/>
|
|
|
- /// [ZH] 异常名称,不能为null
|
|
|
- /// </param>
|
|
|
- /// <param name="exceptionMsg">
|
|
|
- /// [EN] Exception message, cannot be null<br/>
|
|
|
- /// [ZH] 异常信息,不能为null
|
|
|
- /// </param>
|
|
|
- /// <param name="exceptionStack">
|
|
|
- /// [EN] Stack, cannot be null<br/>
|
|
|
- /// [ZH] 堆栈,不能为null
|
|
|
- /// </param>
|
|
|
- /// <param name="extInfo">
|
|
|
- /// [EN] Other Info<br/>
|
|
|
- /// [ZH] 其他信息
|
|
|
- /// </param>
|
|
|
- /// <param name="dumpNativeType">
|
|
|
- /// [EN] 0: close, 1: call system interface dump, 3: minidump (only valid for mobile)<br/>
|
|
|
- /// [ZH] 0:关闭,1:调用系统接口dump,3:minidump(仅移动端有效)
|
|
|
- /// </param>
|
|
|
- /// <param name="errorAttachmentPath">
|
|
|
- /// [EN] Absolute path of log attachment (only valid for Android)<br/>
|
|
|
- /// [ZH] 日志附件的绝对路径(仅Android有效)
|
|
|
- /// </param>
|
|
|
- public static void ReportException(int type, string exceptionName, string exceptionMsg, string exceptionStack, Dictionary<string, string> extInfo, int dumpNativeType = 0, string errorAttachmentPath = "")
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- UQMCrash.ReportException(type, exceptionName, exceptionMsg, exceptionStack, extInfo, dumpNativeType, errorAttachmentPath);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets user ID<br/>
|
|
|
- /// [ZH] 设置用户ID
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] The user id defaults to unknown<br/>
|
|
|
- /// [ZH] 用户ID默认为unknown
|
|
|
- /// </remarks>
|
|
|
- /// <param name="userId">
|
|
|
- /// [EN] User ID<br/>
|
|
|
- /// [ZH] 用户ID
|
|
|
- /// </param>
|
|
|
- public static void SetUserId(string userId)
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- DebugLog(null, "Set user id: " + userId);
|
|
|
-
|
|
|
- UQMCrash.SetUserId(userId);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Adds custom data<br/>
|
|
|
- /// [ZH] 添加自定义数据
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Set the Key-Value data customized by the user. It will be reported together with exception info when sending the crash<br/>
|
|
|
- /// [ZH] 设置用户自定义的 Key-Value 数据,将在发送 Crash 时随异常信息一起上报<br/>
|
|
|
- /// [EN] View page: Crash Details->Download Attachments->valueMapOthers.txt<br/>
|
|
|
- /// [ZH] 页面查看:崩溃详情页->附件下载->valueMapOthers.txt
|
|
|
- /// </remarks>
|
|
|
- /// <param name="key"></param>
|
|
|
- /// <param name="value"></param>
|
|
|
- public static void AddSceneData(string key, string value)
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- DebugLog(null, "Add scene data: [" + key + ", " + value + "]");
|
|
|
-
|
|
|
- UQMCrash.AddSceneData(key, value);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Adds custom data<br/>
|
|
|
- /// [ZH] 添加自定义数据
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Call <see cref="AddSceneData"/> to set the Key-Value data customized by the user, where the value is int type.
|
|
|
- /// It will be reported together with exception info when sending the crash<br/>
|
|
|
- /// [ZH] 调用 <see cref="AddSceneData"/> 设置用户自定义的 Key-Value 数据,其中 value 为 int 类型,将在发送 Crash 时随异常信息一起上报<br/>
|
|
|
- /// [EN] View page: Crash Details->Download Attachments->valueMapOthers.txt<br/>
|
|
|
- /// [ZH] 页面查看:崩溃详情页->附件下载->valueMapOthers.txt
|
|
|
- /// </remarks>
|
|
|
- /// <param name="key"></param>
|
|
|
- /// <param name="value"></param>
|
|
|
- public static void SetUserValue(string key, int value)
|
|
|
- {
|
|
|
- AddSceneData("I#" + key, "" + value);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Adds custom data<br/>
|
|
|
- /// [ZH] 添加自定义数据
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Call <see cref="AddSceneData"/> to set the Key-Value data customized by the user, where the value is string type.
|
|
|
- /// It will be reported together with exception info when sending the crash<br/>
|
|
|
- /// [ZH] 调用 <see cref="AddSceneData"/> 设置用户自定义的 Key-Value 数据,其中 value 为 string 类型,将在发送 Crash 时随异常信息一起上报<br/>
|
|
|
- /// [EN] View page: Crash Details->Download Attachments->valueMapOthers.txt<br/>
|
|
|
- /// [ZH] 页面查看:崩溃详情页->附件下载->valueMapOthers.txt
|
|
|
- /// </remarks>
|
|
|
- /// <param name="key"></param>
|
|
|
- /// <param name="value"></param>
|
|
|
- public static void SetUserValue(string key, string value)
|
|
|
- {
|
|
|
- AddSceneData("K#" + key, value);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Adds custom data<br/>
|
|
|
- /// [ZH] 添加自定义数据
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Call <see cref="AddSceneData"/> to set the Key-Value data customized by the user, where the value is string[] type.
|
|
|
- /// It will be reported together with exception info when sending the crash<br/>
|
|
|
- /// [ZH] 调用 <see cref="AddSceneData"/> 设置用户自定义的 Key-Value 数据,其中 value 为 string[] 类型,将在发送 Crash 时随异常信息一起上报<br/>
|
|
|
- /// [EN] View page: Crash Details->Download Attachments->valueMapOthers.txt<br/>
|
|
|
- /// [ZH] 页面查看:崩溃详情页->附件下载->valueMapOthers.txt
|
|
|
- /// </remarks>
|
|
|
- /// <param name="key"></param>
|
|
|
- /// <param name="value"></param>
|
|
|
- public static void SetUserValue(string key, string[] value)
|
|
|
- {
|
|
|
- string valueStr = string.Join("#", value);
|
|
|
- AddSceneData("S#" + key, valueStr);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets application version<br/>
|
|
|
- /// [ZH] 设置应用版本号
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Need to be called before <see cref="InitWithAppId"/> interface<br/>
|
|
|
- /// [ZH] 需要在 <see cref="InitWithAppId"/> 接口之前调用
|
|
|
- /// </remarks>
|
|
|
- /// <param name="appVersion">
|
|
|
- /// [EN] Version Number<br/>
|
|
|
- /// [ZH] 版本号
|
|
|
- /// </param>
|
|
|
- public static void SetAppVersion(string appVersion)
|
|
|
- {
|
|
|
- DebugLog(null, "Set app version: " + appVersion);
|
|
|
-
|
|
|
- UQMCrash.SetAppVersion(appVersion);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets the reporting domain name<br/>
|
|
|
- /// [ZH] 设置上报域名
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Need to be called before <see cref="InitWithAppId"/> interface<br/>
|
|
|
- /// [ZH] 需要在 <see cref="InitWithAppId"/> 接口之前调用
|
|
|
- /// </remarks>
|
|
|
- /// <param name="crashServerUrl">
|
|
|
- /// [EN] Target domain name of reporting<br/>
|
|
|
- /// [ZH] 要上报的域名
|
|
|
- /// </param>
|
|
|
- public static void ConfigCrashServerUrl(string crashServerUrl)
|
|
|
- {
|
|
|
- DebugLog(null, "Config crashServerUrl:" + crashServerUrl);
|
|
|
- UQMCrash.ConfigCrashServerUrl(crashServerUrl);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets upload path for log after crash<br/>
|
|
|
- /// [ZH] 设置崩溃后上传的日志路径
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Read permission is required. On Android and iOS, this interface has a lower priority than <see cref="RegisterCrashLogCallback"/>.
|
|
|
- /// It is not available on Switch.<br/>
|
|
|
- /// [ZH] 需要可读权限,在Android和iOS端上,该接口的优先级低于 <see cref="RegisterCrashLogCallback"/> , Switch暂不可用<br/>
|
|
|
- /// </remarks>
|
|
|
- /// <param name="logPath">
|
|
|
- /// [EN] Absolute path for log files<br/>
|
|
|
- /// [ZH] 日志绝对路径
|
|
|
- /// </param>
|
|
|
- public static void SetLogPath(string logPath)
|
|
|
- {
|
|
|
- UQMCrash.SetLogPath(logPath);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets debug mode<br/>
|
|
|
- /// [ZH] 设置debug模式
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Disabled by default. Need to be called before <see cref="InitWithAppId"/> interface.
|
|
|
- /// When enabled, more logs will be printed to facilitate problem location.<br/>
|
|
|
- /// [ZH] 默认关闭, 需要在 <see cref="InitWithAppId"/> 接口之前调用,开启后会打印更多便于问题定位的Log
|
|
|
- /// </remarks>
|
|
|
- /// <param name="enable"></param>
|
|
|
- public static void ConfigDebugMode(bool enable)
|
|
|
- {
|
|
|
- _debugMode = enable;
|
|
|
- UQMCrash.ConfigDebugMode(enable);
|
|
|
- DebugLog(null, (enable ? "Enable" : "Disable") + " the log message print to console");
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets device id<br/>
|
|
|
- /// [ZH] 设置设备Id
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] By default, uuid is used as the device ID. Need to be called before <see cref="InitWithAppId"/> interface.<br/>
|
|
|
- /// [ZH] 默认采用uuid作为设备ID, 需要在 <see cref="InitWithAppId"/> 接口之前调用
|
|
|
- /// </remarks>
|
|
|
- /// <param name="deviceId">
|
|
|
- /// [EN] Device ID<br/>
|
|
|
- /// [ZH] 设备唯一标识
|
|
|
- /// </param>
|
|
|
- public static void SetDeviceId(string deviceId)
|
|
|
- {
|
|
|
- UQMCrash.SetDeviceId(deviceId);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets custom log reporting level<br/>
|
|
|
- /// [ZH] 设置自定义日志上报级别
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Need to be called before <see cref="InitWithAppId"/> interface.<br/>
|
|
|
- /// [ZH] 需要在 <see cref="InitWithAppId"/> 接口之前调用
|
|
|
- /// </remarks>
|
|
|
- /// <param name="logLevel">
|
|
|
- /// [EN] Off=0, Error=1, Warn=2, Info=3, Debug=4, default is Info<br/>
|
|
|
- /// [ZH] Off=0, Error=1, Warn=2, Info=3, Debug=4, 默认Info
|
|
|
- /// </param>
|
|
|
- public static void ConfigCrashReporter(int logLevel)
|
|
|
- {
|
|
|
- UQMCrash.ConfigAutoReportLogLevel(logLevel);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets custom log reporting level<br/>
|
|
|
- /// [ZH] 设置自定义日志上报级别
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Need to be called before <see cref="InitWithAppId"/> interface.<br/>
|
|
|
- /// [ZH] 需要在 <see cref="InitWithAppId"/> 接口之前调用
|
|
|
- /// </remarks>
|
|
|
- /// <param name="logLevel">
|
|
|
- /// [EN] Off=0, Error=1, Warn=2, Info=3, Debug=4, default is Info, <see cref="CSLogSeverity"/><br/>
|
|
|
- /// [ZH] Off=0, Error=1, Warn=2, Info=3, Debug=4, 默认Info, <see cref="CSLogSeverity"/>
|
|
|
- /// </param>
|
|
|
- public static void ConfigCrashReporter(CSLogSeverity logLevel)
|
|
|
- {
|
|
|
- UQMCrash.ConfigAutoReportLogLevel((int)logLevel);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Adds custom logs<br/>
|
|
|
- /// [ZH] 添加自定义日志
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] The custom log shouldn't exceed 30KB. Custom log view: <br/>
|
|
|
- /// Android, iOS, PS4, PS5, Switch: issue details->tracking log->custom log <br/>
|
|
|
- /// Windows, Xbox, Linux: issue details -> custom log (from interface)<br/>
|
|
|
- /// [ZH] 自定义日志,限制30KB。 自定义日志查看:<br/>
|
|
|
- /// Android、iOS、PS4、PS5、Switch:问题详情->跟踪日志->custom log <br/>
|
|
|
- /// Windows、Xbox、Linux:问题详情->自定义日志(来自接口)
|
|
|
- /// </remarks>
|
|
|
- /// <param name="level">
|
|
|
- /// [EN] Log level, <see cref="CSLogSeverity"/><br/>
|
|
|
- /// [ZH] 日志级别 <see cref="CSLogSeverity"/>
|
|
|
- /// </param>
|
|
|
- /// <param name="format">
|
|
|
- /// [EN] Log format<br/>
|
|
|
- /// [ZH] 日志格式
|
|
|
- /// </param>
|
|
|
- /// <param name="args">
|
|
|
- /// [EN] Variable parameter array<br/>
|
|
|
- /// [ZH] 可变参数数组
|
|
|
- /// </param>
|
|
|
- public static void PrintLog(CSLogSeverity level, string format, params object[] args)
|
|
|
- {
|
|
|
- if (string.IsNullOrEmpty(format))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (args == null || args.Length == 0)
|
|
|
- {
|
|
|
- UQMCrash.LogRecord((int)level, format);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- UQMCrash.LogRecord((int)level, string.Format(format, args));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Tests native crash<br/>
|
|
|
- /// [ZH] 测试 native 崩溃
|
|
|
- /// </summary>
|
|
|
- public static void TestNativeCrash()
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- DebugLog(null, "test native crash");
|
|
|
-
|
|
|
- UQMCrash.TestNativeCrash();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets the distribution channel<br/>
|
|
|
- /// [ZH] 设置发行渠道
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Each network connection or report can carry this field to collect statistics for different distribution channels.
|
|
|
- /// It is not available on PS4、PS5、Switch and Linux.<br/>
|
|
|
- /// [ZH] 每一个联网或者上报都可以携带该字段,可实现针对不同的发行渠道统计数据。 PS4、PS5、Switch、Linux暂不可用
|
|
|
- /// </remarks>
|
|
|
- /// <param name="serverEnv"></param>
|
|
|
- public static void SetEnvironmentName(string serverEnv)
|
|
|
- {
|
|
|
- UQMCrash.SetServerEnv(serverEnv);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Enables Unity ANR monitoring<br/>
|
|
|
- /// [ZH] 启用 Unity ANR 监控
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Here ANR means that the Unity main thread is unresponsive, which is different from Android ANR<br/>
|
|
|
- /// [ZH] 此处ANR是指Unity主线程无响应,区别于Android ANR
|
|
|
- /// </remarks>
|
|
|
- /// <param name="timeoutMs">
|
|
|
- /// [EN] Timeout in milliseconds to trigger ANR report when main thread is unresponsive<br/>
|
|
|
- /// [ZH] 主线程无响应多少毫秒触发上报
|
|
|
- /// </param>
|
|
|
- public static void EnableAnrMonitor(int timeoutMs = 5000)
|
|
|
- {
|
|
|
- CrashSightAnrMonitor.Start(timeoutMs);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Disables Unity ANR monitoring<br/>
|
|
|
- /// [ZH] 停用 Unity ANR 监控
|
|
|
- /// </summary>
|
|
|
- public static void DisableAnrMonitor()
|
|
|
- {
|
|
|
- CrashSightAnrMonitor.Stop();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Registers crash callback<br/>
|
|
|
- /// [ZH] 注册崩溃回调
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Callback is called when a crash occurs and the return value will be included in the crash report.<br/>
|
|
|
- /// Create a custom class inheriting from CrashSightCallback and implement OnCrashBaseRetEvent method.<br/>
|
|
|
- /// Not available on PS4, PS5, Switch, Linux and HarmonyOS.<br/>
|
|
|
- /// [ZH] 回调在崩溃时调用,返回值随崩溃信息一起上报<br/>
|
|
|
- /// 自定义CsCrashCallBack类,继承 CrashSightCallback,实现 OnCrashBaseRetEvent方法<br/>
|
|
|
- /// PS4、PS5、Switch、Linux、鸿蒙暂不可用<br/>
|
|
|
- /// </remarks>
|
|
|
- /// <example>
|
|
|
- /// <code>
|
|
|
- /// public class CsCrashCallBack: CrashSightCallback {
|
|
|
- /// //Put you own code to implemente the callback func
|
|
|
- /// public override string OnCrashBaseRetEvent(int methodId)
|
|
|
- /// {
|
|
|
- /// if (methodId == (int)UQMMethodNameID.UQM_CRASH_CALLBACK_EXTRA_MESSAGE)
|
|
|
- /// {
|
|
|
- /// // For Android/iOS: return extra message
|
|
|
- /// return "this is extra message.";
|
|
|
- /// }
|
|
|
- /// else if (methodId == (int)UQMMethodNameID.UQM_CRASH_CALLBACK_NO_RET)
|
|
|
- /// {
|
|
|
- /// // For Win/Xbox: return value is ignored but you can perform operations here
|
|
|
- /// }
|
|
|
- /// return "";
|
|
|
- /// }
|
|
|
- /// }
|
|
|
- /// </code>
|
|
|
- /// </example>
|
|
|
- /// <param name="callback">
|
|
|
- /// [EN] Callback instance that inherits from CrashSightCallback<br/>
|
|
|
- /// [ZH] 继承自 CrashSightCallback 的回调实例
|
|
|
- /// </param>
|
|
|
- public static void RegisterCrashCallback(CrashSightCallback callback)
|
|
|
- {
|
|
|
- if (callback != null)
|
|
|
- {
|
|
|
- UQMCrash.CrashBaseRetEvent += callback.OnCrashBaseRetEvent;
|
|
|
- UQMCrash.ConfigCallBack();
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DebugLog(null, "RegisterCallback failed: callback is null.");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Unregisters the crash callback<br/>
|
|
|
- /// [ZH] 注销崩溃回调
|
|
|
- /// </summary>
|
|
|
- public static void UnregisterCrashCallback()
|
|
|
- {
|
|
|
- UQMCrash.UnregisterCallBack();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Registers crash log upload callback<br/>
|
|
|
- /// [ZH] 注册上传日志回调
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Called after handling a crash.<br/>
|
|
|
- /// Customize the CsCrashLogCallback class, inherit CrashSightLogCallback, and use OnSetLogPathEvent and OnLogUploadResultEvent methods.<br/>
|
|
|
- /// [ZH] 崩溃处理后调用,自定义CsCrashLogCallback类,继承CrashSightLogCallback,实现OnSetLogPathEvent、OnLogUploadResultEvent方法
|
|
|
- /// </remarks>
|
|
|
- /// <example>
|
|
|
- /// <code>
|
|
|
- /// public class CsCrashLogCallBack : CrashSightLogCallback
|
|
|
- /// {
|
|
|
- /// // Returns absolute path of log file to upload
|
|
|
- /// // methodId: Method ID (can be ignored)
|
|
|
- /// // crashType: Crash type (0: Java/OC crash, 2: Native crash)
|
|
|
- /// public override string OnSetLogPathEvent(int methodId, int crashType)
|
|
|
- /// {
|
|
|
- /// return "";
|
|
|
- /// }
|
|
|
- ///
|
|
|
- /// // Notifies log upload result
|
|
|
- /// // methodId: Method ID (can be ignored)
|
|
|
- /// // crashType: Crash type (0: Java/OC crash, 2: Native crash)
|
|
|
- /// // result: Upload result (0: success, others: failure)
|
|
|
- /// public override void OnLogUploadResultEvent(int methodId, int crashType, int result)
|
|
|
- /// {
|
|
|
- ///
|
|
|
- /// }
|
|
|
- /// }
|
|
|
- /// </code>
|
|
|
- /// </example>
|
|
|
- /// <param name="callback">
|
|
|
- /// [EN] Callback instance that inherits from CrashSightLogCallback<br/>
|
|
|
- /// [ZH] 继承自CrashSightLogCallback的回调实例
|
|
|
- /// </param>
|
|
|
- public static void RegisterCrashLogCallback(CrashSightLogCallback callback)
|
|
|
- {
|
|
|
- if (callback != null)
|
|
|
- {
|
|
|
- UQMCrash.CrashSetLogPathRetEvent += callback.OnSetLogPathEvent;
|
|
|
- UQMCrash.CrashLogUploadRetEvent += callback.OnLogUploadResultEvent;
|
|
|
- UQMCrash.ConfigLogCallBack();
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- DebugLog(null, "RegisterCallback failed: callback is null.");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Report Unity Log Error<br/>
|
|
|
- /// [ZH] 上报Unity Log Error
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Enables automatic reporting of Unity log errors to CrashSight.<br/>
|
|
|
- /// The triggering frequency of Unity Log Error in the project should be kept low after enabling the feature.<br/>
|
|
|
- /// [ZH] 调用该接口可以将Unity Log Error作为错误上报到CrashSight<br/>
|
|
|
- /// 开启该功能后请尽量控制项目中Unity Log Error的触发频率
|
|
|
- /// </remarks>
|
|
|
- public static void EnableExceptionHandler()
|
|
|
- {
|
|
|
- if (IsInitialized)
|
|
|
- {
|
|
|
- DebugLog(null, "CrashSightAgent has already been initialized.");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- DebugLog(null, "Only enable the exception handler, please make sure you has initialized the sdk in the native code in associated Android or iOS project.");
|
|
|
-
|
|
|
- // Register the LogCallbackHandler by Application.RegisterLogCallback(Application.LogCallback)
|
|
|
- _RegisterExceptionHandler();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Registers log callback<br/>
|
|
|
- /// [ZH] 注册日志回调
|
|
|
- /// </summary>
|
|
|
- /// <param name="handler">
|
|
|
- /// [EN] Log callback delegate<br/>
|
|
|
- /// [ZH] 日志回调委托
|
|
|
- /// </param>
|
|
|
- public static void RegisterLogCallback(LogCallbackDelegate handler)
|
|
|
- {
|
|
|
- if (handler != null)
|
|
|
- {
|
|
|
- DebugLog(null, "Add log callback handler: " + handler);
|
|
|
-
|
|
|
- _LogCallbackEventHandler += handler;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Unregisters log callback<br/>
|
|
|
- /// [ZH] 注销日志回调
|
|
|
- /// </summary>
|
|
|
- /// <param name="handler">
|
|
|
- /// [EN] Log callback delegate to unregister<br/>
|
|
|
- /// [ZH] 要注销的日志回调委托
|
|
|
- /// </param>
|
|
|
- public static void UnregisterLogCallback(LogCallbackDelegate handler)
|
|
|
- {
|
|
|
- if (handler != null)
|
|
|
- {
|
|
|
- DebugLog(null, "Remove log callback handler");
|
|
|
-
|
|
|
- _LogCallbackEventHandler -= handler;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets the extra data handler for log callbacks<br/>
|
|
|
- /// [ZH] 设置日志回调的额外数据处理函数
|
|
|
- /// </summary>
|
|
|
- /// <param name="handler">
|
|
|
- /// [EN] Function that returns extra data dictionary<br/>
|
|
|
- /// [ZH] 返回额外数据的函数
|
|
|
- /// </param>
|
|
|
- public static void SetLogCallbackExtrasHandler(Func<Dictionary<string, string>> handler)
|
|
|
- {
|
|
|
- if (handler != null)
|
|
|
- {
|
|
|
- _LogCallbackExtrasHandler = handler;
|
|
|
-
|
|
|
- DebugLog(null, "Add log callback extra data handler : " + handler);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Configures whether to automatically quit the application after crash reporting<br/>
|
|
|
- /// [ZH] 配置崩溃上报后是否自动退出应用
|
|
|
- /// </summary>
|
|
|
- /// <param name="autoQuit">
|
|
|
- /// [EN] Whether to auto quit<br/>
|
|
|
- /// [ZH] 是否自动退出
|
|
|
- /// </param>
|
|
|
- public static void ConfigAutoQuitApplication(bool autoQuit)
|
|
|
- {
|
|
|
- _autoQuitApplicationAfterReport = autoQuit;
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Gets whether the application will auto quit after crash reporting<br/>
|
|
|
- /// [ZH] 获取崩溃上报后是否自动退出应用的配置
|
|
|
- /// </summary>
|
|
|
- /// <returns>
|
|
|
- /// [EN] Current auto quit configuration<br/>
|
|
|
- /// [ZH] 当前自动退出配置
|
|
|
- /// </returns>
|
|
|
- public static bool AutoQuitApplicationAfterReport
|
|
|
- {
|
|
|
- get { return _autoQuitApplicationAfterReport; }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Outputs debug log messages<br/>
|
|
|
- /// [ZH] 调试日志输出
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Only works when debugMode is enabled.<br/>
|
|
|
- /// [ZH] 仅当debugMode为true时有效
|
|
|
- /// </remarks>
|
|
|
- /// <param name="tag">
|
|
|
- /// [EN] Log tag
|
|
|
- /// [ZH] 日志标签</param>
|
|
|
- /// <param name="format">
|
|
|
- /// [EN] Format string with placeholders<br/>
|
|
|
- /// [ZH] 带占位符的格式化字符串
|
|
|
- /// </param>
|
|
|
- public static void DebugLog(string tag, string format)
|
|
|
- {
|
|
|
- if (!_debugMode)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (string.IsNullOrEmpty(format))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- UQMLog.Log(string.Format("{0}:{1}", tag, format));
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Checks if CrashSight has been initialized<br/>
|
|
|
- /// [ZH] 获取CrashSight是否已初始化
|
|
|
- /// </summary>
|
|
|
- /// <returns>
|
|
|
- /// [EN] Initialization status<br/>
|
|
|
- /// [ZH] 初始化状态
|
|
|
- /// </returns>
|
|
|
- public static bool IsInitialized
|
|
|
- {
|
|
|
- get { return _isInitialized; }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Registers exception handler callbacks<br/>
|
|
|
- /// [ZH] 注册异常处理回调
|
|
|
- /// </summary>
|
|
|
- public static void _RegisterExceptionHandler()
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- // hold only one instance
|
|
|
-
|
|
|
-#if UNITY_5 || UNITY_5_3_OR_NEWER
|
|
|
- Application.logMessageReceived += _OnLogCallbackHandlerMain;
|
|
|
- Application.logMessageReceivedThreaded += _OnLogCallbackHandlerThreaded;
|
|
|
-#else
|
|
|
- Application.RegisterLogCallback(_OnLogCallbackHandlerMain);
|
|
|
- Application.RegisterLogCallbackThreaded(_OnLogCallbackHandlerThreaded);
|
|
|
-#endif
|
|
|
- AppDomain.CurrentDomain.UnhandledException += _OnUncaughtExceptionHandler;
|
|
|
-
|
|
|
- string version = Application.unityVersion;
|
|
|
-#if UNITY_EDITOR
|
|
|
- string buildConfig = "editor";
|
|
|
-#elif DEVELOPMENT_BUILD
|
|
|
- string buildConfig = "development";
|
|
|
-#else
|
|
|
- string buildConfig = "release";
|
|
|
-#endif
|
|
|
- SystemLanguage language = Application.systemLanguage;
|
|
|
- CultureInfo locale = CultureInfo.CurrentCulture;
|
|
|
- UQMCrash.SetEngineInfo(version, buildConfig, language.ToString(), locale.ToString());
|
|
|
-
|
|
|
- _isInitialized = true;
|
|
|
-
|
|
|
- DebugLog(null, "Register the log callback in Unity " + Application.unityVersion);
|
|
|
- }
|
|
|
- catch
|
|
|
- {
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Unregisters exception handler callbacks<br/>
|
|
|
- /// [ZH] 注销异常处理回调
|
|
|
- /// </summary>
|
|
|
- public static void _UnregisterExceptionHandler()
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
-#if UNITY_5 || UNITY_5_3_OR_NEWER
|
|
|
- Application.logMessageReceived -= _OnLogCallbackHandlerMain;
|
|
|
- Application.logMessageReceivedThreaded -= _OnLogCallbackHandlerThreaded;
|
|
|
-#else
|
|
|
- Application.RegisterLogCallback(null);
|
|
|
- Application.RegisterLogCallbackThreaded(null);
|
|
|
-#endif
|
|
|
- System.AppDomain.CurrentDomain.UnhandledException -= _OnUncaughtExceptionHandler;
|
|
|
- DebugLog(null, "Unregister the log callback in unity " + Application.unityVersion);
|
|
|
- }
|
|
|
- catch
|
|
|
- {
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Enables/disables CrashSight stack trace collection<br/>
|
|
|
- /// [ZH] 设置是否启用CrashSight堆栈跟踪
|
|
|
- /// </summary>
|
|
|
- /// <param name="enable"></param>
|
|
|
- public static void SetCrashSightStackTraceEnable(bool enable)
|
|
|
- {
|
|
|
- CrashSightStackTrace.setEnable(enable);
|
|
|
- }
|
|
|
-
|
|
|
- /************************************Android、iOS、Mac端接口************************************/
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Configures callback types for reports (Android, iOS, Mac)<br/>
|
|
|
- /// [ZH] 设置各类上报的回调开关(Android、iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- /// <param name="callbackType">
|
|
|
- /// [EN] There are currently 5 types of callback represented by 5 digits. The first digit represents crash, the second digit represents anr,
|
|
|
- /// the third digit represents u3d c# error, the fourth digit represents js, and the fifth digit represents lua<br/>
|
|
|
- /// [ZH] 目前是5种类型,用5位表示。第一位表示crash,第二位表示anr,第三位表示u3d c# error第四位表示js,第五位表示lua。默认全开
|
|
|
- /// </param>
|
|
|
- public static void ConfigCallbackType(Int32 callbackType)
|
|
|
- {
|
|
|
- UQMCrash.ConfigCallbackType(callbackType);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets device model (Android, iOS, Mac)<br/>
|
|
|
- /// [ZH] 设置设备型号(Android、iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Need to be called before <see cref="InitWithAppId"/> interface.<br/>
|
|
|
- /// [ZH] 需要在 <see cref="InitWithAppId"/> 接口之前调用
|
|
|
- /// </remarks>
|
|
|
- /// <param name="deviceModel">
|
|
|
- /// [EN] Device model name<br/>
|
|
|
- /// [ZH] 手机型号
|
|
|
- /// </param>
|
|
|
- public static void SetDeviceModel(string deviceModel)
|
|
|
- {
|
|
|
- UQMCrash.SetDeviceModel(deviceModel);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Reports lightweight log (Android, iOS, Mac)<br/>
|
|
|
- /// [ZH] 上报轻量级日志(Android、iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- /// <param name="msgType">
|
|
|
- /// [EN] Message type<br/>
|
|
|
- /// [ZH] 消息类型
|
|
|
- /// </param>
|
|
|
- /// <param name="msg">
|
|
|
- /// [EN] Message content<br/>
|
|
|
- /// [ZH] 消息内容
|
|
|
- /// </param>
|
|
|
- public static void ReportLogInfo(string msgType, string msg)
|
|
|
- {
|
|
|
- UQMCrash.ReportLogInfo(msgType, msg);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets the scene field name(Android、iOS、Mac)<br/>
|
|
|
- /// [ZH] 设置场景字段(Android、iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Each network connection or report can carry this field to calculate crash rates and other data for different scenes.
|
|
|
- /// It is not available on PS4、PS5、Switch and Linux.<br/>
|
|
|
- /// [ZH] 每一个联网或者上报都可以携带该字段,实现针对不同的子场景计算崩溃率等数据。 PS4、PS5、Switch、Linux暂不可用
|
|
|
- /// </remarks>
|
|
|
- /// <param name="sceneId"></param>
|
|
|
- /// <param name="upload">
|
|
|
- /// [EN] Whether to report the change of scene<br/>
|
|
|
- /// [ZH] 是否上报场景变更
|
|
|
- /// </param>
|
|
|
- public static void SetScene(string sceneId, bool upload = false)
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- DebugLog(null, "Set scene: " + sceneId + ", upload:" + upload);
|
|
|
-
|
|
|
- UQMCrash.SetScene(sceneId, upload);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets the scene field name(Android、iOS、Mac)<br/>
|
|
|
- /// [ZH] 设置场景字段(Android、iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Each network connection or report can carry this field to calculate crash rates and other data for different scenes.
|
|
|
- /// It is not available on PS4、PS5、Switch and Linux.<br/>
|
|
|
- /// [ZH] 每一个联网或者上报都可以携带该字段,实现针对不同的子场景计算崩溃率等数据。 PS4、PS5、Switch、Linux暂不可用
|
|
|
- /// </remarks>
|
|
|
- /// <param name="sceneId"></param>
|
|
|
- /// <param name="upload">
|
|
|
- /// [EN] Whether to report the change of scene<br/>
|
|
|
- /// [ZH] 是否上报场景变更
|
|
|
- /// </param>
|
|
|
- public static void SetScene(int sceneId, bool upload = false)
|
|
|
- {
|
|
|
- SetScene(sceneId.ToString(), upload);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Gets crash thread ID (Android, iOS, Mac)<br/>
|
|
|
- /// [ZH] 获取崩溃线程ID(Android、iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Can be called in callback<br/>
|
|
|
- /// [ZH] 可在回调中调用
|
|
|
- /// </remarks>
|
|
|
- /// <returns>
|
|
|
- /// [EN] Crash thread ID, returns -1 on failure<br/>
|
|
|
- /// [ZH] 崩溃线程ID,失败时返回-1
|
|
|
- /// </returns>
|
|
|
- public static long GetCrashThreadId()
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return -1;
|
|
|
- }
|
|
|
- DebugLog(null, "GetCrashThreadId");
|
|
|
-
|
|
|
- return UQMCrash.GetCrashThreadId();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets customized device ID (Android, iOS, Mac)<br/>
|
|
|
- /// 设置自定义device ID(Android、iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- /// <param name="deviceId">
|
|
|
- /// [EN] Custom device id<br/>
|
|
|
- /// [ZH] 自定义device ID
|
|
|
- /// </param>
|
|
|
- public static void SetCustomizedDeviceID(string deviceId)
|
|
|
- {
|
|
|
- UQMCrash.SetCustomizedDeviceID(deviceId);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Gets SDK generated device ID (Android, iOS, Mac)<br/>
|
|
|
- /// [ZH] 获取SDK生成的device ID(Android、iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- /// <returns>
|
|
|
- /// [EN] SDK generated device ID<br/>
|
|
|
- /// [ZH] SDK生成的device ID
|
|
|
- /// </returns>
|
|
|
- public static string GetSDKDefinedDeviceID()
|
|
|
- {
|
|
|
- return UQMCrash.GetSDKDefinedDeviceID();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets customized match ID (Android, iOS, Mac)<br/>
|
|
|
- /// [ZH] 设置自定义 match ID(Android、iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Match ID can be used to search crashes and errors in "Advanced Search"<br/>
|
|
|
- /// [ZH] match id可用于在"高级搜索"中查找崩溃和错误
|
|
|
- /// </remarks>
|
|
|
- /// <param name="matchId">match ID</param>
|
|
|
- public static void SetCustomizedMatchID(string matchId)
|
|
|
- {
|
|
|
- UQMCrash.SetCustomizedMatchID(matchId);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Gets SDK generated session ID (Android, iOS, Mac)<br/>
|
|
|
- /// [ZH] 获取SDK生成的session ID(Android、iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Session ID uniquely marks a launch session, typically used in callbacks to determine if it's the same launch.<br/>
|
|
|
- /// [ZH] session ID用于唯一标记一次启动,一般用于在回调中确定是否为同一次启动。
|
|
|
- /// </remarks>
|
|
|
- /// <returns>
|
|
|
- /// [EN] SDK generated session ID<br/>
|
|
|
- /// [ZH] SDK生成的session ID
|
|
|
- /// </returns>
|
|
|
- public static string GetSDKSessionID()
|
|
|
- {
|
|
|
- return UQMCrash.GetSDKSessionID();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Triggers test OOM crash (Android, iOS, Mac)<br/>
|
|
|
- /// [ZH] 测试OOM崩溃(Android、iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- public static void TestOomCrash()
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- DebugLog(null, "test oom crash");
|
|
|
-
|
|
|
- UQMCrash.TestOomCrash();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Triggers test Java crash (Android)<br/>
|
|
|
- /// [ZH] 测试java崩溃(Android)
|
|
|
- /// </summary>
|
|
|
- public static void TestJavaCrash()
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- DebugLog(null, "test java crash");
|
|
|
-
|
|
|
- UQMCrash.TestJavaCrash();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Triggers test ANR (Android only)<br/>
|
|
|
- /// [ZH] 测试ANR(仅Android)
|
|
|
- /// </summary>
|
|
|
- public static void TestANR()
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- DebugLog(null, "test ANR");
|
|
|
-
|
|
|
- UQMCrash.TestANR();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Gets crash UUID<br/>
|
|
|
- /// [ZH] 获取崩溃UUID
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] This UUID is used to uniquely identify a report and is generally used in callbacks.<br/>
|
|
|
- /// [ZH] 该UUID用于唯一标识一次上报,一般在回调中使用
|
|
|
- /// </remarks>
|
|
|
- /// <returns></returns>
|
|
|
- public static string GetCrashUuid()
|
|
|
- {
|
|
|
- return UQMCrash.GetCrashUuid();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets the logcat buffer size(Android)<br/>
|
|
|
- /// [ZH] 设置logcat缓存大小(Android)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Default is 10KB in non-debug mode, 128KB in debug mode<br/>
|
|
|
- /// [ZH] 默认非debug模式下10KB,debug模式下128KB
|
|
|
- /// </remarks>
|
|
|
- /// <param name="size">
|
|
|
- /// [EN] Buffer size in KB<br/>
|
|
|
- /// [ZH] logcat缓存大小(单位:KB)
|
|
|
- /// </param>
|
|
|
- public static void SetLogcatBufferSize(int size)
|
|
|
- {
|
|
|
- UQMCrash.SetLogcatBufferSize(size);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Tests Objective-C crash (iOS, Mac)<br/>
|
|
|
- /// [ZH] 测试Objective-C崩溃(iOS、Mac)
|
|
|
- /// </summary>
|
|
|
- public static void TestOcCrash()
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- DebugLog(null, "test oc crash");
|
|
|
-
|
|
|
- UQMCrash.TestOcCrash();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Starts scheduled dump routine<br/>
|
|
|
- /// [ZH] 启动定时dump任务
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Starts a thread to periodically capture and report dumps.
|
|
|
- /// Performance overhead depends on dump interval and count settings.
|
|
|
- /// Mainly for testing purposes. Disable before release.<br/>
|
|
|
- /// [ZH] 启动一个线程定时获取dump并上报。根据dump间隔和次数会产生性能开销。一般用于测试,正式发布前请关闭。
|
|
|
- /// </remarks>
|
|
|
- /// <param name="dumpMode">
|
|
|
- /// [EN] 0: close, 1: call system interface dump, 3: minidump (only valid for mobile)<br/>
|
|
|
- /// [ZH] 0:关闭,1:调用系统接口dump,3:minidump(仅移动端有效)
|
|
|
- /// </param>
|
|
|
- /// <param name="startTimeMode">
|
|
|
- /// [EN] Start time mode: 0=absolute time, 1=relative time (ms)<br/>
|
|
|
- /// [ZH] 启动时间模式:0=绝对时间,1=相对时间(毫秒)
|
|
|
- /// </param>
|
|
|
- /// <param name="startTime">
|
|
|
- /// [EN] Start time<br/>
|
|
|
- /// [ZH] 启动时间
|
|
|
- /// </param>
|
|
|
- /// <param name="dumpInterval">
|
|
|
- /// [EN] Dump interval in milliseconds<br/>
|
|
|
- /// [ZH] dump间隔(毫秒)
|
|
|
- /// </param>
|
|
|
- /// <param name="dumpTimes">
|
|
|
- /// [EN] Number of dumps to perform<br/>
|
|
|
- /// [ZH] dump执行次数
|
|
|
- /// </param>
|
|
|
- /// <param name="saveLocal">
|
|
|
- /// [EN] Whether to save dump locally<br/>
|
|
|
- /// [ZH] 是否本地保存dump
|
|
|
- /// </param>
|
|
|
- /// <param name="savePath">
|
|
|
- /// [EN] Local save path for dumps<br/>
|
|
|
- /// [ZH] dump本地保存路径
|
|
|
- /// </param>
|
|
|
- public static void StartDumpRoutine(int dumpMode, int startTimeMode, long startTime,
|
|
|
- long dumpInterval, int dumpTimes, bool saveLocal, string savePath)
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- UQMCrash.StartDumpRoutine(dumpMode, startTimeMode, startTime, dumpInterval, dumpTimes, saveLocal, savePath);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Starts monitoring file descriptor count<br/>
|
|
|
- /// [ZH] 监控FD数量
|
|
|
- /// </summary>
|
|
|
- /// <param name="interval">
|
|
|
- /// [EN] Scan interval in milliseconds<br/>
|
|
|
- /// [ZH] 扫描间隔,单位:毫秒
|
|
|
- /// </param>
|
|
|
- /// <param name="limit">FD数量限制<br/>
|
|
|
- /// [EN] Maximum allowed FD count
|
|
|
- /// [ZH] FD数量限制
|
|
|
- /// </param>
|
|
|
- /// <param name="dumpType">
|
|
|
- /// [EN] 0: close, 1: call system interface dump, 3: minidump (only valid for mobile)<br/>
|
|
|
- /// [ZH] 0:关闭,1:调用系统接口dump,3:minidump(仅移动端有效)
|
|
|
- /// </param>
|
|
|
- public static void StartMonitorFdCount(int interval, int limit, int dumpType)
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- UQMCrash.StartMonitorFdCount(interval, limit, dumpType);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Gets exception type code<br/>
|
|
|
- /// [ZH] 获取异常类型编号
|
|
|
- /// </summary>
|
|
|
- /// <param name="name">
|
|
|
- /// [EN] Exception type name (e.g. "c#", "js", "lua", "custom1")<br/>
|
|
|
- /// [ZH] 异常类型名(如"c#","js","lua","custom1"等)
|
|
|
- /// </param>
|
|
|
- /// <returns>
|
|
|
- /// [EN] Exception type code for ReportException<br/>
|
|
|
- /// [ZH] 用于ReportException接口的异常类型编号
|
|
|
- /// </returns>
|
|
|
- public static int getExceptionType(string name)
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- return UQMCrash.getExceptionType(name);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Tests use-after-free memory error (Android)<br/>
|
|
|
- /// [ZH] 测试释放后使用内存错误(Android)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Only works when GWP-Asan or MTE is enabled<br/>
|
|
|
- /// [ZH] 仅当GWP-Asan或MTE功能启用时有效
|
|
|
- /// </remarks>
|
|
|
- public static void TestUseAfterFree()
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- DebugLog(null, "test UseAfterFree");
|
|
|
-
|
|
|
- UQMCrash.TestUseAfterFree();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Restarts CrashSight monitoring (Android, iOS)<br/>
|
|
|
- /// [ZH] 重启CrashSight监控(Android, iOS)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Used in native Android integration scenarios<br/>
|
|
|
- /// [ZH] 用于Android原生接入场景
|
|
|
- /// </remarks>
|
|
|
- public static void ReRegistAllMonitors()
|
|
|
- {
|
|
|
- _isInitialized = true;
|
|
|
- UQMCrash.ReRegistAllMonitors();
|
|
|
- DebugLog(null, "ReRegistAllMonitors");
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Stops CrashSight monitoring (Android, iOS, Mac)<br/>
|
|
|
- /// [ZH] 关闭CrashSight监控(Android, iOS, Mac)
|
|
|
- /// </summary>
|
|
|
- public static void CloseAllMonitors()
|
|
|
- {
|
|
|
- UQMCrash.CloseAllMonitors();
|
|
|
- DebugLog(null, "CloseAllMonitors");
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Toggles getPackageInfo system API (Android)<br/>
|
|
|
- /// [ZH] 设置getPackageInfo系统接口调用开关(Android)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Enabled by default, can be disabled if rejected by Google Play<br/>
|
|
|
- /// [ZH] 默认开启,谷歌审核不通过时可关闭
|
|
|
- /// </remarks>
|
|
|
- /// <param name="enable"></param>
|
|
|
- public static void setEnableGetPackageInfo(bool enable)
|
|
|
- {
|
|
|
- DebugLog(null, "setEnableGetPackageInfo: " + enable);
|
|
|
-
|
|
|
- UQMCrash.setEnableGetPackageInfo(enable);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets multi-thread signal handling switch (Android)<br/>
|
|
|
- /// [ZH] 设置安卓多线程信号处理开关(仅Android)
|
|
|
- /// </summary>
|
|
|
- /// <param name="enable"></param>
|
|
|
- public static void setCatchMultiSignal(bool enable)
|
|
|
- {
|
|
|
- DebugLog(null, "setCatchMultiSignal: " + enable);
|
|
|
-
|
|
|
- UQMCrash.setCatchMultiSignal(enable);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets Android Fragment Tracking, iOS Page Tracking Switch<br/>
|
|
|
- /// [ZH] 设置安卓Fragment追踪、iOS页面追踪开关
|
|
|
- /// </summary>
|
|
|
- /// <param name="enable"></param>
|
|
|
- public static void enableDetailedPageTracing(bool enable)
|
|
|
- {
|
|
|
- DebugLog(null, "enableDetailedPageTracing: " + enable);
|
|
|
-
|
|
|
- UQMCrash.enableDetailedPageTracing(enable);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Checks if last session crashed<br/>
|
|
|
- /// [ZH] 判断上次启动会话是否发生崩溃
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- public static bool IsLastSessionCrash()
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- DebugLog(null, "IsLastSessionCrash");
|
|
|
-
|
|
|
- return UQMCrash.IsLastSessionCrash();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Gets user ID of last session<br/>
|
|
|
- /// [ZH] 获取上次会话的用户ID
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- public static string GetLastSessionUserId()
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return "";
|
|
|
- }
|
|
|
- DebugLog(null, "GetLastSessionUserId");
|
|
|
-
|
|
|
- return UQMCrash.GetLastSessionUserId();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Checks if file descriptor count exceeds limit<br/>
|
|
|
- /// [ZH] 检查文件描述符(FD)数量是否超过限制
|
|
|
- /// </summary>
|
|
|
- /// <param name="limit">
|
|
|
- /// [EN] Maximum FD count<br/>
|
|
|
- /// [ZH] FD数量限制
|
|
|
- /// </param>
|
|
|
- /// <param name="dumpType">
|
|
|
- /// [EN] 0: close, 1: call system interface dump, 3: minidump (only valid for mobile)<br/>
|
|
|
- /// [ZH] 0:关闭,1:调用系统接口dump,3:minidump(仅移动端有效)
|
|
|
- /// </param>
|
|
|
- /// <param name="upload">
|
|
|
- /// [EN] Whether to upload report<br/>
|
|
|
- /// [ZH] 是否上报
|
|
|
- /// </param>
|
|
|
- /// <returns>
|
|
|
- /// [EN] true if FD count exceeds limit, false otherwise<br/>
|
|
|
- /// [ZH] FD数量超过限制返回true,否则返回false
|
|
|
- /// </returns>
|
|
|
- public static bool CheckFdCount(int limit, int dumpType, bool upload)
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- return UQMCrash.CheckFdCount(limit, dumpType, upload);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets OOM log path (Android, iOS)<br/>
|
|
|
- /// [ZH] 设置OOM日志路径(Android、iOS)
|
|
|
- /// </summary>
|
|
|
- /// <param name="logPath">
|
|
|
- /// [EN] Path for OOM logs<br/>
|
|
|
- /// [ZH] OOM日志路径
|
|
|
- /// </param>
|
|
|
- public static void SetOomLogPath(string logPath)
|
|
|
- {
|
|
|
- UQMCrash.SetOomLogPath(logPath);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Reports jank<br/>
|
|
|
- /// [ZH] 上报卡顿事件
|
|
|
- /// </summary>
|
|
|
- /// <param name="type">
|
|
|
- /// [EN] Jank type (reserved for future use)<br/>
|
|
|
- /// [ZH] 卡顿类型(保留字段,暂未使用)
|
|
|
- /// </param>
|
|
|
- /// <param name="exceptionName">
|
|
|
- /// [EN] Name of the jank exception<br/>
|
|
|
- /// [ZH] 卡顿异常名称
|
|
|
- /// </param>
|
|
|
- /// <param name="exceptionMsg">
|
|
|
- /// [EN] Description of the jank event<br/>
|
|
|
- /// [ZH] 卡顿事件描述信息
|
|
|
- /// </param>
|
|
|
- /// <param name="exceptionStack">
|
|
|
- /// [EN] Stack trace of jank<br/>
|
|
|
- /// [ZH] 卡顿堆栈内容
|
|
|
- /// </param>
|
|
|
- /// <param name="paramsJson">
|
|
|
- /// [EN] Additional information in JSON format<br/>
|
|
|
- /// [ZH] 额外信息,JSON格式
|
|
|
- /// </param>
|
|
|
- /// <param name="reportInfoOption">
|
|
|
- /// [EN] Collection options for jank reporting information, represented by 6 binary bits for different options, 0 indicating no collection of additional information.<br/>
|
|
|
- /// The 1st bit: Collect system logs, the 2nd bit: Collect custom logs, the 3rd bit: Collect user-defined key-value pairs,
|
|
|
- /// the 4th bit: Trigger user callbacks, the 5th bit: Automatically dump stack traces, the 6th bit:Automatically collect full-thread Java stack.<br/>
|
|
|
- /// [ZH] jank上报信息收集选项,用6位二进制位表示不同选项,0表示不收集任何额外信息<br/>
|
|
|
- /// 第1位:收集系统日志,第2位:收集自定义日志,第3位:收集用户自定义键值对,第4位:触发用户回调,第5位:自动dump堆栈,第6位:自动采集全线程Java堆栈
|
|
|
- /// </param>
|
|
|
- /// <param name="jankAttachmentPath">
|
|
|
- /// [EN] Path to attachment file for jank report<br/>
|
|
|
- /// [ZH] 卡顿报告附件文件路径
|
|
|
- /// </param>
|
|
|
- public static void ReportJank(int type, string exceptionName,
|
|
|
- string exceptionMsg, string exceptionStack,
|
|
|
- string paramsJson, int reportInfoOption,
|
|
|
- string jankAttachmentPath)
|
|
|
- {
|
|
|
- UQMCrash.ReportJank(type, exceptionName, exceptionMsg, exceptionStack, paramsJson, reportInfoOption, jankAttachmentPath);
|
|
|
- }
|
|
|
-
|
|
|
- public static void ReportStuck(int threadId, int maxChecks, long checkInterval,
|
|
|
- string name, string message, Dictionary<string, string> extInfo,
|
|
|
- int dumpNativeType, string attachPath)
|
|
|
- {
|
|
|
- UQMCrash.ReportStuck(threadId, maxChecks, checkInterval, name, message, extInfo, dumpNativeType, attachPath);
|
|
|
- }
|
|
|
-
|
|
|
- /************************************PC、Xbox端接口************************************/
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets VEH(Vectored Exception Handling) enable status (Win, Xbox)<br/>
|
|
|
- /// [ZH] 设置VEH(向量化异常处理)捕获开关(Win、Xbox)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Enabled by default. Recommended to disable for Unity projects to avoid false crash reports.<br/>
|
|
|
- /// [ZH] 默认开启,建议所有Unity项目关闭此开关,否则可能产生crash误报。
|
|
|
- /// </remarks>
|
|
|
- /// <param name="enable"></param>
|
|
|
- public static void SetVehEnable(bool enable)
|
|
|
- {
|
|
|
- UQMCrash.SetVehEnable(enable);
|
|
|
- DebugLog(null, "SetVehEnable");
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Manually reports a crash (Win, Xbox)<br/>
|
|
|
- /// [ZH] 主动上报崩溃信息(Win、Xbox)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Reports a crash manually. Normally not needed, use only when necessary.<br/>
|
|
|
- /// [ZH] 主动上报一条崩溃信息,一般没有使用场景,可根据项目需要酌情使用。
|
|
|
- /// </remarks>
|
|
|
- public static void ReportCrash()
|
|
|
- {
|
|
|
- UQMCrash.ReportCrash();
|
|
|
- DebugLog(null, "ReportCrash");
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Manually reports dump file(Win, Xbox)<br/>
|
|
|
- /// [ZH] 主动上报dump文件(Win、Xbox)
|
|
|
- /// </summary>
|
|
|
- /// <param name="dump_path">
|
|
|
- /// [EN] Directory containing dump files<br/>
|
|
|
- /// [ZH] dump文件所在目录
|
|
|
- /// </param>
|
|
|
- /// <param name="is_async">
|
|
|
- /// [EN] Whether to report asynchronously<br/>
|
|
|
- /// [ZH] 是否异步上报
|
|
|
- /// </param>
|
|
|
- public static void ReportDump(string dump_path, bool is_async)
|
|
|
- {
|
|
|
- UQMCrash.ReportDump(dump_path, is_async);
|
|
|
- DebugLog(null, "ReportDump");
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets extra exception handler (Win, Xbox)<br/>
|
|
|
- /// [ZH] 设置额外异常捕获开关(Win、Xbox)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Disabled by default for backward compatibility.<br/>
|
|
|
- /// When enabled, can catch illegal parameter crashes from security functions like strcpy_s,
|
|
|
- /// and purecall errors from virtual function calls.<br/>
|
|
|
- /// [ZH] 默认为关闭,与旧版保持一致。<br/>
|
|
|
- /// 开启后,可以捕获上报strcpy_s一类的安全函数抛出的非法参数崩溃,以及虚函数调用purecall错误导致的崩溃。
|
|
|
- /// </remarks>
|
|
|
- /// <param name="extra_handle_enable"></param>
|
|
|
- public static void SetExtraHandler(bool extra_handle_enable)
|
|
|
- {
|
|
|
- UQMCrash.SetExtraHandler(extra_handle_enable);
|
|
|
- DebugLog(null, "SetExtraHandler");
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Uploads dump files from specified path (Win, Xbox)<br/>
|
|
|
- /// [ZH] 上传指定路径下的dump文件(Win、Xbox)
|
|
|
- /// </summary>
|
|
|
- /// <param name="dump_dir">
|
|
|
- /// [EN] Directory containing dump files<br/>
|
|
|
- /// [ZH] dump文件所在目录
|
|
|
- /// </param>
|
|
|
- /// <param name="is_extra_check">
|
|
|
- /// [EN] Extra validation check, set to false by default<br/>
|
|
|
- /// [ZH] 额外校验检查,默认填false即可
|
|
|
- /// </param>
|
|
|
- public static void UploadGivenPathDump(string dump_dir, bool is_extra_check)
|
|
|
- {
|
|
|
- UQMCrash.UploadGivenPathDump(dump_dir, is_extra_check);
|
|
|
- DebugLog(null, "UploadGivenPathDump");
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets dump type (Win, Xbox)<br/>
|
|
|
- /// [ZH] 设置dump类型(Win、Xbox)
|
|
|
- /// </summary>
|
|
|
- /// <param name="dump_type">
|
|
|
- /// [EN] Dump type value: see Windows documentation for valid values.<br/>
|
|
|
- /// [ZH] dump类型值,有效值请参考Windows官方文档
|
|
|
- /// </param>
|
|
|
- public static void SetDumpType(int dump_type)
|
|
|
- {
|
|
|
- UQMCrash.SetDumpType(dump_type);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Adds valid exception code (Win, Xbox)<br/>
|
|
|
- /// [ZH] 添加可用的异常类型(Win、Xbox)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Consult CrashSight developers before using<br/>
|
|
|
- /// [ZH] 使用前请咨询CrashSight开发人员
|
|
|
- /// </remarks>
|
|
|
- /// <param name="exp_code">
|
|
|
- /// [EN] Exception code: see Windows documentation<br/>
|
|
|
- /// [ZH] 异常代码: 参考Windows官方文档
|
|
|
- /// </param>
|
|
|
- public static void AddValidExpCode(ulong exp_code)
|
|
|
- {
|
|
|
- UQMCrash.AddValidExpCode(exp_code);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Uploads crash with specified GUID (Win, Xbox)<br/>
|
|
|
- /// [ZH] 上报指定GUID的错误(Win、Xbox)
|
|
|
- /// </summary>
|
|
|
- /// <param name="guid">
|
|
|
- /// [EN] GUID identifying the specific issue, an be obtained through callback.<br/>
|
|
|
- /// [ZH] 唯一问题的代码,可通过回调获取
|
|
|
- /// </param>
|
|
|
- public static void UploadCrashWithGuid(string guid)
|
|
|
- {
|
|
|
- UQMCrash.UploadCrashWithGuid(guid);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets crash upload enable status (Win, Xbox)<br/>
|
|
|
- /// [ZH] 设置崩溃上报开关(Win、Xbox)
|
|
|
- /// </summary>
|
|
|
- /// <param name="enable"></param>
|
|
|
- public static void SetCrashUploadEnable(bool enable)
|
|
|
- {
|
|
|
- UQMCrash.SetCrashUploadEnable(enable);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets workspace path (Win, Xbox)<br/>
|
|
|
- /// [ZH] 设置工作空间路径(Win、Xbox)
|
|
|
- /// </summary>
|
|
|
- /// <param name="workspace">
|
|
|
- /// [EN] Absolute path to workspace directory<br/>
|
|
|
- /// [ZH] 工作空间的绝对路径
|
|
|
- /// </param>
|
|
|
- public static void SetWorkSpace(string workspace)
|
|
|
- {
|
|
|
- UQMCrash.SetWorkSpace(workspace);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets custom attachment directory (Win, Xbox)<br/>
|
|
|
- /// [ZH] 设置自定义附件目录(Win、Xbox)
|
|
|
- /// </summary>
|
|
|
- /// <param name="path">
|
|
|
- /// [EN] Absolute path to attachment directory<br/>
|
|
|
- /// [ZH] 附件的绝对路径
|
|
|
- /// </param>
|
|
|
- public static void SetCustomAttachDir(string path)
|
|
|
- {
|
|
|
- UQMCrash.SetCustomAttachDir(path);
|
|
|
- }
|
|
|
-
|
|
|
- /************************************PS4、PS5、Switch端接口************************************/
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets error report interval (PS4, PS5, Switch)<br/>
|
|
|
- /// [ZH] 设置错误上报间隔(PS4、PS5、Switch)
|
|
|
- /// </summary>
|
|
|
- /// <param name="interval">
|
|
|
- /// [EN] Report interval in seconds<br/>
|
|
|
- /// [ZH] 错误上报间隔(单位:秒)
|
|
|
- /// </param>
|
|
|
- public static void SetErrorUploadInterval(int interval)
|
|
|
- {
|
|
|
- UQMCrash.SetErrorUploadInterval(interval);
|
|
|
- DebugLog(null, "SetErrorUploadInterval");
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Enables/disables error reporting (PS4, PS5, Switch)<br/>
|
|
|
- /// [ZH] 设置错误上报开关(PS4、PS5、Switch)
|
|
|
- /// </summary>
|
|
|
- /// <param name="enable"></param>
|
|
|
- public static void SetErrorUploadEnable(bool enable)
|
|
|
- {
|
|
|
- UQMCrash.SetErrorUploadEnable(enable);
|
|
|
- DebugLog(null, "SetErrorUploadEnable");
|
|
|
- }
|
|
|
-
|
|
|
- /************************************Linux端接口************************************/
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Sets directory for all record files (Linux)<br/>
|
|
|
- /// [ZH] 设置所有记录文件的路径(Linux)
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// [EN] Includes SDK logs and dump files, defaults to executable directory<br/>
|
|
|
- /// [ZH] 包括SDK日志和dump文件,默认为当前可执行文件的目录下
|
|
|
- /// </remarks>
|
|
|
- /// <param name="record_dir">
|
|
|
- /// [EN] Path to record files directory<br/>
|
|
|
- /// [ZH] 记录文件的路径
|
|
|
- /// </param>
|
|
|
- public static void SetRecordFileDir(string record_dir)
|
|
|
- {
|
|
|
- UQMCrash.SetRecordFileDir(record_dir);
|
|
|
- DebugLog(null, "SetRecordFileDir");
|
|
|
- }
|
|
|
-
|
|
|
- /************************************已废弃接口************************************/
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Initializes CrashSight (Windows/Xbox) - DEPRECATED, use <see cref="InitWithAppId"/> instead<br/>
|
|
|
- /// [ZH] 初始化CrashSight(Windows/Xbox平台)- 已废弃,请使用 <see cref="InitWithAppId"/> 替代
|
|
|
- /// </summary>
|
|
|
- /// <param name="userId"></param>
|
|
|
- /// <param name="version"></param>
|
|
|
- /// <param name="key"></param>
|
|
|
- [Obsolete("该接口已废弃,请使用 InitWithAppId 进行初始化")]
|
|
|
- public static void InitContext(string userId, string version, string key)
|
|
|
- {
|
|
|
- if (IsInitialized)
|
|
|
- {
|
|
|
- DebugLog(null, "CrashSightAgent has already been initialized.");
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (userId == null || string.IsNullOrEmpty(version) || string.IsNullOrEmpty(key))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- _isInitialized = true;
|
|
|
- // init the sdk with app id
|
|
|
- UQMCrash.InitContext(userId, version, key);
|
|
|
- DebugLog(null, "Initialized with userId: " + userId +" version: " + version + " key: " + key);
|
|
|
-
|
|
|
- // Register the LogCallbackHandler by Application.RegisterLogCallback(Application.LogCallback)
|
|
|
- _RegisterExceptionHandler();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Initializes CrashSight (Linux) - DEPRECATED, use <see cref="InitWithAppId"/> instead<br/>
|
|
|
- /// [ZH] 初始化CrashSight(Linux平台)- 已废弃,请使用 <see cref="InitWithAppId"/> 替代
|
|
|
- /// </summary>
|
|
|
- /// <param name="app_id"></param>
|
|
|
- /// <param name="app_key"></param>
|
|
|
- /// <param name="app_version"></param>
|
|
|
- [Obsolete("该接口已废弃,请使用 InitWithAppId 进行初始化")]
|
|
|
- public static void Init(string app_id, string app_key, string app_version)
|
|
|
- {
|
|
|
- if (IsInitialized)
|
|
|
- {
|
|
|
- DebugLog(null, "CrashSightAgent has already been initialized.");
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (string.IsNullOrEmpty(app_id) || string.IsNullOrEmpty(app_key) || string.IsNullOrEmpty(app_version))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- _isInitialized = true;
|
|
|
- // init the sdk with app id
|
|
|
- UQMCrash.Init(app_id, app_key, app_version);
|
|
|
- DebugLog(null, "Initialized with app_id: " + app_id + " app_key: " + app_key + " app_version: " + app_version);
|
|
|
-
|
|
|
- // Register the LogCallbackHandler by Application.RegisterLogCallback(Application.LogCallback)
|
|
|
- _RegisterExceptionHandler();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// [EN] Configures default settings (Android/iOS/Switch) - DEPRECATED<br/>
|
|
|
- /// [ZH] 配置默认设置(Android/iOS/Switch平台)- 已废弃
|
|
|
- /// </summary>
|
|
|
- /// <param name="channel"></param>
|
|
|
- /// <param name="version"></param>
|
|
|
- /// <param name="user"></param>
|
|
|
- /// <param name="delay"></param>
|
|
|
- [Obsolete("该接口已废弃")]
|
|
|
- public static void ConfigDefault(string channel, string version, string user, long delay)
|
|
|
- {
|
|
|
- DebugLog(null, "Config default channel:" + channel + ", version:" + version + ", user:" + user + ", delay:" + delay);
|
|
|
- UQMCrash.ConfigDefault(channel, version, user, delay);
|
|
|
- }
|
|
|
-
|
|
|
- #region Privated Fields and Methods
|
|
|
- /************************************private部分************************************/
|
|
|
-
|
|
|
- private static void _OnLogCallbackHandlerMain(string condition, string stackTrace, LogType type)
|
|
|
- {
|
|
|
- _OnLogCallbackHandler(condition, stackTrace, type, CSReportType.LogCallback);
|
|
|
- }
|
|
|
-
|
|
|
- private static void _OnLogCallbackHandlerThreaded(string condition, string stackTrace, LogType type)
|
|
|
- {
|
|
|
- _OnLogCallbackHandler(condition, stackTrace, type, CSReportType.LogCallbackThreaded);
|
|
|
- }
|
|
|
-
|
|
|
- private static void _OnLogCallbackHandler(string condition, string stackTrace, LogType type, CSReportType rType)
|
|
|
- {
|
|
|
- if (_LogCallbackEventHandler != null)
|
|
|
- {
|
|
|
- _LogCallbackEventHandler(condition, stackTrace, type);
|
|
|
- }
|
|
|
-
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (!string.IsNullOrEmpty(condition) && condition.Contains("[CrashSightAgent] <Log>"))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (_uncaughtAutoReportOnce)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (callbackThreads.Contains(Thread.CurrentThread.ManagedThreadId))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- _HandleException(type, null, condition, stackTrace, true, rType);
|
|
|
- }
|
|
|
-
|
|
|
- private static void _OnUncaughtExceptionHandler(object sender, System.UnhandledExceptionEventArgs args)
|
|
|
- {
|
|
|
- if (args == null || args.ExceptionObject == null)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
- if (args.ExceptionObject.GetType() != typeof(System.Exception))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- catch
|
|
|
- {
|
|
|
- if (UnityEngine.Debug.isDebugBuild == true)
|
|
|
- {
|
|
|
- UnityEngine.Debug.Log("CrashSightAgent: Failed to report uncaught exception");
|
|
|
- }
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (_uncaughtAutoReportOnce)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- _HandleException((System.Exception)args.ExceptionObject, null, true);
|
|
|
- }
|
|
|
-
|
|
|
- private static void _HandleException(System.Exception e, string message, bool uncaught)
|
|
|
- {
|
|
|
- if (e == null)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- string name = e.GetType().Name;
|
|
|
- string reason = e.Message;
|
|
|
-
|
|
|
- if (!string.IsNullOrEmpty(message))
|
|
|
- {
|
|
|
- reason = string.Format("{0}{1}***{2}", reason, Environment.NewLine, message);
|
|
|
- }
|
|
|
-
|
|
|
- StringBuilder stackTraceBuilder = new StringBuilder(512);
|
|
|
-
|
|
|
- StackTrace stackTrace = new StackTrace(e, true);
|
|
|
- int count = stackTrace.FrameCount;
|
|
|
- for (int i = 0; i < count; i++)
|
|
|
- {
|
|
|
- StackFrame frame = stackTrace.GetFrame(i);
|
|
|
-
|
|
|
- stackTraceBuilder.AppendFormat("{0}.{1}", frame.GetMethod().DeclaringType.Name, frame.GetMethod().Name);
|
|
|
-
|
|
|
- ParameterInfo[] parameters = frame.GetMethod().GetParameters();
|
|
|
- if (parameters == null || parameters.Length == 0)
|
|
|
- {
|
|
|
- stackTraceBuilder.Append(" () ");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- stackTraceBuilder.Append(" (");
|
|
|
-
|
|
|
- int pcount = parameters.Length;
|
|
|
-
|
|
|
- ParameterInfo param = null;
|
|
|
- for (int p = 0; p < pcount; p++)
|
|
|
- {
|
|
|
- param = parameters[p];
|
|
|
- stackTraceBuilder.AppendFormat("{0} {1}", param.ParameterType.Name, param.Name);
|
|
|
-
|
|
|
- if (p != pcount - 1)
|
|
|
- {
|
|
|
- stackTraceBuilder.Append(", ");
|
|
|
- }
|
|
|
- }
|
|
|
- param = null;
|
|
|
-
|
|
|
- stackTraceBuilder.Append(") ");
|
|
|
- }
|
|
|
-
|
|
|
- string fileName = frame.GetFileName();
|
|
|
- if (!string.IsNullOrEmpty(fileName) && !fileName.ToLower().Equals("unknown"))
|
|
|
- {
|
|
|
- fileName = fileName.Replace("\\", "/");
|
|
|
-
|
|
|
- int loc = fileName.ToLower().IndexOf("/assets/");
|
|
|
- if (loc < 0)
|
|
|
- {
|
|
|
- loc = fileName.ToLower().IndexOf("assets/");
|
|
|
- }
|
|
|
-
|
|
|
- if (loc > 0)
|
|
|
- {
|
|
|
- fileName = fileName.Substring(loc);
|
|
|
- }
|
|
|
-
|
|
|
- stackTraceBuilder.AppendFormat("(at {0}:{1})", fileName, frame.GetFileLineNumber());
|
|
|
- }
|
|
|
- stackTraceBuilder.AppendLine();
|
|
|
- }
|
|
|
-
|
|
|
- // report
|
|
|
- _reportException(uncaught, name, reason, stackTraceBuilder.ToString());
|
|
|
- }
|
|
|
-
|
|
|
- private static bool ShouldSkipFrame(string frame)
|
|
|
- {
|
|
|
- string[] skipPatterns = { "System.Collections.Generic.", "ShimEnumerator", "CrashSight" };
|
|
|
-
|
|
|
- foreach (var pattern in skipPatterns)
|
|
|
- {
|
|
|
- if (frame.StartsWith(pattern, StringComparison.Ordinal))
|
|
|
- {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- private static void _reportException(bool uncaught, string name, string reason, string stackTrace)
|
|
|
- {
|
|
|
- if (string.IsNullOrEmpty(name))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (string.IsNullOrEmpty(stackTrace))
|
|
|
- {
|
|
|
- stackTrace = StackTraceUtility.ExtractStackTrace();
|
|
|
- }
|
|
|
-
|
|
|
- if (string.IsNullOrEmpty(stackTrace))
|
|
|
- {
|
|
|
- stackTrace = "Empty";
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
- string[] frames = stackTrace.Split('\n');
|
|
|
-
|
|
|
- if (frames != null && frames.Length > 0)
|
|
|
- {
|
|
|
-
|
|
|
- StringBuilder trimFrameBuilder = new StringBuilder(512);
|
|
|
-
|
|
|
- string frame = null;
|
|
|
- int count = frames.Length;
|
|
|
- for (int i = 0; i < count; i++)
|
|
|
- {
|
|
|
- frame = frames[i];
|
|
|
-
|
|
|
- if (string.IsNullOrEmpty(frame) || string.IsNullOrEmpty(frame.Trim()))
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- frame = frame.Trim();
|
|
|
-
|
|
|
- if (string.IsNullOrEmpty(frame) || ShouldSkipFrame(frame) || frame.Contains("..ctor"))
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- int start = -1;
|
|
|
- int end = -1;
|
|
|
- if (frame.Contains("(at") && frame.Contains("/assets/"))
|
|
|
- {
|
|
|
- start = frame.IndexOf("(at", StringComparison.OrdinalIgnoreCase);
|
|
|
- end = frame.IndexOf("/assets/", StringComparison.OrdinalIgnoreCase);
|
|
|
-
|
|
|
- }
|
|
|
- if (start > 0 && end > 0)
|
|
|
- {
|
|
|
- trimFrameBuilder.AppendFormat("{0}(at {1}", frame.Substring(0, start).Replace(":", "."), frame.Substring(end));
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- trimFrameBuilder.Append(frame.Replace(":", "."));
|
|
|
- }
|
|
|
-
|
|
|
- trimFrameBuilder.AppendLine();
|
|
|
- }
|
|
|
-
|
|
|
- stackTrace = trimFrameBuilder.ToString();
|
|
|
- }
|
|
|
- }
|
|
|
- catch
|
|
|
- {
|
|
|
- PrintLog(CSLogSeverity.LogWarning, "{0}", "Error to parse the stack trace");
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-// PrintLog(CSLogSeverity.LogError, "ReportException: " + name + " " + reason + "\n*********\n" + stackTrace + "\n*********");
|
|
|
-
|
|
|
- _uncaughtAutoReportOnce = uncaught && _autoQuitApplicationAfterReport;
|
|
|
-
|
|
|
- string extraInfo = string.Empty;
|
|
|
- Dictionary<string, string> extras = null;
|
|
|
- if (_LogCallbackExtrasHandler != null)
|
|
|
- {
|
|
|
- extras = _LogCallbackExtrasHandler();
|
|
|
- }
|
|
|
-
|
|
|
- if (extras != null && extras.Count > 0)
|
|
|
- {
|
|
|
- StringBuilder builder = new StringBuilder(128);
|
|
|
- foreach (KeyValuePair<string, string> kvp in extras)
|
|
|
- {
|
|
|
- builder.AppendFormat("\"{0}\" : \"{1}\", ", kvp.Key, kvp.Value);
|
|
|
- }
|
|
|
- builder.Length -= 2; // 去掉最后一个逗号和空格
|
|
|
- extraInfo = "{" + builder.ToString() + "}";
|
|
|
- }
|
|
|
- UQMCrash.ReportException(4, name, reason, stackTrace, extraInfo, uncaught && AutoQuitApplicationAfterReport);
|
|
|
- }
|
|
|
-
|
|
|
- private static int valueOf(LogType logLevel)
|
|
|
- {
|
|
|
- switch(logLevel)
|
|
|
- {
|
|
|
- case LogType.Exception:
|
|
|
- return 1;
|
|
|
- case LogType.Error:
|
|
|
- return 2;
|
|
|
- case LogType.Assert:
|
|
|
- return 3;
|
|
|
- case LogType.Warning:
|
|
|
- return 4;
|
|
|
- case LogType.Log:
|
|
|
- return 5;
|
|
|
- default:
|
|
|
- return 6;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static bool isEnableAutoReport(LogType logLevel)
|
|
|
- {
|
|
|
- return valueOf(logLevel) <= valueOf(_autoReportLogLevel);
|
|
|
- }
|
|
|
-
|
|
|
- private static void _HandleException(LogType logLevel, string name, string message, string stackTrace, bool uncaught, CSReportType rType)
|
|
|
- {
|
|
|
- if (!IsInitialized)
|
|
|
- {
|
|
|
- DebugLog(null, "It has not been initialized.");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if ((uncaught && !isEnableAutoReport(logLevel)))
|
|
|
- {
|
|
|
- DebugLog(null, "Not report exception for level " + logLevel.ToString());
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- string type = null;
|
|
|
- string reason = "";
|
|
|
-
|
|
|
- if (!string.IsNullOrEmpty(message))
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- if ((LogType.Exception == logLevel) && message.Contains("Exception"))
|
|
|
- {
|
|
|
-
|
|
|
- Match match = new Regex(@"^(?<errorType>\S+):\s*(?<errorMessage>.*)", RegexOptions.Singleline).Match(message);
|
|
|
-
|
|
|
- if (match.Success)
|
|
|
- {
|
|
|
- if (stackTrace.Contains("UnityEngine.Debug:LogException"))
|
|
|
- {
|
|
|
- if (rType == CSReportType.LogCallback)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (rType == CSReportType.LogCallbackThreaded)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- type = match.Groups["errorType"].Value.Trim();
|
|
|
- reason = match.Groups["errorMessage"].Value.Trim();
|
|
|
- }
|
|
|
- else if (rType == CSReportType.LogCallback)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- else if ((LogType.Error == logLevel) && message.StartsWith("Unhandled Exception:", StringComparison.Ordinal))
|
|
|
- {
|
|
|
-
|
|
|
- Match match = new Regex(@"^Unhandled\s+Exception:\s*(?<exceptionName>\S+):\s*(?<exceptionDetail>.*)", RegexOptions.Singleline).Match(message);
|
|
|
-
|
|
|
- if (match.Success)
|
|
|
- {
|
|
|
- if (rType == CSReportType.LogCallbackThreaded)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- string exceptionName = match.Groups["exceptionName"].Value.Trim();
|
|
|
- string exceptionDetail = match.Groups["exceptionDetail"].Value.Trim();
|
|
|
-
|
|
|
- //
|
|
|
- int dotLocation = exceptionName.LastIndexOf(".");
|
|
|
- if (dotLocation > 0 && dotLocation != exceptionName.Length)
|
|
|
- {
|
|
|
- type = exceptionName.Substring(dotLocation + 1);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- type = exceptionName;
|
|
|
- }
|
|
|
-
|
|
|
- int stackLocation = exceptionDetail.IndexOf(" at ");
|
|
|
- if (stackLocation > 0)
|
|
|
- {
|
|
|
- //
|
|
|
- reason = exceptionDetail.Substring(0, stackLocation);
|
|
|
- // substring after " at "
|
|
|
- string callStacks = exceptionDetail.Substring(stackLocation + 3).Replace(" at ", "\n").Replace("in <filename unknown>:0", string.Empty).Replace("[0x00000]", string.Empty);
|
|
|
- //
|
|
|
- stackTrace = stackTrace + "\n" + callStacks.Trim();
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- reason = exceptionDetail;
|
|
|
- }
|
|
|
-
|
|
|
- // for LuaScriptException
|
|
|
- if (type.Equals("LuaScriptException") && exceptionDetail.Contains(".lua") && exceptionDetail.Contains("stack traceback:"))
|
|
|
- {
|
|
|
- stackLocation = exceptionDetail.IndexOf("stack traceback:");
|
|
|
- if (stackLocation > 0)
|
|
|
- {
|
|
|
- reason = exceptionDetail.Substring(0, stackLocation);
|
|
|
- // substring after "stack traceback:"
|
|
|
- string callStacks = exceptionDetail.Substring(stackLocation + 16).Replace(" [", " \n[");
|
|
|
-
|
|
|
- //
|
|
|
- stackTrace = stackTrace + "\n" + callStacks.Trim();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else if (rType == CSReportType.LogCallback)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- else if (rType == CSReportType.LogCallback)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- catch
|
|
|
- {
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if (string.IsNullOrEmpty(reason))
|
|
|
- {
|
|
|
- reason = message;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (string.IsNullOrEmpty(name))
|
|
|
- {
|
|
|
- if (string.IsNullOrEmpty(type))
|
|
|
- {
|
|
|
- string sLogLevel = "Log";
|
|
|
- switch (logLevel)
|
|
|
- {
|
|
|
- case LogType.Log:
|
|
|
- sLogLevel = "Log";
|
|
|
- break;
|
|
|
- case LogType.Warning:
|
|
|
- sLogLevel = "LogWarning";
|
|
|
- break;
|
|
|
- case LogType.Assert:
|
|
|
- sLogLevel = "LogAssert";
|
|
|
- break;
|
|
|
- case LogType.Error:
|
|
|
- sLogLevel = "LogError";
|
|
|
- break;
|
|
|
- case LogType.Exception:
|
|
|
- sLogLevel = "LogException";
|
|
|
- break;
|
|
|
- }
|
|
|
- type = "Unity" + sLogLevel;
|
|
|
- if (CrashSightStackTrace.enable)
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- stackTrace = CrashSightStackTrace.ExtractStackTrace();
|
|
|
- //去掉前三行
|
|
|
- if (stackTrace.Contains("CrashSightAgent:_HandleException(LogType, String, String, String, Boolean)")
|
|
|
- && stackTrace.Contains("CrashSightAgent:_OnLogCallbackHandler(String, String, LogType)")
|
|
|
- && stackTrace.Contains("UnityEngine.Application:CallLogCallback(String, String, LogType, Boolean)"))
|
|
|
- {
|
|
|
- int count = stackTrace.IndexOf("\n");
|
|
|
- count = stackTrace.IndexOf("\n", count + 1);
|
|
|
- count = stackTrace.IndexOf("\n", count + 1);
|
|
|
- stackTrace = stackTrace.Substring(count + 1);
|
|
|
- }
|
|
|
- }
|
|
|
- catch
|
|
|
- {
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- type = name;
|
|
|
- }
|
|
|
-
|
|
|
- _reportException(uncaught, type, reason, stackTrace);
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
-}
|