Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gather callstack even if instruction pointer is null. #1303

Merged
merged 1 commit into from
Jun 7, 2020

Conversation

unpacklo
Copy link

@unpacklo unpacklo commented Jun 3, 2020

Address this issue https://unity3d.atlassian.net/browse/DOTS-1997

This change allows a full callstack to be obtained even if IP is NULL. I encountered this issue while working on a CI failure https://unity3d.atlassian.net/browse/DOTS-1866 that caused the editor to crash and the logs showed Obtained 0 stack frames.. In this failure, some external function pointers were not always being set which allowed an indirect jump to NULL. Since no callstack was printed, debugging this issue was more difficult.

@unpacklo
Copy link
Author

unpacklo commented Jun 3, 2020

My manual test required changing some code in the editor, namely in the ForceCrash function and then calling that from a script:

diff --git a/Runtime/Export/Diagnostics/DiagnosticsUtils.bindings.cpp b/Runtime/Export/Diagnostics/DiagnosticsUtils.bindings.cpp
index addee2b48877..b85b9233f569 100644
--- a/Runtime/Export/Diagnostics/DiagnosticsUtils.bindings.cpp
+++ b/Runtime/Export/Diagnostics/DiagnosticsUtils.bindings.cpp
@@ -17,6 +17,7 @@
 #include <signal.h>
 #endif

+extern void (*wtfFuncPtr)();

 namespace DiagnosticsUtils_Bindings
 {
@@ -28,10 +29,12 @@ namespace DiagnosticsUtils_Bindings
         {
             printf_console("Forcing a crash -- Intentionally Dereferencing NULL pointer\n");
 #if UNITY_POSIX
-            raise(SIGSEGV);
+            //raise(SIGSEGV);
+            wtfFuncPtr();
 #elif PLATFORM_WIN
             RaiseException(EXCEPTION_ACCESS_VIOLATION, NULL, NULL, NULL);
 #else
+            wtfFuncPtr();
             int* p = NULL;
             *p = 5;
 #endif
diff --git a/Runtime/Export/Unsafe/UnsafeUtility.bindings.cpp b/Runtime/Export/Unsafe/UnsafeUtility.bindings.cpp
index 75f89d167bea..c3e9af2ce8b3 100644
--- a/Runtime/Export/Unsafe/UnsafeUtility.bindings.cpp
+++ b/Runtime/Export/Unsafe/UnsafeUtility.bindings.cpp
@@ -10,6 +10,7 @@
 int* g_NativeArrayContainer = NULL;
 static UNITY_TLS_VALUE(ManagedTempMemScope*) gCurrentManagedTempMem;

+void (*wtfFuncPtr)() = nullptr;

 struct StackAllocatorAtomicNode
 {

Running this test before this PR, Unity crashes and contains this in the log:

DisplayProgressbar: Test Runner
Forcing a crash -- Intentionally Dereferencing NULL pointer
Obtained 0 stack frames.
[Unity Package Manager (Upm)]
Parent process [995] was terminated

Running this test with the changes included in this PR:

DisplayProgressbar: Test Runner
Forcing a crash -- Intentionally Dereferencing NULL pointer
Obtained 58 stack frames.
#0  0x00000000000000 in (Unknown)
#1  0x00000105c60d53 in Utils_CUSTOM_ForceCrash(DiagnosticsUtils_Bindings::ForcedCrashCategory)
#2  0x0000015451144d in  (wrapper managed-to-native) UnityEngine.Diagnostics.Utils:ForceCrash (UnityEngine.Diagnostics.ForcedCrashCategory) {0x7fd9311b7110} + 0x5d (0x1545113f0 0x1545114d5) [0x13104e960 - Unity Child Domain]
#3  0x0000013090ef0c in mono_jit_runtime_invoke
#4  0x00000130ad1801 in do_runtime_invoke
#5  0x00000130ad4b88 in mono_runtime_try_invoke_array
#6  0x00000130a83a94 in ves_icall_InternalInvoke
#7  0x0000013c7cb261 in  (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) {0x7fd940c0e120} + 0x71 (0x13c7cb1f0 0x13c7cb30b) [0x13104e960 - Unity Child Domain]
#8  0x0000013c7cabeb in  System.Reflection.MethodBase:Invoke (object,object[]) {0x7fd948d42df0} + 0x2b (0x13c7cabc0 0x13c7cabf4) [0x13104e960 - Unity Child Domain]
#9  0x00000154510ae3 in  NUnit.Framework.Internal.MethodWrapper:Invoke (object,object[]) {0x7fd930527900} + 0x33 (0x154510ab0 0x154510ae8) [0x13104e960 - Unity Child Domain]
#10 0x000001545107cb in  UnityEngine.TestRunner.NUnitExtensions.Runner.UnityLogCheckDelegatingCommand:ExecuteAndCheckLog (UnityEngine.TestTools.Logging.LogScope,NUnit.Framework.Internal.TestResult,System.Action) {0x7fd948b93848} + 0x2b (0x1545107a0 0x1545107f8) [0x13104e960 - Unity Child Domain]
#11 0x00000154510072 in  UnityEngine.TestRunner.NUnitExtensions.Runner.UnityLogCheckDelegatingCommand/<ExecuteEnumerable>d__3:MoveNext () {0x7fd948bb8158} + 0x1a2 (0x15450fed0 0x1545104bb) [0x13104e960 - Unity Child Domain]
#12 0x000001524f3b96 in  UnityEngine.TestTools.BeforeAfterTestCommandBase`1/<ExecuteEnumerable>d__9<T_REF>:MoveNext () {0x7fd8f244b850} + 0xb96 (0x1524f3000 0x1524f4347) [0x13104e960 - Unity Child Domain]
#13 0x000001524f3b96 in  UnityEngine.TestTools.BeforeAfterTestCommandBase`1/<ExecuteEnumerable>d__9<T_REF>:MoveNext () {0x7fd8f244b850} + 0xb96 (0x1524f3000 0x1524f4347) [0x13104e960 - Unity Child Domain]
#14 0x000001524f5a92 in  UnityEngine.TestTools.ImmediateEnumerableCommand:Execute (NUnit.Framework.Internal.ITestExecutionContext) {0x7fd948b9c4a8} + 0x1e2 (0x1524f58b0 0x1524f5bf9) [0x13104e960 - Unity Child Domain]
#15 0x000001524f3bf8 in  UnityEngine.TestTools.BeforeAfterTestCommandBase`1/<ExecuteEnumerable>d__9<T_REF>:MoveNext () {0x7fd8f244b850} + 0xbf8 (0x1524f3000 0x1524f4347) [0x13104e960 - Unity Child Domain]
#16 0x000001524f3b96 in  UnityEngine.TestTools.BeforeAfterTestCommandBase`1/<ExecuteEnumerable>d__9<T_REF>:MoveNext () {0x7fd8f244b850} + 0xb96 (0x1524f3000 0x1524f4347) [0x13104e960 - Unity Child Domain]
#17 0x000001524f2931 in  UnityEngine.TestRunner.NUnitExtensions.Runner.DefaultTestWorkItem/<PerformWork>d__2:MoveNext () {0x7fd948bb5dd8} + 0x8c1 (0x1524f2070 0x1524f2aa6) [0x13104e960 - Unity Child Domain]
#18 0x000001524ebbea in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<RunChildren>d__16:MoveNext () {0x7fd948bb5090} + 0x32a (0x1524eb8c0 0x1524ebdf9) [0x13104e960 - Unity Child Domain]
#19 0x000001524e9b1e in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<PerformWork>d__12:MoveNext () {0x7fd948bb4988} + 0x3be (0x1524e9760 0x1524e9d6b) [0x13104e960 - Unity Child Domain]
#20 0x000001524ebbea in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<RunChildren>d__16:MoveNext () {0x7fd948bb5090} + 0x32a (0x1524eb8c0 0x1524ebdf9) [0x13104e960 - Unity Child Domain]
#21 0x000001524e9b1e in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<PerformWork>d__12:MoveNext () {0x7fd948bb4988} + 0x3be (0x1524e9760 0x1524e9d6b) [0x13104e960 - Unity Child Domain]
#22 0x000001524ebbea in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<RunChildren>d__16:MoveNext () {0x7fd948bb5090} + 0x32a (0x1524eb8c0 0x1524ebdf9) [0x13104e960 - Unity Child Domain]
#23 0x000001524e9b1e in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<PerformWork>d__12:MoveNext () {0x7fd948bb4988} + 0x3be (0x1524e9760 0x1524e9d6b) [0x13104e960 - Unity Child Domain]
#24 0x000001524ebbea in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<RunChildren>d__16:MoveNext () {0x7fd948bb5090} + 0x32a (0x1524eb8c0 0x1524ebdf9) [0x13104e960 - Unity Child Domain]
#25 0x000001524e9b1e in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<PerformWork>d__12:MoveNext () {0x7fd948bb4988} + 0x3be (0x1524e9760 0x1524e9d6b) [0x13104e960 - Unity Child Domain]
#26 0x000001524ebbea in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<RunChildren>d__16:MoveNext () {0x7fd948bb5090} + 0x32a (0x1524eb8c0 0x1524ebdf9) [0x13104e960 - Unity Child Domain]
#27 0x000001524e9b1e in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<PerformWork>d__12:MoveNext () {0x7fd948bb4988} + 0x3be (0x1524e9760 0x1524e9d6b) [0x13104e960 - Unity Child Domain]
#28 0x000001524ebbea in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<RunChildren>d__16:MoveNext () {0x7fd948bb5090} + 0x32a (0x1524eb8c0 0x1524ebdf9) [0x13104e960 - Unity Child Domain]
#29 0x000001524e9b1e in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<PerformWork>d__12:MoveNext () {0x7fd948bb4988} + 0x3be (0x1524e9760 0x1524e9d6b) [0x13104e960 - Unity Child Domain]
#30 0x000001524ebbea in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<RunChildren>d__16:MoveNext () {0x7fd948bb5090} + 0x32a (0x1524eb8c0 0x1524ebdf9) [0x13104e960 - Unity Child Domain]
#31 0x000001524e9b1e in  UnityEngine.TestRunner.NUnitExtensions.Runner.CompositeWorkItem/<PerformWork>d__12:MoveNext () {0x7fd948bb4988} + 0x3be (0x1524e9760 0x1524e9d6b) [0x13104e960 - Unity Child Domain]
#32 0x000001524e943e in  UnityEditor.TestTools.TestRunner.EditModeRunner:MoveNextAndUpdateYieldObject () {0x7fd9310cbaf8} + 0x3e (0x1524e9400 0x1524e9729) [0x13104e960 - Unity Child Domain]
#33 0x0000013090ef0c in mono_jit_runtime_invoke
#34 0x00000130ad1801 in do_runtime_invoke
#35 0x00000130ad175f in mono_runtime_invoke
#36 0x000001059b0237 in scripting_method_invoke(ScriptingMethodPtr, ScriptingObjectPtr, ScriptingArguments&, ScriptingExceptionPtr*, bool)
#37 0x000001059a9d37 in ScriptingInvocation::Invoke(ScriptingExceptionPtr*, bool)
#38 0x00000103e7e607 in Scripting::UnityEditor::EditorApplicationProxy::Internal_CallUpdateFunctions(ScriptingExceptionPtr*)
#39 0x0000010645260d in SceneTracker::Update()
#40 0x000001066de34d in Application::TickTimer()
#41 0x00000108824255 in -[EditorApplication TickTimer]
#42 0x007fff2fb5c3ca in __NSFireTimer
#43 0x007fff2d4859b9 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__
#44 0x007fff2d48551f in __CFRunLoopDoTimer
#45 0x007fff2d485007 in __CFRunLoopDoTimers
#46 0x007fff2d469daa in __CFRunLoopRun
#47 0x007fff2d468ffe in CFRunLoopRunSpecific
#48 0x007fff2c09cabd in RunCurrentEventLoopInMode
#49 0x007fff2c09c7d5 in ReceiveNextEventCommon
#50 0x007fff2c09c579 in _BlockUntilNextEventMatchingListInModeWithFilter
#51 0x007fff2a6e7c99 in _DPSNextEvent
#52 0x007fff2a6e64e0 in -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]
#53 0x007fff2a6d81ee in -[NSApplication run]
#54 0x007fff2a6a9ff6 in NSApplicationMain
#55 0x0000010885dc79 in EditorMain(int, char const**)
#56 0x0000010885de39 in main
#57 0x007fff673b1cc9 in start
[Unity Package Manager (Upm)]
Parent process [1073] was terminated

@unpacklo unpacklo requested a review from joncham June 3, 2020 23:06
@joncham
Copy link
Member

joncham commented Jun 3, 2020

If CI is green I'll merge.

@unpacklo two questions:

  1. Is there a FogBug for this issue for release notes?
  2. Should this be backported to other releases (pre-2020.2)?

@unpacklo
Copy link
Author

unpacklo commented Jun 4, 2020

1. Is there a FogBug for this issue for release notes?

There is no FogBugz issue for this as far as I'm aware. Should I create one?

2. Should this be backported to other releases (pre-2020.2)?

It would be really helpful to have it backported in case we run in to crashes of a similar nature on those other editor versions. Do I need to do some follow up work to make that happen?

@sschoener
Copy link

Great work, Dale!
This should most definitely be backported to 2020.1 and 2019.4.

@joncham joncham merged commit 57d903d into unity-master Jun 7, 2020
@joncham
Copy link
Member

joncham commented Jun 7, 2020

I merged this, and backported to 2020.1 and 2019.4. @unpacklo I think we should make a proper version of the manual test you did in DiagnosticsUtils.bindings.cpp. I can help you do that on the Unity side.

@joncham joncham deleted the stackwalking-handle-null-ip branch June 7, 2020 13:08
@unpacklo
Copy link
Author

@joncham I haven't forgotten about the test, just haven't been able to get to it yet. Tracking this here https://unity3d.atlassian.net/browse/DOTS-2070

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants