The getStackTrace Super Bug

By | August 4, 2009

If you happen to be hitting an issue where an application runs fine in the debug version of the Flash player but hangs up in the normal version, read on. This could be your problem.

I’ve made good use of a tip I picked up from McCune on generating a stacktrace in my logging statements so that I can not only see the method that was called but also from where it was being called.

In this particular case, I was trying to determine why my component was getting its maxWidth value changed at some point in the lifecycle. I overrode the maxWidth accessor using this snippet:

override public function set maxWidth(value:Number):void {
    trace("set maxWidth = " + value);
    var stackTrace:String = new Error().getStackTrace();
    var callStackString:String = stackTrace.substring(stackTrace.indexOf("n"), 500);
    trace("---- call stack: " + callStackString + "... n");
    super.maxWidth = value;
}

The result is a nice log statement showing me what led up to the call:

set maxWidth = 757
---- call stack:
at BaseContainer/set maxWidth()[/Users/white/dev/workspace/FlexContainerTesting/src/BaseContainer.as:45]
at layouts::HorizontalFlowLayout/updateDisplayList()[/Users/white/dev/workspace/FlexContainerTesting/src/layouts/HorizontalFlowLayout.as:96]
at BaseContainer/updateDisplayList()[/Users/white/dev/workspace/FlexContainerTesting/src/BaseContainer.as:85]
at mx.core::UIComponent/validateDisplayList()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreUICompone...

Now this works great until you run into the issue that I did the other day. According to the Doug’s posted (at the bottom) and according to the docs, there is a gotcha that I wish I had paid attention to before hitting this problem. Doug’s post mentions that this only works in the debug player, but to get more specific, the docs point out that it returns a null value:

getStackTrace(): Returns the call stack for an error as a string at the time of the error's construction (for the debugger version of Flash Player and the AIR Debug Launcher (ADL) only; returns null if not using the debugger version of Flash Player or the ADL.

So this means that the stackTrace variable will be valid when I’m using the debug version of the Flash player. But in the normal player, the third line will throw a nullpointer exception. However, in my application, these null pointers were getting ‘eaten’ by the application and never being shown.

The result? The perfect bug. One that hides when you look for it. Because the getStackTrace() method of the Error object returns a valid object in the debug version of the Flash player and a null in the regular version, it was a real pain to figure out why my app worked great on my dev box (with the debug player) and would never finish loading in the regular version of the flash player. The answer, of course, would be to have runtime errors correctly bubble up to an error dialog in the application so non-debug flash players could indicate that something is wrong. Alternatively, something like this would also work:

override public function set maxWidth(value:Number):void {
    trace("set maxWidth = " + value);
    var stackTrace:String = new Error().getStackTrace();
    if (stackTrace != null) {
        var methodNameString:String = stackTrace.substring(stackTrace.indexOf("n"), 500);
        trace("----> call stack method: " + methodNameString + "... n");
    }
    super.maxWidth = value;
}

Just wanted to post this in case anyone else ever got bitten by the same issue.

5 thoughts on “The getStackTrace Super Bug

  1. LAlex

    I just got this one, with a bug in the computer of my client but not mine (as a dev, I always use a Debug player).

    I spent so much time telling the client: “If the app freezes, please install the Debug player, then send the error to me”… And then, the app worked!

    This caused weeks of misunderstanding…

    I feel less alone thanks to your post! ;oP

    Reply
  2. Joshua Jung

    Just ran into this one myself… quite a nightmare. We discovered it right before a giant demo and were trying to test.

    Thanks for the post!

    Reply
  3. Chris

    Wow, a true Heisenbug. Thanks for the clarifying post, took me almost 3 days to track this one down..

    Reply
  4. Gael

    Just found this after having spent one day to understand why my app was not working anymore on release.
    For information, the symptom is the same on IOS and Android …

    Reply
  5. Nico Limpika

    Thank you so much.
    “For Flash Player 11.4 and earlier and AIR 3.4 and earlier, stack traces are only available when code is running in the debugger version of Flash Player or the AIR Debug Launcher (ADL). In non-debugger versions of those runtimes, calling this method returns null.” what a gotcha. Why do they even do this. Cardinal rule is the debugger should run exactly the same as the production player. What gets me is this worked fine in flash 9. Maybe they did it for security reasons at first since it was returning line numbers and files and then later worked it to be this.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *