sentry-unity
sentry-unity copied to clipboard
Improve stack trace when targeting `WebGL`
Does it support the WebGL platform for WeChat mini-game development?
It does support webgl. but wechat specifically I'm not sure. could you try and let us know?
But when I try to build a webgl package and display it on a web page, the stack cannot be displayed. Is there any step that is not executed? And Does it support crash log capture for webgl? When I enter the crash command of unity, there is no log capture.
Can you provide a sample for us to look at? When running the SDK's sample game, I do see the stack trace getting reported.
Demo: https://github.com/dryyy27/SentryDemo.git. I deleted the dsn, auth, project and organization. When I switch the platform to Linux or Android, the stack can be displayed
Thanks for the repro. The stack trace doesn't work even on webgl outside wechat? if we just build it for web vs linux we'll see the lack of stack trace you mean?
It doesn't work even on webgl outside wechat. But when I build android or linux, it work normally.
We didn't get around trying the report yet but to confirm:
- Which browser are you using?
- Is there a stack trace in the browser dev tools?
Hi guys. We have almost the same issue in our projects. So I can provide my investigation results and share some more details.
- Package version:
3.1.0 - Unity Version:
2022.3.19f1 - Platform:
WebGL - Tested on the:
Google Chrome
We have SentrySDK integrated via Package Manager and instead of using base config we're disabling it with Enable Sentry toggle from the Sentry SDK Options window and doing a runtime initialization via C# using SentrySDK.Init(options) where options parameter contains our custom setup per environment using the same DSN but different Sample Rates and etc.
Right after calling SentrySDK.Init we are also calling SentrySDK.CaptureMessage(msg) to test if Custom messages are coming through the dashboard.
As a result:
- We DO get all errors and messages that were sent from the Unity Editor.
- We DO NOT get any error/warning or custom events we sent from the browser.
Also some extra info we found when we used config initialization instead of C#.
- We DO get some events, but maybe about 1 of 20 events, event if Sample Rate set to 1(100%) and configuration values set to get all warnings and errors.
Here is the code we use to initialize the SentrySDK:
private static void InternalInit(string dsn, string environment)
{
#if SENTRY
SentrySdk.Close();
if (string.IsNullOrEmpty(dsn))
{
Debug.Log("[SDK_Init] Sentry SDK is disabled by remote config, 'sentry_dsn' is not defined");
return;
}
RuntimeInfo.Environment env = RuntimeInfoManager.ConvertEnvironment(environment);
float sampleRate = env == RuntimeInfo.Environment.Production
? sentry_sample_rate
: 1;
Debug.Log($"[SDK_Init] Sentry SDK initialization with '{dsn}', env '{environment}' and '{sampleRate}' sample rate");
SentrySdk.Init(options =>
{
options.Dsn = dsn;
options.TracesSampleRate = sampleRate;
options.MaxCacheItems = 30;
options.InitCacheFlushTimeout = TimeSpan.FromMilliseconds(0);
options.ShutdownTimeout = TimeSpan.FromSeconds(2);
options.MaxQueueItems = 30;
options.Release = $"{RuntimeInfoManager.runtimeInfo.version}";
options.AutoSessionTrackingInterval = TimeSpan.FromSeconds(30);
options.Environment = environment;
options.ProfilesSampleRate = 1;
options.SampleRate = 1;
});
Debug.Log($"[SDK_Init] Sentry SDK initialized, SentrySdk.Enabled: {SentrySdk.IsEnabled}");
#else
Debug.Log("[SDK_Init] Sentry SDK is disabled by define symbol");
#endif
}
@EduardSayGames thanks for sharing the details.
One thing I noticed is that. you're using SentrySdk.Init which is the .NET SDK, without any of the Unity stuff we built here.
Can you try this out with SentryUnity.Init instead?
@bruno-garcia Thank you for this option.
Unfortunately, issue is still the same. I do see logs from the Editor, but nothing from the browser. I did try it with Safari as well to check if it isn't only Chrome, same result.
As a side question, wouldn't it be better to make SentrySdk.Init internal to avoid two APIs doing the same if you already have SentryUnity.Init?
However, I can confirm both APIs didn't work for my WebGL builds but they are both working just well in the Editor.
SentrySdk is a public class of the core API of the dotnet SDK which Unity is built on too. Not sure how we can hide that but agree it's a pitfall having that in combination with SentryUnity.
We'll need to debug this through. Something must have changed in the Unity side I imagine.
@bruno-garcia Please let me know if I can help with debugging or anything else. Thanks again! We’re looking forward to getting the SDK integrated for production as soon as you’ve figured this out.
We didn't get around trying the report yet but to confirm:我们还没有尝试报告,但为了确认:
- Which browser are you using?您正在使用哪个浏览器?
- Is there a stack trace in the browser dev tools?浏览器开发者工具中是否有堆栈跟踪?
I used Google Chrome。Strack trace like this:
Could you try SentrySdk.CaptureException? Looking at this with @bitsandfoxes he mentioned messages on WebGL don't have stack traces (Unity doesn't give them out).
e.g:
void Test1() { throw new Exception("test"); }
void Test2() {
try { Test1(): } catch (Exception e) {SentrySdk.CaptureException(e);)}
}
This should work. And if so, it sounds like we need to document bettter where/when Unity provides a stack trace so Sentry can attach that to events, or not.
like this? but it don't display
Thank you for confirming. There's definitely something broken here. We'll look into this asap.
Hey @dryyy27, @EduardSayGames, sorry this took some time to dig into. Thanks for providing the minimal repro, it helped a lot! Sorry to not have any better news but here it goes.
In the provided setup the SDK fails to create the stacktrace with Could not resolve stack frame. here, leading to
Sentry: (Debug) Created DebugStackTrace with 0 frames.
leading to missing stack traces in the issues on Sentry.
Currently, it looks like there's not much the SDK can do at this point and seems to be a limitation of WebGL and its exception handling. The only option forward I have found at this point is to change the exception settings in the PlayerSettings here:
With Full with Stacktrace the SDK is able to provide a proper stack trace on the events in Sentry.
But when trying to make use of Unity's stringified stack traces available in Unity 6 and newer we're getting this:
| $WebGLPrintfConsolev(LogType, char const*, void*) | @ | Test.wasm:0x9a033e
| $printf_consolev(LogType, char const*, void*, bool, LineEndInfoHint) | @ | Test.wasm:0xe6f040
| $InternalErrorConsoleWithNewline(char const*, ...) | @ | Test.wasm:0xe704fd
| $DebugStringToFilePostprocessedStacktrace(DebugStringToFileData const&) | @ | Test.wasm:0xe703e3
| $DebugStringToFile(DebugStringToFileData const&) | @ | Test.wasm:0xe6fb0f
| $DebugLogHandler_CUSTOM_Internal_Log(LogType, LogOption, BindingsManagedSpan*, void*) | @ | Test.wasm:0xe3090a
| $dynCall_viiii | @ | Test.wasm:0xe7bbce
| invoke_viiii | @ | Test.framework.js:9
| $DebugLogHandler_Internal_Log_m20852F18A88BB18425BA07260545E3968F7EA76C | @ | Test.wasm:0x3bc563
| $DebugLogHandler_LogFormat_m216B169EF9B669F2ED4C59F6B9F326D4EBBDF821 | @ | Test.wasm:0x3bc722
| $UnityLogHandlerIntegration_LogFormat_m05B60A465C6F6A98B4E14C2128DED1281EE38DE2 | @ | Test.wasm:0x7a7576
| $Logger_Log_mEA3D39763D610E92491AA479BA653ECFEE3E9E5C | @ | Test.wasm:0x3c73aa
| $Debug_LogError_mB00B2B4468EF3CAF041B038D840820FB84C924B2 | @ | Test.wasm:0x3bce38
| $Main_Start_m5864CE07B60D35921FE23903087087FC5C3CF8FD | @ | Test.wasm:0x944afc
| $RuntimeInvoker_TrueVoid_t4861ACF8F4594C3437BB48B6E56783494B843915(void (*)(), MethodInfo const*, void*, void**, void*) | @ | Test.wasm:0x97252a
| $il2cpp::vm::Runtime::InvokeWithThrow(MethodInfo const*, void*, void**) | @ | Test.wasm:0x98c8aa
| $dynCall_iiii | @ | Test.wasm:0xe7bb48
| invoke_iiii | @ | Test.framework.js:9
| $il2cpp::vm::Runtime::Invoke(MethodInfo const*, void*, void**, Il2CppException**) | @ | Test.wasm:0x98b9d2
| $il2cpp_runtime_invoke | @ | Test.wasm:0x99930
| $scripting_method_invoke(ScriptingMethodPtr, ScriptingObjectPtr, ScriptingArguments&, ScriptingExceptionPtr*, bool) | @ | Test.wasm:0xe48960
| $ScriptingInvocation::Invoke(ScriptingExceptionPtr*, bool) | @ | Test.wasm:0xe173d4
| $MonoBehaviour::InvokeMethodOrCoroutineChecked(ScriptingMethodPtr, ScriptingObjectPtr) | @ | Test.wasm:0xdcce1b
| $MonoBehaviour::DelayedStartCall(Object*, void*) | @ | Test.wasm:0xdce3e7
| $DelayedCallManager::Update(int) | @ | Test.wasm:0xb70f80
| $InitPlayerLoopCallbacks()::EarlyUpdateScriptRunDelayedStartupFrameRegistrator::Forward() | @ | Test.wasm:0xca374e
| $ExecutePlayerLoop(NativePlayerLoopSystem*) | @ | Test.wasm:0xc34e1b
| $ExecutePlayerLoop(NativePlayerLoopSystem*) | @ | Test.wasm:0xc34e90
| $MainLoop() | @ | Test.wasm:0xe50c92
| $dynCall_v | @ | Test.wasm:0xe7bb50
| (anonymous)
So this might be something we could capture and attempt to parse in a future update of the SDK.
In Unity 6.1 changing these options is greyed out:
We could parse that in the SDK and create a stack trace but there wouldn't be any line numbers unless we add symbolication support. Looking at those file name and hex appended to the line it seems to be memory addresses we could use.
For now I'd add to the docs that we don't support stack traces for Wasm starting on version X of Unity (assuming it broke eventually, since iirc we did have the parsing working originally and had stack traces without line numbers already)
Thank you @bitsandfoxes @bruno-garcia for sharing this information. But this won't solve my issue because I don't get any error registered in the dashboard, even without stacktraces. So my issue is still open.
FYI: I've updated the SDK to the latest 3.2.1 and it has the same issue.
I'll have to try and check the conditions under which we can reliably grab and parse the stacktrace and then put together a PR.
So after digging through it there are two issues tied to the `exceptionSupport:
PlayerSettings.WebGL.exceptionSupport Limitations
None
Not supported. See https://github.com/getsentry/sentry-unity/pull/2141 for more details.
Explicitly Thrown Exceptions Only
Captures and reports exceptions but misses stacktrace.
Full Without Stacktrace
Captures and reports exceptions but misses stacktrace.
Full With Stacktrace
Captures and reports exception and provides a stacktrace (albeit with no line numbers due to lack of IL2CPP backend availability)
Failing to create a new StackTrace
This is happening when setting to Explicitly Thrown Exceptions Only and Full Without Stacktrace.
The SDK fails trying to create a new SentryStackTrace the SDK fails with Could not resolve stack frame. This is due to the DebugStackTrace failing to create a managed frame. It relies on the following snippet used in the AotHelper
var stackTrace = new StackTrace(false);
return stackTrace.GetFrame(0)?.GetMethod() is null;
To resolve this we could provide our own dedicated WebGLStackTraceFactory to create a new frame and fall back on stackFrame.ToString() instead of doing nothing. And probably skip a whole lot of other, for WebGL unnecessary checks i.e.
if (CreateFrame(stackFrame) is { } frame)
{
yield return frame;
}
else
{
yield return new SentryStackFrame { Function = stackFrame.ToString() };
}
LogError events missing stacktrace
The missing stacktrace also mentioned in https://github.com/getsentry/sentry-unity/issues/2091#issuecomment-2839750715 is also related to the PlayerSettings.WebGL.exceptionSupport. When setting to FullWithStacktrace the SDK is able to provide stacktraces for these events as well. Set to any other option Unity does not pass down a stacktrace to the logging integration and we'd need to create a new stacktrace, bringing us back to the point above.
Recommendation
The current recommendation is to set PlayerSettings.WebGL.exceptionSupport to Full With Stacktrace to get the most out of the SDK. Anything else will require us to build a WebGL specific integration to better handle those cases.
Superseded by https://github.com/getsentry/sentry-unity/issues/2415