Search Unity

Question How can I attach to a crashing standalone player, see stack trace?

Discussion in 'Windows' started by jasons-novaleaf, Feb 7, 2021.

  1. jasons-novaleaf

    jasons-novaleaf

    Joined:
    Sep 13, 2012
    Posts:
    181
    Unity 2020.2.3, Windows 10, using Visual Studio 2019. When I "Build and run" my app runs for a little while but then crashes:



    Once that green bar fills up it just terminates. I know windows used to offer me to Debug / Retry / Cancel. How can I attach to a crashing app? I know I can modify the build settings to wait for a debugger before starting, but I want to attach to a crash and see what caused it. or at least a stack trace!

    I remember back in the Windows XP days there used to be a "Debug / Retry / Cancel" option when an app crashes. I haven't seen that in a while. is this something I need to configure on windows?

    PS: I found the cause of the crash (my code throwing an exception) but that's even more frustrating because the exception callstack/message are nowhere to be seen.
     
  2. jasons-novaleaf

    jasons-novaleaf

    Joined:
    Sep 13, 2012
    Posts:
    181
    I simplified things down to see if it's some burst/x64/il2cpp setting that makes it non-logging. A basic Mono x86 build does not provide crash information either. I could really use some help here. Having standalone builds unable to log/attach when crashing is extremely troubling.

    Here are my settings.

    a monobehavior with:
    Code (CSharp):
    1.     void Start()
    2.     {
    3.         instance = this;
    4. #if UNITY_STANDALONE && !UNITY_EDITOR
    5.         UnityEngine.Diagnostics.Utils.ForceCrash(UnityEngine.Diagnostics.ForcedCrashCategory.Abort);
    6. #endif
    7.     }
    build settings:

    upload_2021-2-7_17-43-50.png

    Project Settings, Burst disabled:
    upload_2021-2-7_17-44-52.png

    Project Settings, Player: Mono with as much debug enabled as possible:
    upload_2021-2-7_17-46-8.png
     
  3. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    The crash callstack should get printed out to the log. Is it not?

    Yes: https://docs.microsoft.com/en-us/vi...-using-the-just-in-time-debugger?view=vs-2019
     
    jasons-novaleaf likes this.
  4. jasons-novaleaf

    jasons-novaleaf

    Joined:
    Sep 13, 2012
    Posts:
    181
    Thank you for the reply Tautvydas! That link really helped. The regkey edits it mentions made the debugger prompt start appearing. However Not for
    Utils.ForceCrash(ForcedCrashCategory.Abort);
    . I had to switch to something like
    ForcedCrashCategory.MonoAbort
    for the debug attach prompt to show up.

    However, when I attach to the process, I don't get anything useful to debug:

    upload_2021-2-9_0-34-47.png

    Is there any way to debug into my game code at this point?

    Re Crash callstack in log: I actually didn't know about that! I found the docs pointing to where it is for the Player: https://docs.unity3d.com/Manual/LogFiles.html and yep, inside that is a stacktrace with
    0x000001E5E5710873 (Mono JIT Code) [C:\repos\unity\2021-wip\block-spawn-test\Assets\Scripts\_editor_bridge.cs:59] _editor_bridge:crashTest (int)


    So if there isn't a way to effectively attach to the crashing process, at least the crash log will be useful.

    Thank you again for your help.
     
  5. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    In Unity, you have two types of code:

    1) Native code - Unity's runtime and native plugins (generally written in C++);
    2) Managed code - all your C# scripts and managed plugins.

    Each of them has its own debugger: managed debugger and native debugger. Managed debuggers allow debugging C# code, while native debuggers allow debugging native code.

    In general, managed code cannot bring the game down, even if it throws an exception. Therefore the only things that can make the game crash is native code. Since managed code cannot bring down the game, managed debuggers generally cannot capture crashes. That leaves you with native debuggers, and that's what you are using in your screenshot.

    When looking at a native debugger, you will not immediately be able to see your C# code callstack.

    If you're using Mono scripting backend (like in the screenshot you showed), C# code will show up as bare memory addresses, for instance "000001e5e5710af()". If you double click on a frame with "mono-2.0-bdwgc.dll", and load symbols for it, it will enable you to call functions from that DLL from the debugger watch window. If you are in this debugger state, and type in "mono_pmip(0x0001e5e5710af)", it will tell you the managed function name (the hex number passed to the function is taken from the call stack window).

    If you're using IL2CPP scripting backend, you will see the C++ code that was generated from the original C# code, and you should be able to tell which function it is and where in the function you are, since the original C# source code is emitted as C++ comments.
     
  6. jasons-novaleaf

    jasons-novaleaf

    Joined:
    Sep 13, 2012
    Posts:
    181
    I can't load symbols for the "000001e5e5710af()" managed frame. It seems that all symbols are loaded, yet nothing shows up there. Is there a page documenting how to do this? Maybe I need to install some mono sdk?
     
  7. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674