Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by StephanK · Mar 19, 2014 at 04:21 PM · exceptionlog

How to get a reliable stack trace in release build?

I am currently investigating some weird behaviour regarding stacktraces of Exceptions in release builds.

I understand that the common way of tracking exceptions is to register your own handler as a callback for the unity logger. However the stacktraces for exceptions that get passed to the handler sometimes are incomplete. If they are incomplete they will contain only the first method that was called, or if any call to Debug.Log was made from the current stack the stacktrace will include all calls up to that point. For example if I do this:

 void Start ()
 {
   ThrowException();
 }
 
 void ThrowException()
 {
   Debug.Log("");
   DoThrowException();
 }
 
 void DoThrowException()
 {
   throw new System.NullReferenceException();
 }

Then the stacktrace will report that the exception was fired from ThrowException. If I remove the Debug.Log it will only contain the Start() method.

But it gets weirder. So for some exceptions i get the correct stacktrace, and for some I don't. For instance throwing an IndexOutOfRangeException does not produce the correct stacktrace, but if I actually try to access an array with an index bigger than its length the resulting runtime exception WILL have the correct stacktrace. NullReferenceExceptions never seem to have the correct stacktrace. This seems really weird to me. Is there any explanation for this? (i assume that unity is somehow tampering with some of the exceptions behind the scenes) If not, is there a better way of getting stacktraces for Exceptions in a release build?

If you want to try it yourself you can just use this script and (un)comment the various cases:

 using UnityEngine;
 using System.Collections;
 
 public class SbsErrorTrackingTest : MonoBehaviour {
 
     void HandleLog (string message, string stackTrace, LogType type)
     {
         Debug.LogException(null);
     }
 
     // Use this for initialization
     void Start () {
         Debug.Log("START");    
         ThrowException();
     }
     
     void ThrowException ()
     {       
         DoThrowException();
     }
 
     void DoThrowException ()
     {   
         // if this line is un-commented the stack trace is probably correct
 //        Debug.Log("");
 
         // doesn't work
         throw new System.NullReferenceException(message);
 
         // doesn't work
         throw new System.IndexOutOfRangeException("test");
 
         // does work
         string[] arr = { "" };
         var s = arr[3];
 
         // doesn't work
         int x = 0;
         int y = 1 / x;
 
         // does work
         System.Collections.Generic.Dictionary<string,string> dict = new System.Collections.Generic.Dictionary<string,string>();
         var s = dict["key"];

         // does not work
         DummyClass dm = new DummyClass();
         var s = dm.GetStringCopy();
     }
 }
 
 public class DummyClass
 {
     string s = null;
 
     public string GetStringCopy ()
     {
         return s.Clone() as string;
     }
 }

I tried this with release builds on Android and iOS.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by hanger · Sep 22, 2014 at 09:27 PM

I originally pointed out the undocumented UnityEngine.StackTraceUtility.ExtractStackTrace, but I've since found that those stack traces are sometimes incomplete or missing. Haven't fully identified in what cases they are incomplete. Generally they are always complete in debug builds, but it gets strange in release builds.

The most robust way to do this is to use System.Diagnostics.StackTrace. This will get you the full stack trace, even in release code, with a few minor exceptions:

  1. It will not give stack traces for inlined method calls.

  2. If compiled in release mode, it will probably not have file and line numbers.

  3. It works on all the platforms I've seen, but there may be an odd platform it doesn't support.

If you use it, make sure to null check everything.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by rschilling · May 17, 2015 at 08:04 PM

Adding a comment here because I'm having the same problem: In my Android plugin for Unity sometimes a RuntimeException is generated (e.g. NullPointerException). The normal behavior and expected for any RuntimeException is that the app crashes and the stacktrace is dumped. After all, RuntimeExceptions exist to tell me there's a developer issue.

But, it looks like the Unity library in Android catches RuntimeExceptions, and instead of dumping the stacktrace of the RuntimeException, I see some odd JNI stacktrace generated by the Unity layer.

I need a way to ensure that RuntimeExceptions are dumped to the console as-is/unmolested and the app crashes when they happen. Is that possible?

Thanks.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image hanger · May 17, 2015 at 09:42 PM 0
Share

This is different enough be a separate question, but I'll answer it here.

Unity is not great for "failing fast." (Games in general are very complex, but have a much lower reliability requirement than say, medical technology.) Unity generally catches, logs and ignores most errors. And its logging facilities aren't great.

That said, if you wrote the Android plugin, you probably used the UnityEngine.AndroidJNI class. I haven't tested anything, but there are methods in there for getting information about the exception in logcat.

If that doesn't work for you, I doubt anything you're doing is performance-critical. You could just wrap all your plugin calls in try-catch blocks. There are probably ways to kill the app from Java itself, but if you need to do it from C#, System.Environment.Exit generally works even when UnityEngine.Application.Quit does not. (I've also seen System.Diagnostics.Process.$$anonymous$$ill used on the current process.)

Also, setting UnityEngine.AndroidJNIHelper.debug to true is a useful (if verbose) debugging aid.

avatar image rschilling · May 18, 2015 at 07:19 PM 0
Share

Putting try/catch blocks throughout the code is a serious step backwards because I would have to do it everywhere, and it's just compensating for the fact that Unity is obscuring perfectly good information in the form of RuntimeException stack traces.

It can turn a five $$anonymous$$ute fix into a five hour fix because I have to hunt for the block of code to put my try/catch block around.

Plain and simple, Unity needs to not catch RuntimeExceptions. I work for a premium support customer of Unity so I'll use that channel to submit a change request.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

23 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

Can someone help me fix my Javascript for Flickering Light? 6 Answers

callback for unhandled exceptions? 3 Answers

Material doesn't have a color property '_Color' 4 Answers

What to do when there is an error at runtime 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges