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. Usually, it will connect to the locally 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 Adobe'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.

Tag ID Meaning Content
0 Source file dd fileIndex, dd unknownIndex, sz fileName, sz sourceCode
1 Line-to-offset mapping dd fileIndex, dd lineNumber, dd offsetInSWF
2 Set breakpoint dw fileIndex, dw lineNumber
3 SWD ID 16 bytes, timestamp (unique hash)
  • dw: 16-bit word
  • dd: 32-bit dword
  • sz: zero-terminated UTF8 string

For each file you have a Tag 0 containing the filename and its corresponding source code, and several Tag 1 (one per line in the soure) that map the line in the source to the offset in the (decompressed) SWF.

In the SWF

When compiled into Debug mode, two tags are added to the SWF:

Tag ID Content
0x40 (ProtectDebug2) 2 ignored bytes, zero-terminated string containing debugging password hash
0x3F (DebugID) 16 bytes: debug ID (matches the content of tag 3 in the .swd)

If at least one of these tags is present, the player will request the browser to download the .swd file. If the .swd file exists, the browser downloads it and the player parses it. Only then, and if a debug password is set, does the player connect to the debugger.

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

  • Each .swf that is eligible for being debugged gets assigned a runtime, 0-based index which we will call swfIndex
  • The source files contained in the different .swd's (we will call them SWD file entries) are assigned a runtime, 1-based global ID which we will call fileID. This is not one of the file indexes contained in the .swd - those are local ID's (you can request the local ID → global ID mapping by sending a “get swf info” message). The global ID's are commonly used together with line numbers, e.g. for setting breakpoints.
  • Each object has a 32-bit ID which is called its ADDRESS

In the tables below, the following types are used:

  • db: byte
  • dw: word (16-bit), little endian
  • dd: dword (32-bit), little endian
  • sz: zero-terminated UTF8 string
  • amf: just like the AMF used by remoting, but with a few important differences:
    • In remoting, there is a type byte followed by the contents. Here, the type is a 16-bit word and is followed by a 32-bit flags dword; only after that do the contents follow.
    • Strings (type ID 2) are not in the usual 2-bytes length + content format. Instead, they are pure zero-terminated strings. Long strings (type ID 12) are unused.
    • For AMF objects (type ID 3), the content consists solely of the object's ADDRESS. The referenced object may or may not yet have been sent.

Protocol negociation

Upon connection, the Player is sending VERSION and two MOVIEATTR 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 CREATEOBJECT or PLACEOBJECT packets. Fields of the objects are then set using SETFIELD or SETFIELD2 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 to debugger messages

ID Name Content
00 menu state dd ?, dd ?
01 property dd addr, dw propertyIndex, sz value
02 exit
03 create anonymous object dd addr
04 remove object dd addr
05 trace sz msg
06 target error sz error
07 recursion depth error
08 with error
09 proto limit error
0A set field dd addr, sz name, amf value
0B delete field dd addr, sz name
0C movie attribute sz name, sz value
0D place object dd addr, sz name
0E SWD file entry dd fileID, dd unknownIndex, sz name, sz sourceCode, dd swfIndex
0F ask breakpoints
10 breakpoint hit dw fileID, dw line, dd addr, sz funcName
11 break
12 set local vars dd addr address of an object containing the named local variables of the current scope
13 breakpoints dd count, (dw fileID, dw line)[count]
14 num swd file entries dd num, dd swfIndex
15 remove SWD file entry dd fileID
16 remove breakpoint dd count, (dw fileID, dw line)[count]
17 not synced Sent if the debug ID in the .swf does not match the SWD ID in the .swd
18 URL open error sz error
19 process tag
1A version dd majorVersion, db 4
1B breakpoint hit ex dw fileID, dw line, dd callDepth, (dw fileID, dw line, dd thisAddr, sz callstackentry)[callDepth]
1C set field 2 addr, sz name, amf value
1D squelch dd enabled
1E get field dd addr, sz name, amf value, (sz memberName, amf memberValue)*
1F function frame dd callDepth, #if(callDepth > -1) dd numRegs, reg registers[numRegs] #endif, dd addr, amf value, (sz childName, amf childValue)* contains two meta children that serve as start markers: one named “$arguments” and one named “$scopechain”
20 debugger option sz name, sz value
21 watch dw success, dw oldFlags, dw oldTag, dw flags, dw tag, dw addr, sz name
22 SWF image .swf file contents
23 SWD image .swd file contents
24 exception dd 0, sz exception
25 stack underflow dd 0
26 divide by 0 dd 0
27 script stuck
28 suspend reason dw reason, dw swfIndex, dd offset, dd prevLineOffset, dd nextLineOffset
29 actions dw swfIndex, dw reserved, dd offset, dd size, db data[size] deprecated/not implemented, will be empty
2A SWF info dw swfcount, (dd swfIndex, dd addr, #if(addr) db debugComing, db vmVersion, dw reserved, dd swfSize, dd swdSize, dd numSWDs, dd numLines, dd numBreakpoints, dd port, sz path, sz url, sz host, dd swdfilecount, (dd swdLocalIndex, dd swdFileID)[swdfilecount] #endif)[swfcount] addr == 0 means swf was unloaded
2B constant pool dw swfIndex, dd count, (dd id, sz name, amf value)[count]
2C console error sz error
2D function info dd fileID, dd count, (dd offset, dd firstLine, dd lastLine, sz name)[count]
2E ?
2F ?
30 ?
31 ?
32 ?
33 ?
34 ?
35 ?
36 ?
37 watch 2 dw success, dw oldFlags, dw oldTag, dw flags, dw tag, dd addr, sz name

Debugger to player messages

ID Name Content
00 zoom in
01 zoom out
02 zoom 100%
03 home
04 set quality sz quality=“LOW”/“MEDIUM”/“HIGH”/“AUTOLOW”/“AUTOMEDIUM”/“AUTOHIGH”/“BEST”
05 play
06 loop
07 rewind
08 forward
09 back
0A print
0B set field dd addr, sz name, sz type=“string”/“number”/“boolean”/“null”, sz value For “number”, value can be “Infinity”, ”-Infinity” or “NaN”
0C set property dd addr, dw propIndex, sz type=“string”/“number”/“boolean”/“null”, sz value For “number”, value can be “Infinity”, ”-Infinity” or “NaN”
0D end debugging session
0E request properties dd addr
0F continue
10 suspend
11 set breakpoint dd ignored, dw fileID, dw line
12 clear breakpoint dd ignored, dw fileID, dw line
13 clear all breakpoints
14 step over
15 step into
16 step out
17 processed tag
18 set squelch dd squelchOn
19 get field dd addr, sz name [, dd flags] flags: 1=fire getter, 2=also get children, 4=? (always set)
1A get function frame dd calldepth
1B get debugger option sz name
1C set debugger option sz name, sz value
1D add watch dw addr, sz name, dw flags, dw tag
1E remove watch dw addr, sz name
1F step continue
20 get SWF file content dw swfIndex
21 get SWD file content dw swfIndex
22 get field which invokes getter dd addr, sz name [, dd flags] flags: 1=fire getter, 2=also get children, 4=? (always set)
23 get suspend reason
24 get actions dd swfIndex, dw reserved, dd offset, dd size deprecated/not implemented, sends back an empty “actions” reply
25 set actions dd swfIndex, dw reserved, dd offset, dd size, db data[size] deprecated/not implemented, sends back an empty “actions” reply
26 get SWF info dw swfIndex, dw 0
27 get constant pool dw swfIndex
28 get function info dd swdID, dd lineNum lineNum =< 0: all functions
29 ?
2A ?
2B ?
2C ?
2D ?
2E ?
2F ?
30 ?
31 add watch 2 dd addr, sz name, dw flags, dw tag flags: 1=read, 2=write, 3=both. tag: for identification, choose one
32 remove watch 2 dd addr, sz name
33 ?
34 ?

Properties List (for packet 0x01 sent by player)

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

Debugger options

Option name Possible values
astrace number
break_on_fault “on”/“off”
console_errors “on”/“off”
disable_script_stuck “on”/“off”
disable_script_stuck_dialog “on”/“off”
enumerate_override “on”/“off”
getter_timeout number
invoke_setters “on”/“off”
notify_on_failure “on”/“off”
setter_timeout “on”/“off”
script_timeout number
swf_load_messages “on”/“off”
verbose “on”/“off”

Suspend reasons

ID Meaning
0 unknown
1 hit breakpoint
2 hit watchpoint
3 exception
4 suspend request
5 finished stepping
6 halt opcode
7 loaded into player

Discussion

parksh, 2011/03/21 20:10
as
Mem's, 2011/08/10 05:11
There are usefull informations in OS Flex SDK.

For Flash Debugger Protocol:
http://opensource.adobe.com/svn/opensource/flex/sdk/trunk/modules/debugger/src/java/flash/tools/debugger/concrete/DMessage.java
http://opensource.adobe.com/svn/opensource/flex/sdk/trunk/modules/debugger/src/java/flash/tools/debugger/concrete/DProtocol.java

For SWD file:
http://opensource.adobe.com/svn/opensource/flex/sdk/trunk/modules/swfutils/src/java/flash/swf/DebugEncoder.java
http://opensource.adobe.com/svn/opensource/flex/sdk/trunk/modules/swfutils/src/java/flash/swf/DebugDecoder.java
Enter your comment
 
 
ofd.txt · Last modified: 2011/03/22 08:21 by 93.191.34.130
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki