MXMLC WTF (7): Snooping with verbose stacktraces

The -verbose-stacktraces flag to mxmlc is really useful, but it also has a fun, but disturbing, side effect: you can discover how the person who packaged a swc organized their project. If an error is thrown in a context where the call stack includes methods defined by classes inside a swc the getStackTrace method on Error reveals the location of the .as file as it was when it was compiled.

This is the output from getStackTrace for an error thrown in a FlexUnit test case (scroll to the right to see the path to the file):

...
at flexunit.framework::TestCase/flexunit.framework:TestCase::runTestOrAsync()[C:\Documents and Settings\mchamber\My Documents\src\flashplatform\projects\flexunit\trunk\src\actionscript3\flexunit\framework\TestCase.as:275]
...
at flexunit.framework::TestSuiteTestListener/handleTimer()[C:\Documents and Settings\mchamber\My Documents\src\flashplatform\projects\flexunit\trunk\src\actionscript3\flexunit\framework\TestSuiteTestListener.as:81]
at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
at flash.utils::Timer/flash.utils:Timer::tick()

From this we can determine that the swc distribution of FlexUnit (at least the version I use) was compiled by Mike Chambers, who uses Windows and stores his projects in C:\Documents and Settings\mchamber\My Documents\src\flashplatform\projects.

Sorry about the intrusion of your privacy Mike, I hope you don’t mind.

This is from the Flex 3 beta 2 framework:

at mx.binding::Binding/wrapFunctionCall()[E:\dev\flex_3_beta2\sdk\frameworks\projects\framework\src\mx\binding\Binding.as:204]
at mx.binding::Binding/execute()[E:\dev\flex_3_beta2\sdk\frameworks\projects\framework\src\mx\binding\Binding.as:180]
at mx.binding::BindingManager$/executeBindings()[E:\dev\flex_3_beta2\sdk\frameworks\projects\framework\src\mx\binding\BindingManager.as:110]

There’s not as much information there, the code was not anywhere where you can see the username in the path. The only thing we can gather is that it was built on a Windows machine.

The strange thing about this is that you would assume that when they packaged up the Flex framework swc they would compile it with -optimize which should strip such things as file names and line numbers from the code. Since the file names and line numbers are there I assumed that they didn’t, until I tried compiling a swc with -optimize (and, obviously, without -verbose-stacktraces). The file names and line numbers were still there. So I tried compiling with the Flex 2 compc instead, maybe Flex 3 beta 2 doesn’t do -optimize, but no, still the same result.

My conclusion is that regardless of what you do, compc includes file names and line numbers in the code compiled to a swc. mxmlc will include these into the final swf if -verbose-stacktraces is set, even if -optimize is also set. If the file names and line numbers are stripped from the final swf if -verbose-stacktraces is a bit hard to see, I’m can’t run strings because the compression of a swf hides the data, and I don’t know how to uncompress a swf properly. However, there is a noticeable size difference between -optimize -verbose-stacktraces and just -optimize, so it seems like they are stripped. On a side note, -optimize does not seem to have any effect on the size of the swf, the output size is the same wether or not it is specified, even though the docs say that “This optimizer reduces file size” (I haven’t tested this in Flex 2 so it might be just Flex 3 beta 2).

I think this is a real MXMLC WTF. Including so much information in a swc even when -optimize is specified seems weird, especially since there seems to be no way to stop it from being included. The information is useful while debugging things, but there should be a way to strip the information before releasing a swc, because at that point it stops being useful, and it’s also reveals information about the author which he or she may not want to share (sorry again Mike, but I had to show something to prove my point).

That -optimize doesn’t have the effects you would assume it has is perhaps worthy it’s own installment of MXMC WTF.

Try this at home

If you want to try this yourself you need the debug version of Flash Player , compile your code with -verbose-stacktraces and include this snipplet:

try {
  throw new Error();
} catch ( e : Error ) {
  trace(e.getStackTrace());
}

You will find a nice stack trace in your flashlog.txt. You need to put the snipplet somewhere where the call stack includes methods from the swc you want to inspect. This means that you place it in a method which you know is called by (or is called by something that is called by) a class that came from the swc.

2 Responses to “MXMLC WTF (7): Snooping with verbose stacktraces”

  1. Jeff Carnes Says:

    It sounds like you did your testing with compc and not mxmlc (which has different defaults). If that’s the case, compc defaults “debug” to true (mxmlc does not). As per the docs:

    “If you set this option to true, Flex also sets the verbose-stacktraces option to true”

    Try setting “debug” to false and you’ll notice that the stack traces are a bit less revealing now and the file size will be about 33% smaller in part because it’s not including line numbers and file names.

    “optimize” also defaults to true, so compiling with optimize=true is no different than compiling without specifying optimize. The docs don’t state it, but I believe optimize is also affected by debug so with debug defaulting to true it might force optimize to false (even if you specify it). If I remember correctly, taking a debug SWF and running it through Adobe’s optimizer app in the SDK results in a SWF identical to debug=false, optimize=true which makes me believe debug and optimize may be mutually exclusive.

  2. tom Says:

    optimize is enabled per default. you have to disable it to see a difference.

Leave a Reply