Table of Contents

OFD : Open Flash Debugger

There is one very useful tool for the Flash developer which is the Flash Debugger. If you have never used it, try pressing the Shift+Ctrl+Enter shortcut from Flash IDE, and you will access it. You can then set breakpoints, where the program will stop, and check the values or the current variables. This is a very powerful tool, but the Flash IDE version is not very handy and have very poor user interface.

Please Note that you can also do Remote debugging, and that is very interesting. The SWF can be put on the internet and will prompt to connect on some host when opened. Usualy, it will connect to the localy running Flash IDE Debugger, but it could as well connect to OFD : The Open Flash Debugger. Read this document for using Remote Debugging (you need Flash Debug Player installed).

This document is trying to get as much informations as possible about the way the Flash Debugger works and to create an open source version of it, with better user interface, more features if possible, and multiplatform support.

Thank you for any contribution

Important ! It is important to know that in order to do remote debugging you need to run the Debug version of the Flash Player which seems not to be available for Linux and cannot be redistributed (see the Player license FAQ). Note: The debug player can be downloaded from Macromedia's website.

The SWD File Format

When published in Debug Mode (using Ctrl+Shift+Enter) the Flash IDE is also creating a .SWD File that contains very useful informations. In fact, this is the only information that will be loaded on the debugger side, since the SWF is running remotely in the Flash Player.

The SWD File Format makes the Debugger able to display the current place of execution directly in the ActionScript sources, and not in the bytecode. For that, it stores the whole sources that have been compiled as well as some indexes that are matching position in the bytecode and position in the source. Here’s a description of the file format (binary) :

Header := 'FWD' + Version
Version := '\007' on Flash 7 IDE
Body := Tag*
Tag := Tag-Identifier + Tag-Data
Tag-Identifier := 32-bit LowEndian integer
Tag-Data := depends on the Tag-Identifier, see Below

Here’s a list of Tags Data :

Tag 0 := File-Index + Unknown-Index + File-Name + File-Source
Tag 1 := File-Index + LineNumber-In-Source + Index-In-Bytecode
Tag 3 := 16 bytes , TimeStamp (unique hash)

All indexes are 32-bit lowendian integers. For each file you have a Tag 0 , containing the filename (ending with ‘\000’) and the filesource (ending with ‘\000’) and several Tag 1 (one per line in the soure) that make correspond the line in the source with the position in the bytecode.

The remaining question is to understand how the bytecode position maps to the SWF. It is not useful for the Debugger since it doesn’t need it but it is useful for MTASC for example to be able to produce a valid SWD file.

In the SWF

When compiled into Debug mode, a Tag 0x3F is added to the SWF.

Communications

The Flash IDE is opening the port 7935 and listening on it when the “Enable Remote Debugging” option is checked into the Debugger Preferences. The Debug Flash Player connect on that port on the given host (after it pops the host choice).

Protocol

The protocol the Debugger and the Flash Player are talking is pretty easy :

PACKET := LEN + ID + DATA
LEN := 32-bit integer , size of the data
ID := 32-bit integer , id of the packet
DATA := size is LEN, contents depends on the ID

Informations about the formats

Protocol negociation

Upon connection, the Player is sending VERSION and two VARIABLE packets (one with key “movie”, one with key “password”), which is enough for the Debugger to display the password dialog. Then several init packets are following (including SWD packets... before password validation).

Objects Data

The Player will send automaticaly some objects values, or can also send when requested by debugger. Objects are referenced by a 32-bit ADDRESS. They is NAMED objects and ANONYMOUS objects. Both have an address, but NAMED objects are _root (NAME = “/”) and _global for example.

An object is created using NAMEDOBJ or OBJECT packets. Fields of the objects are then set using FIELD or FIELD2 packets using AMF format. Objects can then reference each other using their ADDRESS and the whole object graph is sent in several packets.

Theses datas can be parsed by the Debugger to display the value of different properties.

Player Packet list

Packet Name ID LEN Documentation
VERSION 1A 4 i7 , major version of the player
VARIABLE 0C ~ KEY (0 ended string) , then VALUE (0 ended string)
SWDCOUNT 14 4 a 32-bit integer specifying the number of SWD packets following
SWD 0E ~ FID \000 \000 i1 FILENAME (0 ended string) SOURCE (0 ended string)
OBJECT 03 4 ADDRESS : create an object
NAMEDOBJ 0D ~ ADDRESS , then a NAME (0 ended string) : create a named object
FIELD 0A ~ ADDRESS of the object, then a field NAME (0 ended string) then the field value (AMF format)
FIELD2 1C ~ similar to FIELD
PROPERTY 01 ~ ADDRESS of the object, then 16-bits PROPERTY index, then prop value (0 ended string)
BREAKPOINT-LIST 13 ~ COUNT (number of breakpoints following), [FID (16-bit), LINE(16-bit)] : Sends a list of breakpoints to the debbuger.
TRACE 05 ~ MSG : Trace message (null-terminated ascii string)
BREAK 11 0 Execution stopped due to a breakpoint. You should expect a BREAK-HIT tag following it.
BREAK-HIT 10 9 FID (16-bit), LINE (16-bits), ADDRESS (address of the object containing the code), NAME (function name as a null-terminated ascii string) : breakpoint information.
UNKNOWN 0F 0 maybe “done” or “stopped”
UNKNOWN 00 8 some data
REMOVE-OBJECT 04 4 ADDRESS of the object. : This possibly tells to the debbuger that an object has been removed from the stage.
UNKNOWN 12 ? ?
UNKNOWN 1B ? ?
UNKNOWN 0B ? ?

Debugger Packet list

Packet Name ID LEN Documentation
QUERY 0E 4 query the given object ADDRESS
BREAK 13 8 FID , LINE : request to put a breakpoint
REMOVE 12 12 i1 , FID , LINE : remove a breakpoint
CLEAR 13 0 clear all breakpoints
STOP 0D 0 stop debugging (before closing)
PLAY 0F 0 play

Properties List (for packet 0×01)

PROPERTY Name
0 _x
1 _y
2 _xscale
3 _yscale
4 _currentframe
5 _totalframes
6 _alpha
7 _visible
8 _width
9 _height
10 _rotation
11 _target
12 _framesloaded
13 _name
14 _droptarget
15 _url
16 _highquality
17 _focusrect
18 _soundbuftime
19 _quality
20 _xmouse
21 _ymouse