Blog

Portfolio CV

Flex framework debugging

Published:
2009-01-03 15:36:50
Posted from:
Home
Tags:
Flex,

One of the great features of Flex is that the SDK is open source. Even better is the integration of the Flex Framework source code in Flex Builder. I will now explain how I came to the conclusion that Flex swallowed an exception without even a warning (at least during compile or run time).

A couple of weeks ago I was debugging a weird behavior in GAV Flash. For some reason, a particular event handler was never called, even though the event must have been registered, I thought. The following code snippet is a much simplified version of the class I was debugging (also, I might have renamed a few properties):

package {
  import flash.events.MouseEvent;
  import mx.controls.Button;
  public class MyComponent extends Button {
    private var _factory: IncompleteClass = new ChaChaFactory ();
    private var _theChaCha: String;
    
    private var _doTheChaCha: Boolean = false;
    public function set doTheChaCha(b: Boolean): void {
      if (doTheChaCha)
        removeEventListener(MouseEvent.CLICK, onMouseClick);
      
      _doTheChaCha = b;
      
      if (doTheChaCha) {
        _theChaCha = _factory.getTheChaCha();
        addEventListener(MouseEvent.CLICK, onMouseClick);
      }
    }
    public function get doTheChaCha(): Boolean {
      return _doTheChaCha;
    }
    
    private function onMouseClick(event: MouseEvent): void {
      label = _theChaCha;
    }
  }
}

When the doTheChaCha setter is called with b = true, I would expect the MouseEvent.CLICK-event to be properly registered and thus the event handler onMouseClick to be called when an instance of this button gets clicked.

But, onMouseClick was never called. I fired up the Flex Debugging perspective and put a breakpoint on if (doTheChaCha). As I expected, doTheChaCha was true. I put breakpoints on each of the following two lines and hit "Resume", and the debugger stopped on the following line. What completely upset me was that the next time I hit “Resume”, the debugger did not stop on the addEventListener()-line.

What in the name of the… major bug in AVM2? Yes it is, obviously.

Someone once said that "if you think you’ve found a bug in the {compiler, interpreter, VM}, 99% of the time you’re wrong, so keep looking for errors in your own code. In the remaining 1% of the time, you’re still wrong, so keep looking for errors in your own code." And since I’ve already consumed my 0% bug-in-{compiler, interpreter, VM} quota – I came to the conclusion that I need to keep looking. (couldn't find the original bug report for the bug I found in the mono compiler, so the link is to one I found a couple of days ago).

So, I stepped into getTheChaCha() by putting a breakpoint on the first line. Everything went fine. I also put a breakpoint on the only return-statement in that method. Again, the debugger did not stop. After a few more runs like that I realized that an instance variable in the factory class was null and when it was dereferenced in getTheChaCha(), I would have expected an exception (or Error as it is brilliantly called in ActionScript). Wait a minute! Of course! An exception would make the function not return and execution not to be resumed in the doTheChaCha-setter! I should of course have realized that earlier.

But where did the exception go? Thanks to the open source nature of the Flex Framework I was able to step into the calling code. The setter was called from MXML using a binding to another property. And it turns out that the exception is caught in Binding::wrapFunctionCall(*) and then silently ignored.

A comment in the Binding.as-file states:


// Certain errors are normal when executing a srcFunc or destFunc,
// so we swallow them:
//   Error #1006: Call attempted on an object that is not a function.
//   Error #1009: null has no properties.
//   Error #1010: undefined has no properties.
//   Error #1055: - has no properties.
//   Error #1069: Property - not found on - and there is no default value
// We allow any other errors to be thrown.

Good choice, Flex Team – it only cost me half an afternoon. OK, it was my fault – but a runtime warning would have saved a lot of time. However, I'm glad that I could debug the framework code, so that I could enlightened about what was happening.

Comments

No comments so far. You leave the first:

Name
Email
Website
Text

© 2008 Markus Johnsson