Debuggers

CodeWarrior Magic/MPW includes two complete debuggers that you can use to help debug your packages. This section introduces the debuggers and describes how to use them. To use the debuggers, you should be able to read and understand Motorola 68K assembly language code and you should be familiar with Magic Cap's object runtime.


About Magic Cap Debuggers

CodeWarrior Magic/MPW includes two debuggers: MacsBug, an enhanced version of the Macintosh debugger provided by Apple, and Telebug, a remote debugger developed by General Magic. You can use MacsBug to debug packages running on Magic Cap Simulator. Telebug can debug Magic Cap packages running on personal communicators.

When you install CodeWarrior Magic/MPW, you have everything you need to use MacsBug. To use Telebug, you must also have a communicator and a Telebug Interface Box, available at additional cost. Contact your CodeWarrior Magic/MPW supplier for more information about getting these items.

Although Magic Cap Simulator is very much like communicator-based versions of Magic Cap, there are some insurmountable differences, such as low-level details of communication hardware and power management. In addition, when your package is relatively stable, you should test it on communicators that contain real data, as most users keep dozens of name cards, telecards, appointments, and other items in memory. For these reasons, you should always test your packages on communicators before distributing them, and you may need Telebug if you find problems that only appear on communicators.


MacsBug and Telebug

MacsBug and Telebug provide many similar features. Both debuggers let you examine objects, code, clusters, contexts, and memory. Both let you set breakpoints, view the stack, and single-step through code.

As you create and debug your packages, you should do as much of your development as possible with the simulator and MacsBug. The simulator provides an implementation of Magic Cap that is very much like that in communicators, and the turnaround time for building and running packages is shorter. Because the simulator is a special debug version of Magic Cap, it provides debugging features not present in communicators, such as assertions and method dispatch verification. In addition, because of the relative maturity of the tools, MacsBug provides a more stable debugging environment in general than does Telebug.

You should use Telebug when your package works well on the simulator but encounters problems when running on communicators. You'll also use Telebug more if you exploit specific hardware features of communicators that aren't available on the simulator, such as custom PC card development.

WARNING: You should always back up important data in your communicator before using it for package development. There are many ways you can damage data when developing packages. You should always be prepared to lose the contents of a communicator you're using to develop and debug packages.


MacsBug

This section describes the enhanced version of MacsBug supplied with CodeWarrior Magic/MPW. The basic features available in all versions of MacsBug are not explained here. You can find out about MacsBug's features by using MacsBug's online help, which you can see by typing ? in MacsBug. You can get complete information about MacsBug in the MacsBug Reference and Debugging Guide (order ISBN 0-201-56767-9).

About MacsBug

MacsBug is Apple's object code debugger for Macintosh. CodeWarrior Magic/MPW includes an enhanced version of MacsBug specially designed for use with Magic Cap Simulator. This version of MacsBug includes a patch that improves the appearance of disassembled Magic Cap code by displaying Magic Cap operation calls symbolically. CodeWarrior Magic/MPW also includes external MacsBug commands that provide additional features for debugging Magic Cap packages.

You usually enter MacsBug by pressing the interrupt switch on the Macintosh. MacsBug also takes control when serious errors occur in Magic Cap Simulator and other Macintosh applications, or when code is executed that is designed to invoke the debugger. The simulator provides programming interfaces to macros that cause it to enter the debugger. For information on these interfaces, see this book's Assertions and Macros for Debugging sections.

When you install CodeWarrior Magic/MPW, the installation process puts two files, MacsBug and Debugger Prefs, in your system file. If you already have a Debugger Prefs file, CodeWarrior Magic/MPW adds its commands to your existing copy.

When you build your package, CodeWarrior Magic/MPW includes your package's symbols in your object code if you have the debug build menu item turned on. The simulator includes its symbols in its object code, as you can see when using MacsBug.

MacsBug Tour

This section introduces the Magic Cap extensions to MacsBug by demonstrating how they work on a running package. The MacsBug output in this section was generated by running the simulator with the HelloWorld sample. In this section, monospaced lines that appear in bold are commands you type to MacsBug, while plain monospaced lines are MacsBug output.

To begin using MacsBug, run CodeWarrior Magic/MPW and select HelloWorld as the current directory. Choose Macintosh Build Target from the Magic menu. Build HelloWorld and start Magic Cap. When Magic Cap appears, press the interrupt switch on the Macintosh to enter MacsBug.

WARNING: The left-center of MacsBug's screen indicates the name of the current Macintosh application under the heading CurApName. When you enter MacsBug to debug your package, be sure the current application is Magic Cap Simulator or you won't be able to debug. If the current application is not the simulator, type command-G to resume execution, make sure the simulator is the front most window, and enter MacsBug again.

You can use any mix of upper and lower case when typing commands. Neither MacsBug commands nor Magic Cap symbols are case sensitive.

NOTE: If you're reading this online, you can use your documentation reader to enlarge the MacsBug output in this section.

You can set a breakpoint to get MacsBug to take control whenever a particular function is executed. To tell MacsBug to take control whenever Greeter_Draw is executed, type

br Greeter_Draw
 Break at 00D316DC (Greeter_Draw) every time
The g command exits MacsBug and resumes execution. Next, go to HelloWorld's door in the hallway and enter. When Magic Cap is about to draw the greeter (the box), MacsBug takes control:
Breakpoint at 00AA319C Greeter_Draw+051C

You can also set breakpoints in Magic Cap itself. To find out more about the data and return addresses on the stack, use the sc (stack crawl) command:

sc
  A6 Link  CallerPC Caller                  Params
  00A442F8 006FC1D8 CallMain+0074           D400 0019 0000 0000 0000 0000 0000 0000 0000 
  00A442CA 006F8B54 UserActor_Main+02B0     D400 0019 0000 0000 BADD BADD BADD BADD BADD 
  00A44282 008510BE Viewable_RedrawNow+0114 BADD BADD BADD BADD BADD BADD BADD BADD D400 
  00A44150 0084FC1A Viewable_RedrawNoƒ+03BC EC00 0018 8400 0422 0000 0000 BADD BA01 8400 
  00A440EC 0084F6E2 Viewable_DrawDirty+0542 00A4 4180 00A4 426E 0000 0001 8400 04F9 EC00 
  00A44078 0084F692 Viewable_DrawDirty+04F2 00A4 4180 00A4 4140 0000 0000 A400 0002 8400 
  00A44078 00AA319C Greeter_Draw+0000       B400 000E EC00 0018 D400 00D6 0000 0001 0000
The Caller column shows the names of the functions that have return addresses on the stack, with the most recently executed function on the bottom. The values listed under Params show the contents of the stack (not including the return address) when each function was called.

For methods, the first parameter on the stack is an object ID for the responder, also called the self parameter. Find out more about this object using the getobj (get object) command:

getobj B400000E
 $00A6E27C Greeter                 $B400000E  size:$000038   #:$0000000E  flags:´´´NV´´´´´
  Name: Hello World
This command gives the object's class (Greeter), name (Hello World), and location in memory ($00A6E27C). When you enter MacsBug via a breakpoint at the start of a method, the responder's object ID is located 4 bytes from the top of the stack. MacsBug defines a command to show the object at this location on the stack:
osp4
 $00A6E27C Greeter                 $B400000E  size:$000038   #:$0000000E  flags:´´´NV´´´´´
  Name: Hello World
The osp4 command is shorthand for "call getobj for the object ID at 4 bytes off the stack pointer." You can see the object and all its fields with the do (display object) command. As with getobj, do defines a shorthand, dosp4, for showing the responder when Magic Cap has stopped at the beginning of a method:
dosp4
 $00A6E27C Greeter                 $B400000E  size:$000038   #:$0000000E  flags:´´´NV´´´´´
  Name: Hello World
  Displaying Greeter at 00A6E27C
  o       SingleLinkable
  o       00A6E27C  next                00000000 
  o     Linkable
  o       HasIndexing
  o     00A6E280  previous              00000000 
  o   Viewable
  o   00A6E284  superview               B000000C 
  o   00A6E288  subview                 00000000 
  o   00A6E28C  relativeOrigin          00 00 00 00 FF FF F2 00 
  o   00A6E294  contentSize             00 00 5A 00 00 00 5A 00 
  o   00A6E29C  viewFlags               7818D220 
  o   00A6E2A0  labelStyle              83078001 
  o   00A6E2A4  color                   FFFFFFFF 
  o   00A6E2A8  altColor                FF000000 
  o   00A6E2AC  shadow                  00000000 
  o   00A6E2B0  sound                   83042013 
  o Greeter
When MacsBug takes control at the start of a method, as in the current example, the responder (the self parameter) is 4 bytes from the top of the stack. As the method's code executes, the stack changes, and the responder is no longer 4 bytes from the top of the stack. However, you can always get the responder's object ID while a method is executing by using the following expression:
@(a6+8)
For example, if a method is executing, you can type do @(A6+8) to see the responder and all its fields. This works because every method sets up register A6 to point to its parameters.

The do command (and the related dosp4 shown above) displays objects with the names of their fields. You can use the dm (display memory) command to show the raw data of objects, without using field information. When you use dm, you specify the starting address for the memory to be displayed. MacsBug defines the period (.) as a variable that holds the last address used by a command. So, after using dosp4 to show the object and its fields, you can see the object's raw data:

dm .
 Displaying memory from .
  00A6E27C  0000 0000 0000 0000  B000 000C 0000 0000  ´´´´´´´´´´´´´´´´
  00A6E28C  0000 0000 FFFF F200  0000 5A00 0000 5A00  ´´´´´´´´´´Z´´´Z´
  00A6E29C  7818 D220 8307 8001  FFFF FFFF FF00 0000  x´´ ´´´´´´´´´´´´
  00A6E2AC  0000 0000 8304 2013  8000 0578 0000 0000  ´´´´´´ ´´´´x´´´´
  00A6E2BC  0000 0000 0000 0020  0000 C285 FFFF FFFF  ´´´´´´´ ´´´´´´´´
  00A6E2CC  0000 C286 0494 5AF8  B000 0001 B000 0002  ´´´´´´Z´´´´´´´´´
You can use the information provided by these commands to learn more about the package and its objects. The dosp4 display above shows the other objects that the responder (the Greeter object) refers to, including its superview, which has object ID $B000000C. You can use do to see the superview:
do B000000C
 $00A6E21C Scene                   $B000000C  size:$000054   #:$0000000C  flags:´´´NV´´´´´
  Name: HelloWorld
  Displaying Scene at 00A6E21C
  o           SingleLinkable
  o           00A6E21C  next            800002ED 
  o         Linkable
  o           HasIndexing
  o         00A6E220  previous          00000000 
  o       Viewable
  o       00A6E224  superview           80000422 
  o       00A6E228  subview             B000000E 
  o       00A6E22C  relativeOrigin      00 00 00 00 FF FF F8 00 
  o       00A6E234  contentSize         00 01 E0 00 00 01 00 00 
  o       00A6E23C  viewFlags           11005220 
  o       00A6E240  labelStyle          83078001 
  o       00A6E244  color               FF555555 
  o       00A6E248  altColor            FF000000 
  o       00A6E24C  shadow              00000000 
  o       00A6E250  sound               00000000 
  o     Box
  o       HasBorder
  o       00A6E254  border              00000000 
  o   Panel
  o Scene
  o 00A6E258  sceneFlags                00000000 
  o 00A6E25C  stepBackScene             800004F9 
  o 00A6E260  stepBackSpot              800024C4 
  o 00A6E264  image                     00000000 
  o 00A6E268  additions                 00000000 
  o 00A6E26C  screen                    00000000 

This display shows that the greeter's superview is a scene, also named HelloWorld. You can also find this out by using the Inspector in Magic Cap.

You can use the information from the last do command to see the scene's superview, which is the screen object. Use the object ID from the scene's superview field:

do 80000422
 $00AFDBC8 Screen                  $80000422  size:$000044   #:$00000422  flags:´´´´V´´´´´
  Displaying Screen at 00AFDBC8
  o           SingleLinkable
  o           00AFDBC8  next            00000000 
  o         Linkable
  o           HasIndexing
  o         00AFDBCC  previous          00000000 
  o       Viewable
  o       00AFDBD0  superview           00000000 
  o       00AFDBD4  subview             820024C5 
  o       00AFDBD8  relativeOrigin      00 00 F0 00 00 00 A0 00 
  o       00AFDBE0  contentSize         00 01 E0 00 00 01 40 00 
  o       00AFDBE8  viewFlags           11005020 
  o       00AFDBEC  labelStyle          00000000 
  o       00AFDBF0  color               00000000 
  o       00AFDBF4  altColor            00000000 
  o       00AFDBF8  shadow              00000000 
  o       00AFDBFC  sound               00000000 
  o     Box
  o       HasBorder
  o       00AFDC00  border              00000000 
  o   Panel
  o Screen
  o 00AFDC04  screenFlags               E0000280 
  o 00AFDC08  redrawCount               0000006A 
  
Note that the screen object's ID is $80000422, while the greeter's is $B400000E. The first five bits of an object ID indicate the cluster that contains that object. The screen object is in cluster 8, the system persistent cluster, while the greeter is in cluster B, the package persistent cluster. For more information about object IDs and clusters, see the Object Runtime chapter of Magic Cap Concepts.

Now go back to the scene object shown above and display the viewable next to it, using the object ID in the scene's next field:

do 800002ED
 $00AFDFF4 NameBar                 $800002ED  size:$0000B4   #:$000002ED  flags:´´´´V´´´´´
  Displaying NameBar at 00AFDFF4
  o             SingleLinkable
  o             00AFDFF4  next          80000426 
  o           Linkable
  o             HasIndexing
  o           00AFDFF8  previous        820024C5 
  o         Viewable
  o         00AFDFFC  superview         80000422 
  o         00AFE000  subview           800002F0 
  o         00AFE004  relativeOrigin    00 00 00 00 FF FF 6B 80 
  o         00AFE00C  contentSize       00 01 E0 00 00 00 17 00 
  o         00AFE014  viewFlags         11004020 
  o         00AFE018  labelStyle        8307800D 
  o         00AFE01C  color             FF000000 
  o         00AFE020  altColor          FFFFFFFF 
  o         00AFE024  shadow            00000000 
  o         00AFE028  sound             00000000 
  o       Box
  o         HasBorder
  o         00AFE02C  border            83046001 
  o     Panel
  o   Bar
  o NameBar
  o 00AFE030  titleBarFlags             0700000D 
  o 00AFE034  pageArrow                 8300C24D 
  o 00AFE038  captionTextStyle          83078001 
  o 00AFE03C  lastDrawDate              0000C286 
  o 00AFE040  lastDrawTime              02DD5A88 
  o 00AFE044  lastLevel                 00000000 
  o 00AFE048  lastCharging              FFFFFFFF 
  o 00AFE04C  sceneNameArea             00 00 00 00 00 00 5D 00 
  o 00AFE054  packageArea               00 00 5D 00 00 00 5D 00 
  o 00AFE05C  dateArea                  00 00 83 80 00 01 17 80 
  o 00AFE064  timeArea                  00 00 00 00 00 00 00 00 
  o 00AFE06C  batteryArea               00 01 17 80 00 01 48 80 
  o 00AFE074  leftArrowArea             00 00 00 00 00 00 00 00 
  o 00AFE07C  captionArea               00 00 00 00 00 00 00 00 
  o 00AFE084  rightArrowArea            00 00 00 00 00 00 00 00 
  o 00AFE08C  statusArea                00 01 67 00 00 01 67 00 
  o 00AFE094  stepBackArea              00 01 67 00 00 01 E0 00 
  o 00AFE09C  wirelessArea              00 00 00 00 00 00 00 00 
  o 00AFE0A4  lastACAdapter             1
  o 00AFE0A4  pad1                      0000000000000000000000000000000
  

This display shows the name bar, the viewable object next to the scene. The screen always has at least three subviews: a scene, the name bar at the top of the screen, and the control bar at the bottom of the screen. Look at the viewable object that's next to the name bar, using the name bar's next field:

do 80000426
 $00AFE4A8 ControlBar              $80000426  size:$000044   #:$00000426  flags:´´´´V´´´´´
  Displaying ControlBar at 00AFE4A8
  o             SingleLinkable
  o             00AFE4A8  next          00000000 
  o           Linkable
  o             HasIndexing
  o           00AFE4AC  previous        800002ED 
  o         Viewable
  o         00AFE4B0  superview         80000422 
  o         00AFE4B4  subview           80000423 
  o         00AFE4B8  relativeOrigin    00 00 00 00 00 00 8C 00 
  o         00AFE4C0  contentSize       00 01 E0 00 00 00 20 00 
  o         00AFE4C8  viewFlags         11004020 
  o         00AFE4CC  labelStyle        83078001 
  o         00AFE4D0  color             FF333333 
  o         00AFE4D4  altColor          FF000000 
  o         00AFE4D8  shadow            00000000 
  o         00AFE4DC  sound             00000000 
  o       Box
  o         HasBorder
  o         00AFE4E0  border            830F0039 
  o     Panel
  o   Bar
  o ControlBar
  o 00AFE4E4  separator                 00004680 
  o 00AFE4E8  hiliteIndex               00000000 
  
This display shows the control bar, the viewable next to the name bar in the view hierarchy. You have now used various commands to see the greeter that's about to be drawn, the scene that contains it, the screen, name bar, and control bar.

Looking at Code

MacsBug also includes commands for examining code. You can see the code that includes the current instruction by using the ip (instruction page) command:

ip
 Disassembling from 00AA3180
  No procedure name
            00AA3180   ORI.B      #$2A,D0                    ; '*'        | 0000 002A
            00AA3184   ORI.B      #$00,D0                                 | 0000 0000
            00AA3188   ORI.B      #$88,D0                                 | 0000 0088
            00AA318C   BSET       D0,(A5)+                                | 01DD
            00AA318E   ANDI.L     #$00000020,A2                           | 028A 0000 0020
            00AA3194   ORI.B      #$00,D0                                 | 0000 0000
            00AA3198   ORI.B      #$00,D0                                 | 0000 0000
  Greeter_Draw
     +0000  00AA319C ´*LINK       A6,#$FFF0                               | 4E56 FFF0
     +0004  00AA31A0   MOVEM.L    D6/D7,-(A7)                             | 48E7 0300
     +0008  00AA31A4   MOVE.L     $0008(A6),D7                            | 2E2E 0008
     +000C  00AA31A8   MOVE.L     D7,-(A7)                                | 2F07
     +000E  00AA31AA   _Hilited                                           | 742C 4EAD FFFA
     +0014  00AA31B0   TST.B      D0                                      | 4A00
     +0016  00AA31B2   ADDQ.W     #$4,A7                                  | 584F
     +0018  00AA31B4   BEQ.S      Greeter_Draw+001E          ; 00AA31BA   | 6704
     +001A  00AA31B6   MOVEQ      #$03,D0                                 | 7003
     +001C  00AA31B8   BRA.S      Greeter_Draw+0020          ; 00AA31BC   | 6002
     +001E  00AA31BA   MOVEQ      #$01,D0                                 | 7001
     +0020  00AA31BC   MOVE.L     D0,-(A7)                                | 2F00
     +0022  00AA31BE   MOVE.L     D7,-(A7)                                | 2F07
     +0024  00AA31C0   _PartColor                                         | 343C 0635 4EAD ƒ
     +002C  00AA31C8   MOVE.L     D0,D6                                   | 2C00
     +002E  00AA31CA   PEA        -$0010(A6)                              | 486E FFF0
     +0032  00AA31CE   MOVE.L     D7,-(A7)                                | 2F07
     +0034  00AA31D0   _ContentBox                                        | 7433 4EAD FFE0
     +003A  00AA31D6   MOVEQ      #$20,D0                    ; ' '        | 7020
     +003C  00AA31D8   MOVE.L     D0,-(A7)                                | 2F00
     +003E  00AA31DA   MOVE.L     D6,-(A7)                                | 2F06
     +0040  00AA31DC   PEA        -$0010(A6)                              | 486E FFF0
     +0044  00AA31E0   MOVE.L     $0010(A6),-(A7)                         | 2F2E 0010
     +0048  00AA31E4   MOVE.L     $000C(A6),-(A7)                         | 2F2E 000C
     +004C  00AA31E8   _FillBox                                           | 343C 049B 4EAD ƒ
     +0054  00AA31F0   LEA        $0024(A7),A7                            | 4FEF 0024
     +0058  00AA31F4   MOVEM.L    -$0018(A6),D6/D7                        | 4CEE 00C0 FFE8
     +005E  00AA31FA   UNLK       A6                                      | 4E5E
     +0060  00AA31FC   RTS                                                | 4E75

The ip command starts showing code just before the current instruction and continues to just after the current instruction. You can press return repeatedly to show more code. The program counter is marked with an asterisk just before the instruction disassembly. In this display, the asterisk is at the LINK instruction. You can compare this display to the source code for this method, shown here:

Method void
Greeter_Draw(ObjectID self, ObjectID canvas, ObjectID clip)
{
	Box 		ourContentBox;
	ulong		color;

	color = PartColor(self, Hilited(self) ? partAltContent :
partContent);
	
	ContentBox(self, &ourContentBox);
	FillBox(canvas, clip, &ourContentBox, color, pixelDither |
pixelCopy);
}

MacsBug defines various other commands for disassembling instructions. For more information, type ? in MacsBug to see MacsBug's online help.

Context and Clusters

Magic Cap defines a current context that determines which clusters can be used by each package. You can see the clusters available in the current context by using MacsBug's con (context) command:

con
 context for package HelloWorld
  Start       Class               Size      Free                  Slot
  00AFD37C  Cluster               00014000  00012F6C    #6% full   8   #0 (system persistent)
  00AA2CE0  Cluster               00001070  00000000  #100% full   88  #1 (locked persistent)
  00AA2C90  MetaCluster           0007FF70  00026BAC   #70% full   A   #4 (RAM)
  00A35B98  MetaCluster           0006B0E8  00012520   #83% full   A8  #5 (transient RAM)
  00A6E02C  Cluster               00000800  00000578   #32% full   B   #6 (package persistent
  00A6E838  Cluster               00000200  00000128   #43% full   C   #8 (package transient)
  00A83C44  Cluster               00014960  00006A44   #68% full   D  #10 (system transient)
  00A35BE8  Cluster               00038438  00000400  #100% full   E8 #13 (locked transient)
  00A985B0  Cluster               00001000  00000D1C   #19% full   F  #14 (scripting)
  0065BD5E  MetaCluster           003C6F08  00000000  #100% full  10  #16 (ROM, system persis
  00ACB370  Cluster               00032000  0002EFE0    #7% full  11  #17 (system persistent 
  00AA3144  Cluster               00000C0C  00000000  #100% full  12  #18 (package persistent
  00AA3E3C  Cluster               00000800  00000490   #43% full  13  #19 (package persistent


NOTE: The con command shows the clusters in the current context. The first line of its output identifies the context. In this example, because Magic Cap stopped while executing the package's code, the package's context is current. If you enter MacsBug when another context, such as the system, is current, your package clusters won't be listed in the output from con and you won't be able to access your package's objects with other commands. If you see the message Unable to access that address when trying to see an object, you're probably not in the package context.

There are two techniques you can use to make sure you stop in the package context:

  1. Set a breakpoint in the package's code.
  2. Click on a package object, and before releasing the mouse button, press the interrupt switch on the Macintosh to enter MacsBug.

When in MacsBug, you can always find out which cluster is current by typing con and checking the first line of its output.


Each cluster listed by the con command occupies a cluster slot in the context. Each cluster can be identified by the hexadecimal number shown in the slot column in the output from con. You can use the cdump (cluster dump) command to show information about all the objects in any cluster listed. For example, the RAM cluster, which occupies slot A in the context above, shows all the objects in persistent RAM:

cdump A

 Displaying RAM cluster (slot $A) at 00AA2C90
  
  Start     Class                    Length    Object    ELPONVA!M.C  Name
  00AA2CE0  Cluster                # 001070    000001     ´   ´´      
  00AA3D5C  PackageContext         # 0000D4    000019         ´       
  00AA3E3C  Cluster                # 000800    00001A        ´´       HelloWorld
  00AA4648  __Free__               # 026BAC    
  00ACB1F4  __MasterBlock__        # 000088    000000         ´       
  00ACB288  SystemContext          # 0000DC    000002         ´       
  00ACB370  Cluster                # 032000    000003         ´ ´     
  00AFD37C  Cluster                # 014000    000004         ´       
  00B11388  Buffer                 # 002800    000005                 
  00B13B94  PackageContext         # 0000D4    000006         ´       
  00B13C74  Cluster                # 000800    000007        ´´       Testing
  00B14480  StringList             # 000060    000009         ´       
  00B144EC  StringDictionary       # 00002C    000008         ´       
  00B14524  PackageContext         # 0000D4    00000A         ´       
  00B14604  Cluster                # 000800    00000C        ´´       CloudIP
  00B14E10  PackageContext         # 0000D4    00000D         ´       
  00B14EF0  Cluster                # 000800    00000F        ´´       Calculator
  00B156FC  PackageContext         # 0000D4    000010         ´       
  00B157DC  Cluster                # 002000    000012        ´´       Help Books
  00B177E8  Buffer                 # 006000    000014                 
  00B1D7F4  Buffer                 # 005000    000016                 
  00B22800  Buffer                 # 000400    000018                 
  
   #22 objects displayed, #20 real ones (not free or master-block)
   026BAC bytes free
   059380 bytes used
   000000 bytes purgeable
   07FF2C total bytes
   000001 object accessed
    30% free
  
This cluster contains many other clusters itself, which in turn contain objects in main RAM. This cluster also includes various package context objects, one for each package. When you build and run your package using the simulator, the package is placed in main RAM.

Note that the Object column shows only the lower portion of each object's ID. To form an object ID, prefix the cluster's slot number to the value in the Object column. For example, the second object in the cluster above has 000019 in the Object column. Because you're looking at cluster A, the object's ID is $A0000019.

You can find out more about your package by looking at its package context object. The package context for a particular package is usually located adjacent to the cluster that has the package's name. Use do to see the package context object:

do $A0000019
 $00AA3D5C PackageContext          $A0000019  size:$0000D4   #:$00000019  flags:´´´´V´´´´´
  Displaying PackageContext at 00AA3D5C
  o   Context
  o   00AA3D5C  numEntries              00000014 
  o   00AA3D60  dataOffset              00000034 
  o   00AA3D64  globalsOffset           00000034 
  o   00AA3D68  classList               B4000022 
  o   00AA3D6C  operationList           B4000023 
  o   00AA3D70  intrinsicList           B4000025 
  o   00AA3D74  directDispatchList      B4000024 
  o   00AA3D78  rootList                B400001D 
  o PackageContext
  o   HasPeriodicUpdate
  o   00AA3D7C  dirty                   1
  o   00AA3D7C  shouldUpdateSoon        1
  o   00AA3D7C  older                   0
  o   00AA3D7C  pending                 0
  o   00AA3D7C  pad1                    0000000000000000000000000000
  o   StoreroomScenePackage
  o 00AA3D80  unused                    00000000 
  o 00AA3D84  active                    1
  o 00AA3D84  inited                    1
  o 00AA3D84  hasStubs                  0
  o 00AA3D84  dataPackage               0
  o 00AA3D84  hasShadows                1
  o 00AA3D84  pad1                      000000000000000000000000000
  o 00AA3D88  persistentReferences      800024BD 
  o 00AA3D8C  transientReferences       D00000DB 
  
The package context's rootList field refers to the software package object itself. Use do to look at the software package object:
do B400001D

 $00AA402C SoftwarePackage         $B400001D  size:$0000C8   #:$0000001D  flags:´´´NV´´´´´
  Name: HelloWorld
  Displaying SoftwarePackage at 00AA402C
  o           AbstractList
  o           00AA402C  length          00000020 
  o         FixedList
  o       ObjectList
  o         HasIndexing
  o     RootList
  o       HasDate
  o       00AA4030  dateCreated         0000C285 
  o       00AA4034  timeCreated         FFFFFFFF 
  o       00AA4038  dateModified        0000C286 
  o       00AA403C  timeModified        04945AF8 
  o   PackageRootList
  o   00AA4040  author                  B0000001 
  o   00AA4044  installList             B0000002 
  o   00AA4048  receivers               B0000003 
  o   00AA404C  installFlags            00000000 
  o   00AA4050  installParameters       00000000 
  o   00AA4054  installTargets          00000000 
  o   00AA4058  autoActivate            1
  o   00AA4058  pad1                    0000000000000000000000000000000
  o SoftwarePackage
  o 00AA405C  citation                  B0000004 
  o 00AA4060  publisher                 B0000001 
  o 00AA4064  persistentShadowSize      00000000 
  o 00AA4068  persistentChangesSize     00000000 
  o 00AA406C  transientSize             00000000 
  o 00AA4070  gotoActionSelector        0003 
  o 00AA4072  hidden                    0
  o 00AA4072  dontSaveData              0
  o 00AA4072  copyOnActivate            0
  o 00AA4072  dontDeactivate            0
  o 00AA4072  needsReset                0
  o 00AA4072  systemPackageReserved6    0
  o 00AA4072  systemPackageReserved7    0
  o 00AA4072  systemPackageReserved8    0
  o 00AA4073  systemPackageReserved9    0
  o 00AA4073  systemPackageReserved10   0
  o 00AA4073  systemPackageReserved11   0
  o 00AA4073  systemPackageReserved12   0
  o 00AA4073  systemPackageReserved13   0
  o 00AA4073  systemPackageReserved14   0
  o 00AA4073  systemPackageReserved15   0
  o 00AA4073  systemPackageReserved16   0
  o 00AA4074  entry#1                   00000000
  o 00AA4078  entry#2                   00000000
  o 00AA407C  entry#3                   00000000
  o 00AA4080  entry#4                   00000000
  o 00AA4084  entry#5                   00000000
  o 00AA4088  entry#6                   B0000005
  o 00AA408C  entry#7                   00000000
  o 00AA4090  entry#8                   00000000
  o 00AA4094  entry#9                   B0000006
  o 00AA4098  entry#10                  B0000007
  o 00AA409C  entry#11                  00000000
  o 00AA40A0  entry#12                  00000000
  o 00AA40A4  entry#13                  83050007
  o 00AA40A8  entry#14                  00000000
  o 00AA40AC  entry#15                  8300C0B7
  o 00AA40B0  entry#16                  00000000
  o 00AA40B4  entry#17                  00000000
  o 00AA40B8  entry#18                  00000000
  o 00AA40BC  entry#19                  00000000
  o 00AA40C0  entry#20                  00000000
  o 00AA40C4  entry#21                  00000000
  o 00AA40C8  entry#22                  00000000
  o 00AA40CC  entry#23                  00000000
  o 00AA40D0  entry#24                  B000001C
  o 00AA40D4  entry#25                  00000000
  o 00AA40D8  entry#26                  00000000
  o 00AA40DC  entry#27                  00000000
  o 00AA40E0  entry#28                  00000000
  o 00AA40E4  entry#29                  00000000
  o 00AA40E8  entry#30                  00000000
  o 00AA40EC  entry#31                  00000000
  o 00AA40F0  entry#32                  00000000
  
You can use the software package object to see the install list and the receiver list, the structures that tell Magic Cap which package objects to install and where to put them. The installList and receivers fields refer to these lists. First, look at the install list:
do B0000002
 $00AA33F0 ObjectList              $B0000002  size:$00000C   #:$00000002  flags:´´´NVA´´´´
  Name: Install
  Displaying ObjectList at 00AA33F0
  o     AbstractList
  o     00AA33F0  length                00000002 
  o   FixedList
  o ObjectList
  o   HasIndexing
  o 00AA33F4  entry#1                   B000000C
  o 00AA33F8  entry#2                   B000000D
  
The install list has two entries. You can look at them with do:
do B000000C
 $00A6E21C Scene                   $B000000C  size:$000054   #:$0000000C  flags:´´´NV´´´´´
  Name: HelloWorld
  Displaying Scene at 00A6E21C
  o           SingleLinkable
  o           00A6E21C  next            800002ED 
  o         Linkable
  o           HasIndexing
  o         00A6E220  previous          00000000 
  o       Viewable
  o       00A6E224  superview           80000422 
  o       00A6E228  subview             B000000E 
  o       00A6E22C  relativeOrigin      00 00 00 00 FF FF F8 00 
  o       00A6E234  contentSize         00 01 E0 00 00 01 00 00 
  o       00A6E23C  viewFlags           11005220 
  o       00A6E240  labelStyle          83078001 
  o       00A6E244  color               FF555555 
  o       00A6E248  altColor            FF000000 
  o       00A6E24C  shadow              00000000 
  o       00A6E250  sound               00000000 
  o     Box
  o       HasBorder
  o       00A6E254  border              00000000 
  o   Panel
  o Scene
  o 00A6E258  sceneFlags                00000000 
  o 00A6E25C  stepBackScene             800004F9 
  o 00A6E260  stepBackSpot              800024C4 
  o 00A6E264  image                     00000000 
  o 00A6E268  additions                 00000000 
  o 00A6E26C  screen                    00000000 

This display shows that the first object in the install list is HelloWorld's scene. Now look at the other object to be installed:

do B000000D
 $00AA4100 NameCard                $B000000D  size:$00004C   #:$0000000D  flags:´´´NV´´´´´
  Name: General Magic DTS
  Displaying NameCard at 00AA4100
  o         SingleLinkable
  o         00AA4100  next              00000000 
  o       Linkable
  o         HasIndexing
  o       00AA4104  previous            00000000 
  o     Viewable
  o     00AA4108  superview             00000000 
  o     00AA410C  subview               00000000 
  o     00AA4110  relativeOrigin        FF FF E4 00 00 00 08 00 
  o     00AA4118  contentSize           00 01 88 00 00 00 E5 00 
  o     00AA4120  viewFlags             50005200 
  o     00AA4124  labelStyle            83078001 
  o     00AA4128  color                 00000000 
  o     00AA412C  altColor              00000000 
  o     00AA4130  shadow                00000000 
  o     00AA4134  sound                 00000000 
  o   Card
  o   00AA4138  form                    8306C00B 
  o   00AA413C  stack                   800000DC 
  o   00AA4140  cardFlags               404000E7 
  o NameCard
  o 00AA4144  addressCard               B0000001 
  o 00AA4148  profile                   00000000 
  
The second object to be installed is the name card for General Magic DTS (developer technical support). Now you can look at the receiver list, getting the list's object ID from the software package object's receivers field:
do B0000003
 $00AA3408 ObjectList              $B0000003  size:$00000C   #:$00000003  flags:´´´NVA´´´´
  Name: Receiver
  Displaying ObjectList at 00AA3408
  o     AbstractList
  o     00AA3408  length                00000002 
  o   FixedList
  o ObjectList
  o   HasIndexing
  o 00AA340C  entry#1                   83050007
  o 00AA3410  entry#2                   8307A006
  
You can check the entries in the receiver list to see if they match with the objects to be installed in them. The first entry:
do 83050007
 Indexical $83050007 "iHallway" (list #40, entry #7) is:
  $00AFDF94 Scene                   $800004F9  size:$000054   #:$000004F9  flags:´´´NV´´´´´
  Name: Hallway
  Displaying Scene at 00AFDF94
  o           SingleLinkable
  o           00AFDF94  next            00000000 
  o         Linkable
  o           HasIndexing
  o         00AFDF98  previous          00000000 
  o       Viewable
  o       00AFDF9C  superview           00000000 
  o       00AFDFA0  subview             800005A9 
  o       00AFDFA4  relativeOrigin      00 00 00 00 FF FF F8 00 
  o       00AFDFAC  contentSize         00 01 E0 00 00 01 00 00 
  o       00AFDFB4  viewFlags           11005000 
  o       00AFDFB8  labelStyle          83078001 
  o       00AFDFBC  color               FF555555 
  o       00AFDFC0  altColor            FF000000 
  o       00AFDFC4  shadow              00000000 
  o       00AFDFC8  sound               00000000 
  o     Box
  o       HasBorder
  o       00AFDFCC  border              00000000 
  o   Panel
  o Scene
  o 00AFDFD0  sceneFlags                C0040000 
  o 00AFDFD4  stepBackScene             800005C5 
  o 00AFDFD8  stepBackSpot              00000000 
  o 00AFDFDC  image                     00000000 
  o 00AFDFE0  additions                 800005AA 
  o 00AFDFE4  screen                    D020008B 
  
The digit 3 in the second nibble of an object ID indicates that the ID is an indexical. This object is the hallway; it corresponds to the HelloWorld scene, the first entry in the install list. Magic Cap recognizes the scene-hallway install-receive pair and creates a door in the hallway that leads to the given scene.

Now look at the second entry in the receiver list:

do 8307A006
 Indexical $8307A006 "iNameCardsStack" (list #61, entry #6) is:
  $00ACC970 NameCardsStack          $800000DC  size:$00007C   #:$000000DC  flags:´´´NV´´´´´
  Name: all
  Displaying NameCardsStack at 00ACC970
  o           AbstractList
  o           00ACC970  length          00000014 
  o         FixedList
  o       ObjectList
  o         HasIndexing
  o     DenseObjectList
  o   StackOfCards
  o   00ACC974  protoCard               800000AB 
  o   00ACC978  stackFlags              00000003 
  o   00ACC97C  stackScene              800000AC 
  o NameCardsStack
  o 00ACC980  displaySize               00000000 
  o 00ACC984  entry#1                   800000AD
  o 00ACC988  entry#2                   800000AE
  o 00ACC98C  entry#3                   800000AF
  o 00ACC990  entry#4                   800000B0
  o 00ACC994  entry#5                   800000B1
  o 00ACC998  entry#6                   800000B2
  o 00ACC99C  entry#7                   800000B3
  o 00ACC9A0  entry#8                   800000B4
  o 00ACC9A4  entry#9                   800000B5
  o 00ACC9A8  entry#10                  820024C8
  o 00ACC9AC  entry#11                  800000B6
  o 00ACC9B0  entry#12                  800000B7
  o 00ACC9B4  entry#13                  800000B8
  o 00ACC9B8  entry#14                  800000B9
  o 00ACC9BC  entry#15                  800000BA
  o 00ACC9C0  entry#16                  800000BB
  o 00ACC9C4  entry#17                  8200248E
  o 00ACC9C8  entry#18                  800000BC
  o 00ACC9CC  entry#19                  800000BD
  o 00ACC9D0  entry#20                  800000BE
  

This entry, the name cards stack, gets the second installed object, the DTS name card. When the package is unpacked, the DTS name card goes into the name cards stack where it belongs.

That's the end of the tour. This tour covered several of the most important MacsBug commands, including br, do, con, and cdump, and demonstrated how you can use the commands to navigate through your objects and find information. To see how you might use these commands for real debugging, see this book's Sample Debugging Session section. For more information on MacsBug commands, see the MacsBug Reference section below or MacsBug's online reference.

MacsBug Reference

This table below lists MacsBug commands. Some of the commands listed here are built into MacsBug, while others are debugger command (dcmd) extensions provided by CodeWarrior Magic/MPW. Not all built-in MacsBug commands are listed, only those that are most useful for Magic Cap development. You can enter MacsBug commands in upper or lower case.

The commands added to MacsBug by CodeWarrior Magic/MPW are shown in bold. If you are an experienced MacsBug user, you can just look for the bold items to see what CodeWarrior Magic/MPW adds.

MacsBug itself includes online help, which you can see by typing ? while in MacsBug. Many of the commands listed in this table have optional additional syntax; use MacsBug's online help to see the full syntax. For complete information on MacsBug, see the book MacsBug Reference and Debugging Guide (order ISBN 0-201-56767-9).

-----------------------------------------------------------------------
Command               Description                                        
-----------------------------------------------------------------------
ACTOR                 Display information about actors.                  
BR addr [n | expr]    Set a breakpoint that breaks at the given ad       
[';cmds']             dress each [n] times or when [expr] is true,       
                      or every time if both are omitted. Execute         
                      [cmds] on break.                                   
BRC [addr]            Clear the breakpoint at the given address, or      
                      clear all breakpoints if no address is given.      
BRD                   List all breakpoints.                              
BRM string            Set a breakpoint at all addresses that contain     
                      the given string. For example, BRM _Draw           
                      sets breakpoints at all Draw methods; BRM          
                      Clock_ sets breakpoints at all methods of          
                      class Clock.                                       
CDUMP <cluster> [mi   Display information about objects in the           
nAddress] [\class         given cluster, starting at [minAddress] or         
Name | classNumber]   entire cluster if omitted. The cluster can         
                      be specified by context slot, object ID, or        
                      address. Only show objects of [class               
                      Name] or [classNumber], or all objects if          
                      omitted. Use backslash before class                
                      name, e.g.: \Scene                                     
CON                   Display information about the clusters in          
                      the current context.                               
DM [addr [n | tem     Display the contents of memory at [addr]           
plate | basic type]]  for [n] bytes or as defined by [template] or       
                      [basic type].                                      
DO                    Same as DOBJ.                                      
DOBJ <object>         Display the object's fields and their con          
                      tents. The object can be specified by ob           
                      ject ID or memory address.                         
DOAx                  (x is 0 through 4) Given an object ID in           
                      address register x, display the object's           
                      fields and their contents.                         
DOSP, DOSP4, DOSP8    Given an object ID on top of the stack, 4          
                      bytes from the top of the stack, or 8 bytes        
                      from the top of the stack, display the ob          
                      ject's fields and their contents.                  
DOx                   (x is 0 through 7) Given an object ID in           
                      data register x, display the object's fields       
                      and their contents.                                
EXC <number>          Given an exception number, display the             
                      name of the exception.                             
G                     Resume execution. You can also type  command-G.           
GETCLASS <index>      Given a class number, display the name             
                      of the class.                                      
GETINDEXICAL [<index  Display name of given indexical, which             
icalNum>]             should specified as an object ID with us           
                      able bit set. If GETINDEXICAL returns              
                      <unknown>, add $04000000 to object ID              
                      and try again.                                     
GETINT <number>       Given an intrinsic number, display the             
                      name of the intrinsic.                             
GETOBJ <objectID>     Given an object's ID, display informa              
                      tion about the object.                             
GETOP <operationNum>  Given an operation number, display the             
                      name of the operation.                             
IL [addr [n]]         Disassemble instructions starting at the giv       
                      en address, or start at the program counter if     
                      no address is given. Show [n] instructions,        
                      or 16 if [n] is omitted.                           
IP [addr]             Disassemble instructions around the given          
                      address, or around the program counter if          
                      no address is given.                               
IR [addr]             Disassemble instructions from the given ad         
                      dress to the end of the function.                  
OBJ                   Same as GETOBJ.                                    
S [n | expr]          Execute one instruction, then stop. You can        
                      also type  command-S. If [n] is given, step for [n] in    
                      structions. If [expr] is given, step until [ex     
                      pr] is true.                                       
SC [addr]             Display stack crawl showing function call          
                      chain and parameters. Use A6 links. Start at       
                      [addr], or A6 if omitted.                          
T [n | expr]          Execute one instruction, then stop. If the in      
                      struction is a JSR, execute until RTS. You         
                      can also type  command-T. If [n] is given, step for [n]   
                      instructions. If [expr] is given, step until       
                      [expr] is true.                                    
                                                                         
-----------------------------------------------------------------------

Telebug

This section describes Telebug, the remote debugger you can use to debug Magic Cap packages running on personal communicators. Although Telebug software is supplied with CodeWarrior Magic/MPW, you must have a Telebug Interface Box and a personal communicator to use Telebug. Contact your CodeWarrior Magic/MPW supplier for more information about ordering a Telebug Interface Box.

About Telebug

Telebug is General Magic's remote debugger for Magic Cap. CodeWarrior Magic/MPW includes Telebug software designed for use with communicators that run Magic Cap. Telebug runs on a Macintosh computer connected to the communicator via a Telebug Interface Box.

Telebug is a Macintosh program that uses a specially configured copy of the MPW Shell application. Telebug's features and commands are similar to those of MacsBug, except that Telebug commands and displays are shown in standard Macintosh windows. Telebug also includes a scripting language and command file execution.

Telebug only works with communicators and not with Magic Cap Simulator. To debug packages running on the simulator, use MacsBug instead.

You can start Telebug by selecting the Run Telebug menu item in CodeWarrior Magic/MPW. When Telebug is running, you can force it to take control by typing command- <period>. This command will stop Magic Cap execution in the communicator and give control to Telebug.

Because Telebug uses a version of MPW Shell, you use MPW Shell conventions and editing features in its windows. For example, pressing the enter key executes the commands on the current line.

When you build your package, CodeWarrior Magic/MPW includes your package's symbols in your object code if you have the debug build menu item turned on. If you choose Envoy Debugger Target or Magic Link Debugger Target, CodeWarrior Magic/MPW also adds debugger symbols for the chosen communicator's ROM.

Setting up Telebug

When you install CodeWarrior Magic/MPW, Telebug software is also installed. You need the following items to run Telebug:

You should connect your communicator to AC power when using Telebug, as the debugging process puts great demand on power by frequently interrupting the operation of power-saving software.

You may have to contact the communicator manufacturer to install your Telebug cable, depending on the model. See the documentation that comes with the Telebug Interface Box for more information.

Turn off the communicator, then connect the communicator's Telebug cable to the connector on the Telebug Interface Box labeled Telebug cable to communicator. You should always turn off the communicator before connecting it to the Telebug Interface Box or it may restart spontaneously when you connect it. Be sure to align the cable properly using the key on the connector as a guide.

Next, connect the serial cable between the modem port on the Macintosh and the connector on the Telebug Interface Box labeled Serial cable to Mac.

Finally, connect the Telebug Interface Box and the communicator to their AC adaptors and plug the adaptors in.

The Communicator reset button on the Telebug Interface Box performs the same function as the recessed reset switch found on communicators. Pressing this switch restarts the communicator, leaving persistent RAM intact. You can use this switch as a last resort when the communicator seems to be hung. Before pressing reset, always try to turn the communicator off by pressing the power switch several times.

WARNING: You should always back up important data in your communicator before using it for package development. When developing packages, there are many ways to damage data. In particular, Telebug includes a dangerous command, rb (reboot), that destroys the contents of the communicator's RAM without waiting for confirmation.

WARNING: If your communicator has a Telebug cable installed that is not connected to a Telebug Interface Box, the communicator may be susceptible to spontaneous resets caused by static electricity carried along the cable. If you encounter this problem, you may want to leave the communicator connected to the Telebug Interface Box, tape the cable to the back of the communicator when not in use, or remove the cable, if possible.

The communicator senses when it is connected to a Telebug Interface Box. When Magic Cap encounters various debugger breaks, such as breakpoints or uncaught exceptions, the communicator stops if connected to a Telebug Interface Box, even if Telebug isn't running on a connected Macintosh. If your communicator is connected to a Telebug box and it appears hung, you can either start Telebug and determine the problem, or press the Communicator reset button on the Telebug Interface Box to reset the communicator.

Telebug Tour

This section introduces Telebug by demonstrating how it works on a running package. The output in this section comes from Telebug's worksheet window. This section is mostly the same as the MacsBug Tour, substituting Telebug information where appropriate.

To begin using Telebug, follow the instructions in the Setting up Telebug section to set up the hardware. Run CodeWarrior Magic/MPW and select HelloWorld as the current directory. Choose Universal Device Build Target from the Magic menu. Choose Envoy Debugger Target or Magic Link Debugger Target, whichever is appropriate. When you build HelloWorld, CodeWarrior Magic/MPW finishes by downloading it to a PC RAM card in your communicator. Run Telebug from the Utils menu.

Downloading a package to a RAM card erases the prior contents of the RAM card and makes the card simulate a ROM card, preventing you from storing anything on the card from Magic Cap. If you don't want to simulate a ROM card, you can use the Set PC Card Type item in CodeWarrior Magic/MPW. Downloading also resets the communicator, but leaves persistent data intact.

When Telebug starts up, it will load equates (symbols) for the communicator ROM and your package, a process that can take up to a minute. When the equates are loaded, Telebug displays the following message:

# Personal Messenger status: Running (type Command-Period to
break)...


Personal Messenger is an ancient Sumerian name for personal communicator. When this message appears, you can press command- <period> on the Macintosh keyboard to stop Magic Cap and break into Telebug. You'll see a message like this one:

# _HandleLevel5Int

| 0046C224 # +0000 * NOP                                     
If Telebug has trouble starting, or you can't break into Telebug, check your cables to make sure that the Telebug Interface Box, Macintosh, and personal communicator are connected properly. See this book's Setting up Telebug section and the documentation that came with the Telebug Interface Box for more information.

You can use any mix of upper and lower case when typing commands. Neither Telebug commands nor Magic Cap symbols are case sensitive.

Note: If you're reading this online, you can use your documentation reader to enlarge the Telebug output in this section.

You can set a breakpoint to get Telebug to take control whenever a particular function is executed. To get Telebug to take control whenever Greeter_Draw is executed, type

br Greeter_Draw

g
As in MPW, press the enter key to execute the commands on the current line. The g command exits Telebug and resumes execution in Magic Cap. Next, go to HelloWorld's door in the hallway and enter. When Magic Cap is about to draw the greeter (the black box), Telebug takes control:
# Greeter_Draw
I 04000184 # +0000 * LINK       A6,#$FFEC                    

To find out more about the data and return addresses on the stack, use the sc (stack crawl) command:
sc
  CallerPC   Caller                          A6 Link   Params
| 004705CC # UserActor_Main+00FA             0001F66C  D400 0011 0000 0000 D400 0011 D400 0005 0047 
| 005250A0 # ToolButton_Touch+00A0           0001F610! D460 00A6 0000 0000 D400 0011 704B 72FC 8400 
| 005239D2 # Button_Touch+0140               0001F5DC  8400 17ED D460 00A6 D460 0000 B400 0001 7050 
| 00524B9A # ToolButton_Action+0118          0001F5A4  8400 17ED D460 00A6 8708 8003 8400 17ED 8400 
| 0054935C # Viewable_RedrawNow+0052         0001F55C! 0000 0000 0001 F601 8400 1701 8400 17ED 8400 
| 0054885E # Viewable_RedrawNowOffscreƒ+01D2 0001F434! EC00 0022 8400 0448 0000 0000 8400 24AB 8708 
| 005485D4 # Viewable_DrawDirty+0298         0001F3D8! 0001 F46E 0001 F45E 8400 24AB 8708 8003 0000 
| 005485C2 # Viewable_DrawDirty+0286         0001F36C! 0001 F46E 0001 F424 0001 F480 0000 0000 0000 
| 04000184 # Greeter_Draw+0000               0001F36C! B400 000E EC00 0022 D400 0020 0000 0001 0000 
The Caller column shows the names of the functions that have return addresses on the stack, with the most recently executed function on the bottom. The values listed under Params show the contents of the stack (not including the return address) when each function was called.

For methods, the first parameter on the stack is an object ID for the responder, also called the self parameter. Find out more about this object using the getobj (get object) command:

getobj B400000E
| $0007BAD8 # Greeter             $B400000E  size:$000038   #:$0000000E  flags:´´´NV´´´´´
# Name: Hello World
This command gives the object's class (Greeter), name (Hello World), and location in memory ($000DFFB4). When you enter Telebug via a breakpoint at the start of a method, the responder's object ID is located 4 bytes from the top of the stack. You can use Telebug's expression syntax to show the object at this stack location:
getobj @(sp+4)
| $0007BAD8 # Greeter             $B400000E  size:$000038   #:$0000000E  flags:´´´NV´´´´´
# Name: Hello World
Displaying Greeter at 0007BAD8
o       SingleLinkable
o       0007BAD8  next                00000000 
o     Linkable
o       HasIndexing
o     0007BADC  previous              00000000 
o   Viewable
o   0007BAE0  superview               B000000C 
o   0007BAE4  subview                 00000000 
o   0007BAE8  relativeOrigin          00 00 00 00 FF FF F2 00 
o   0007BAF0  contentSize             00 00 5A 00 00 00 5A 00 
o   0007BAF8  viewFlags               7818D220 
o   0007BAFC  labelStyle              83078001 
o   0007BB00  color                   FFFFFFFF 
o   0007BB04  altColor                FF000000 
o   0007BB08  shadow                  00000000 
o   0007BB0C  sound                   83042013 
o Greeter
When Telebug takes control at the start of a method, as in the current example, the responder (the self parameter) is 4 bytes from the top of the stack. As the method's code executes, the stack changes, and the responder is no longer 4 bytes from the top of the stack. However, you can always get the responder's object ID while a method is executing by using the following expression:
@(a6+8)
For example, if a method is executing, you can type dobj @(A6+8) to see the responder and all its fields. This works because every method sets up register A6 to point to its parameters.

The dobj command displays objects with the names of their fields. You can use the dm (display memory) command to show the raw data of objects, without using field information. When you use dm, you specify the starting address for the memory to be displayed and, optionally, the number of bytes to show. Telebug defines the period (.) as a variable that contains the last address used by a command. So, after using dobj to show the object and its fields, you can see the object's raw data:

dm . 30
  0007BAD8  0000 0000 0000 0000 B000 000C 0000 0000 | ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ |
  0007BAE8  0000 0000 FFFF F200 0000 5A00 0000 5A00 | ÜÜÜÜÜÜÜÜÜÜZÜÜÜZÜ |
  0007BAF8  7818 D220 8307 8001 FFFF FFFF FF00 0000 | xÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜ |
You can use the information provided by these commands to learn more about the package and its objects. The dobj display above shows the other objects that the responder (the greeter object) refers to, including its superview, which has object ID $B000000C. You can use dobj to see the superview:
dobj b000000c
| $0007BA78 # Scene               $B000000C  size:$000054   #:$0000000C  flags:´´´NV´´´´´
# Name: HelloWorld
Displaying Scene at 0007BA78
o           SingleLinkable
o           0007BA78  next            8000030F 
o         Linkable
o           HasIndexing
o         0007BA7C  previous          00000000 
o       Viewable
o       0007BA80  superview           80000448 
o       0007BA84  subview             B000000E 
o       0007BA88  relativeOrigin      00 00 00 00 FF FF F8 00 
o       0007BA90  contentSize         00 01 E0 00 00 01 00 00 
o       0007BA98  viewFlags           11005220 
o       0007BA9C  labelStyle          83078001 
o       0007BAA0  color               FF555555 
o       0007BAA4  altColor            FF000000 
o       0007BAA8  shadow              00000000 
o       0007BAAC  sound               00000000 
o     Box
o       HasBorder
o       0007BAB0  border              00000000 
o   Panel
o Scene
o 0007BAB4  sceneFlags                00000000 
o 0007BAB8  stepBackScene             8000051F 
o 0007BABC  stepBackSpot              800024BE 
o 0007BAC0  image                     00000000 
o 0007BAC4  additions                 00000000 
o 0007BAC8  screen                    00000000 
  
Because Telebug displays appear in standard Macintosh windows, you can use copy and paste to help issue commands. For example, you can copy an object ID from a field and paste it to combine it with a dobj command. This display shows that the greeter's superview is a scene, also named HelloWorld.

You can use the information from the last dobj command to see the scene's superview, which is the screen object. Use the object ID from the scene's superview field:

dobj 80000448
| $00097248 # Screen              $80000448  size:$000044   #:$00000448  flags:´´´´V´´´´´
Displaying Screen at 00097248
o           SingleLinkable
o           00097248  next            00000000 
o         Linkable
o           HasIndexing
o         0009724C  previous          00000000 
o       Viewable
o       00097250  superview           00000000 
o       00097254  subview             820024BF 
o       00097258  relativeOrigin      00 00 F0 00 00 00 A0 00 
o       00097260  contentSize         00 01 E0 00 00 01 40 00 
o       00097268  viewFlags           11005020 
o       0009726C  labelStyle          00000000 
o       00097270  color               00000000 
o       00097274  altColor            00000000 
o       00097278  shadow              00000000 
o       0009727C  sound               00000000 
o     Box
o       HasBorder
o       00097280  border              00000000 
o   Panel
o Screen
o 00097284  screenFlags               E0000280 
o 00097288  redrawCount               00000591 
  
Note that the screen object's ID is $80000448, while the greeter's is $B400000E. The first five bits of an object ID indicate the cluster that contains that object. The screen object is in cluster 8, the system persistent cluster, while the greeter is in cluster B, the package persistent cluster.

Now go back to the scene object shown above and display the viewable next to it, using the object ID in the scene's next field:

dobj 8000030F
| $00097504 # NameBar             $8000030F  size:$0000B4   #:$0000030F  flags:´´´´V´´´´´
Displaying NameBar at 00097504
o             SingleLinkable
o             00097504  next          8000044C 
o           Linkable
o             HasIndexing
o           00097508  previous        820024BF 
o         Viewable
o         0009750C  superview         80000448 
o         00097510  subview           80000312 
o         00097514  relativeOrigin    00 00 00 00 FF FF 6B 80 
o         0009751C  contentSize       00 01 E0 00 00 00 17 00 
o         00097524  viewFlags         11004020 
o         00097528  labelStyle        8307800D 
o         0009752C  color             FF000000 
o         00097530  altColor          FFFFFFFF 
o         00097534  shadow            00000000 
o         00097538  sound             00000000 
o       Box
o         HasBorder
o         0009753C  border            83046001 
o     Panel
o   Bar
o NameBar
o 00097540  titleBarFlags             0700000D 
o 00097544  pageArrow                 8300C24D 
o 00097548  captionTextStyle          83078001 
o 0009754C  lastDrawDate              0000C0F9 
o 00097550  lastDrawTime              022725EF 
o 00097554  lastLevel                 00000064 
o 00097558  lastCharging              00000002 
o 0009755C  sceneNameArea             00 00 00 00 00 00 5D 00 
o 00097564  packageArea               00 00 5D 00 00 00 5D 00 
o 0009756C  dateArea                  00 00 8B 80 00 01 14 80 
o 00097574  timeArea                  00 00 00 00 00 00 00 00 
o 0009757C  batteryArea               00 01 14 80 00 01 40 80 
o 00097584  leftArrowArea             00 00 00 00 00 00 00 00 
o 0009758C  captionArea               00 00 00 00 00 00 00 00 
o 00097594  rightArrowArea            00 00 00 00 00 00 00 00 
o 0009759C  statusArea                00 01 67 00 00 01 67 00 
o 000975A4  stepBackArea              00 01 67 00 00 01 E0 00 
o 000975AC  wirelessArea              00 01 40 80 00 01 66 80 
o 000975B4  lastACAdapter             1
o 000975B4  pad1                      0000000000000000100000010000000
  
This display shows the name bar, the viewable object next to the scene. The screen always has at least three subviews: a scene, the name bar at the top of the screen, and the control bar at the bottom of the screen. Look at the viewable object that's next to the name bar, using the name bar's next field:
dobj 8000044C
| $00097C24 # ControlBar          $8000044C  size:$000044   #:$0000044C  flags:´´´´V´´´´´
Displaying ControlBar at 00097C24
o             SingleLinkable
o             00097C24  next          00000000 
o           Linkable
o             HasIndexing
o           00097C28  previous        8000030F 
o         Viewable
o         00097C2C  superview         80000448 
o         00097C30  subview           80000449 
o         00097C34  relativeOrigin    00 00 00 00 00 00 8C 00 
o         00097C3C  contentSize       00 01 E0 00 00 00 20 00 
o         00097C44  viewFlags         11004020 
o         00097C48  labelStyle        83078001 
o         00097C4C  color             FF333333 
o         00097C50  altColor          FF000000 
o         00097C54  shadow            00000000 
o         00097C58  sound             00000000 
o       Box
o         HasBorder
o         00097C5C  border            830F0039 
o     Panel
o   Bar
o ControlBar
o 00097C60  separator                 00004680 
o 00097C64  hiliteIndex               00000000 
  
This display shows the control bar, the viewable next to the name bar in the view hierarchy. You have now used various commands to see the greeter that's about to be drawn, the scene that contains it, the screen, name bar, and control bar.

Looking at Code

Telebug also includes commands for examining code. You can see the code from the current instruction to the end of the function by using the ir (instruction return) command:

ir
# Greeter_Draw
I 04000184 # +0000 * LINK       A6,#$FFEC                     
I 04000188 # +0004   MOVE.L     D3,-(SP)                      
I 0400018A # +0006   MOVE.L     $0008(A6),D3                  
I 0400018E # +000A   MOVE.L     D3,-(SP)                      
I 04000190 # +000C   _Hilited
I 04000196 # +0012   TST.B      D0                            
I 04000198 # +0014   ADDQ.W     #$4,SP                        
I 0400019A # +0016   BNE.S      Greeter_Draw+001C             ; 040001A0
I 0400019C # +0018   MOVEQ      #$01,D0                       
I 0400019E # +001A   BRA.S      Greeter_Draw+001E             ; 040001A2
I 040001A0 # +001C   MOVEQ      #$03,D0                       
I 040001A2 # +001E   MOVE.L     D0,-(SP)                      
I 040001A4 # +0020   MOVE.L     D3,-(SP)                      
I 040001A6 # +0022   _PartColor
I 040001AE # +002A   MOVE.L     D0,-$0014(A6)                 
I 040001B2 # +002E   PEA        -$0010(A6)                    
I 040001B6 # +0032   MOVE.L     D3,-(SP)                      
I 040001B8 # +0034   _ContentBox
I 040001BE # +003A   PEA        _DMASpace+0018                ; 00000020
I 040001C2 # +003E   MOVE.L     -$0014(A6),-(SP)              
I 040001C6 # +0042   PEA        -$0010(A6)                    
I 040001CA # +0046   MOVE.L     $0010(A6),-(SP)               
I 040001CE # +004A   MOVE.L     $000C(A6),-(SP)               
I 040001D2 # +004E   _FillBox
I 040001DA # +0056   LEA        $0024(SP),SP                  
I 040001DE # +005A   MOVE.L     (SP)+,D3                      
I 040001E0 # +005C   UNLK       A6                            
I 040001E2 # +005E   RTS                                      

The ir command starts showing code at the current instruction and continues to the end of the function. The program counter is marked with an asterisk just before the instruction disassembly. In this display, the asterisk is at the LINK instruction. You can compare this display to the source code for this method, shown here:

Method void
Greeter_Draw(ObjectID self, ObjectID canvas, ObjectID clip)
{
	Box 		ourContentBox;
	ulong		color;

	color = PartColor(self, Hilited(self) ? partAltContent :
partContent);
	
	ContentBox(self, &ourContentBox);
	FillBox(canvas, clip, &ourContentBox, color, pixelDither |
pixelCopy);
}	

Telebug defines various other commands for disassembling instructions. For more information, see the Telebug Reference section below, or type command-? in Telebug for online help.

Context and Clusters

Magic Cap defines a current context that determines which clusters can be used by each package. You can see the clusters available in the current context by using Telebug's con (context) command:

con
context for package HelloWorld
      Start         Class       Size      Free                  Slot
cdump 00096D40 #   Cluster      00014000  00012BA0    #7% full   8   #0 (system persistent)
cdump 00080060 #   Cluster      00000FE0  00000000  #100% full   88  #1 (locked persistent)
cdump 00080010 #   MetaCluster  0007FF70  00046F18   #45% full   A   #4 (RAM)
cdump 00012B18 #   MetaCluster  0006B4E8  00002078   #99% full   A8  #5 (transient RAM)
cdump 0007B888 #   Cluster      00000800  00000578   #32% full   B   #6 (package persistent)
cdump 0007C094 #   Cluster      00000200  00000128   #43% full   C   #8 (package transient)
cdump 006E2684 #   MetaCluster  0011AFEC  00000000  #100% full   C8  #9 (vendor ROM)
cdump 00044C08 #   Cluster      00026000  00017328   #39% full   D  #10 (system transient)
cdump 0400007C #   MetaCluster  00000CD0  00000000  #100% full   E  #12 (card 1)
cdump 00012B68 #   Cluster      00032000  00000114  #100% full   E8 #13 (locked transient)
cdump 00401142 #   MetaCluster  002E1520  00000000  #100% full  10  #16 (ROM, system persistent source)
cdump 0008E108 #   Cluster      00008468  000022A4   #74% full  11  #17 (system persistent committed shadow)
cdump 04000124 #   Cluster      00000B7C  00000000  #100% full  12  #18 (package persistent source)
cdump 00088D58 #   Cluster      00000680  000003A4   #44% full  13  #19 (package persistent committed shadow)

NOTE: The con command shows the clusters in the current context. The first line of its output identifies the context. In this example, because Magic Cap stopped while executing the package's code, the package's context is current. If you enter Telebug when another context, such as the system, is current, your package clusters won't be listed in the output from con and you won't be able to access your package's objects with other commands. If you see the message Unable to access that address when trying to see an object, you're probably not in the package context.

There are two techniques you can use to make sure you stop in the package context:

  1. Set a breakpoint in the package's code.
  2. Touch a package object, and before releasing your touch, press command-<period> on the Macintosh to enter Telebug.
When in Telebug, you can always find out which cluster is current by typing con and checking the first line of its output.

Using information from the con command, you can use the cdump (cluster dump) command to show information about all the objects in any cluster listed. When you build and run your package on a communicator, CodeWarrior Magic/MPW puts the package on a RAM card, so you can use cdump to show all the objects on the RAM card.

Because Telebug uses MPW Shell windows, you can display any cluster listed in the output of a con command by clicking on the line that contains the cluster you want and pressing enter:

cdump 0400007C 
#   MetaCluster  00000CD0  00000000  #100% full   E  #12 (card 1)
Displaying cluster at 0400007C

  Start     Class                    Length    Object    ELPONVA!M.C  Name
| 040000CC  ClassList              # 000010    000003     Ì   ÌÌ      
| 040000E8  OperationList          # 000008    000004     Ì   ÌÌ      
| 040000FC  IntrinsicList          # 000008    000005     Ì   ÌÌ      
| 04000110  ObjectList             # 000008    000006     Ì   ÌÌ      
| 04000124  Cluster                # 000B7C    000007     Ì   ÌÌ      
| 04000CAC  StringList             # 000020    000001     Ì   ÌÌ      
| 04000CD8  StringDictionary       # 00000C    00000A     Ì   ÌÌ      
| 04000CF0  StringList             # 000020    000008     Ì   ÌÌ      
| 04000D1C  __MasterBlock__        # 000030    000000     Ì   ÌÌ      

 #9 objects displayed, #8 real ones (not free or master-block)
 000000 bytes free
 000C8C bytes used
 000000 bytes purgeable
 000C8C total bytes
 000009 objects accessed
   0% free
  
This works because each line of the con output begins with a cdump command, followed by #, which is the Telebug comment character. The comment character causes Telebug to ignore the rest of the line when you press enter.

This cluster contains few objects, including another cluster, which in turn contain objects on the RAM card. Note that the Object column shows only the lower portion of each object's ID. To form an object ID, prefix the cluster's slot number to the value in the Object column. For example, the second object in the cluster above has 000004 in the Object column. Because you're looking at cluster E, the object's ID is $E0000004. You can use either the object ID or the object's address for many Telebug commands, including dobj and cdump.

NOTE: The cdump command sometimes executes very slowly if the cluster includes many named objects. To speed up its operation, hold down the shift key while it executes. This suppresses the display of object names but makes cdump execute much more quickly. You can use this trick to speed up other commands that display object names, such as dobj, but it's most useful with cdump.

You can find out more about your package by looking at its software package object. The software package object is inside the cluster at $04000124, listed in the cdump display above. Use another cdump command to see the objects in this cluster:

cdump e0000007
Displaying cluster at 04000124

  Start     Class                    Length    Object    ELPONVA!M.C  Name
| 04000174  Code                   # 00008C    00001F     Ì  ÌÌÌ      Greeter
| 0400020C  Class                  # 00007C    000020     Ì  ÌÌÌ      Greeter
| 04000294  ClassList              # 000020    000021     Ì   ÌÌ      
| 040002C0  OperationList          # 000008    000022     Ì   ÌÌ      
| 040002D4  DirectDispatchList     # 000004    000023     Ì   ÌÌ      
| 040002E4  IntrinsicList          # 000008    000024     Ì   ÌÌ      
| 040002F8  SoftwarePackage        # 0000C8    00001C     Ì  ÌÌÌ      HelloWorld
| 040003CC  Telename               # 000008    000009     Ì   ÌÌ      
| 040003E0  ObjectList             # 00000C    000002     Ì  ÌÌÌ      Install
| 040003F8  ObjectList             # 00000C    000003     Ì  ÌÌÌ      Receiver
| 04000410  ObjectList             # 000008    000005     Ì  ÌÌÌ      Standard Places
| 04000424  ObjectList             # 000008    000006     Ì  ÌÌÌ      Objects With Help
| 04000438  ObjectList             # 000008    000007     Ì  ÌÌÌ      Help On Objects
| 0400044C  Scene                  # 000054    00000C     Ì  ÌÌÌ      HelloWorld
| 040004AC  Greeter                # 000038    00000E     Ì  ÌÌÌ      Hello World
| 040004F0  Citation               # 000010    000004     Ì   ÌÌ      
| 0400050C  Text                   # 000049+3  00000F     Ì   ÌÌ      
| 04000564  Identifier             # 000000    000008     Ì  ÌÌÌ      HelloWorld
| 04000570  AddressCard            # 000034    000001     Ì  ÌÌÌ      General Magic DTS
| 040005B0  ObjectList             # 000008    000010     Ì   ÌÌ      
| 040005C4  MagicmailName          # 000008    000011     Ì  ÌÌÌ      General Magic DTS
| 040005D8  Image                  # 0002CA+2  000012     Ì  ÌÌÌ      General Magic DTS
| 040008B0  PostalLabe|            # 000028    000013     Ì  ÌÌÌ      main office
| 040008E4  Text                   # 00000D+3  000014     Ì   ÌÌ      
| 04000924  Text                   # 000002+2  000017     Ì   ÌÌ      
| 04000934  Text                   # 00000F+1  000018     Ì   ÌÌ      
| 04000950  ObjectList             # 000008    000019     Ì   ÌÌ      
| 04000964  Text                   # 000011+3  00001A     Ì   ÌÌ      
| 04000984  NameKey                # 00000C    00001B     Ì   ÌÌ      
| 0400099C  NameCard               # 00004C    00000D     Ì  ÌÌÌ      General Magic DTS
| 040009F4  OctetString            # 000011+3  00000A     Ì   ÌÌ      
| 04000A14  OctetString            # 00000B+1  00000B     Ì   ÌÌ      
| 04000A2C  ObjectList             # 00000C    000025     Ì   ÌÌ      
| 04000A44  StringList             # 000020    00001D     Ì   ÌÌ      
| 04000A70  StringDictionary       # 00004C    000028     Ì   ÌÌ      
| 04000AC8  StringList             # 0000F4    000026     Ì   ÌÌ      
| 04000BC8  PackageBoot            # 000020    000029     Ì   ÌÌ      
| 04000BF4  __MasterBlock__        # 0000AC    000000     Ì   ÌÌ      

 #40 objects displayed, #39 real ones (not free or master-block)
 000000 bytes free
 000B38 bytes used
 000000 bytes purgeable
 000B38 total bytes
 000028 objects accessed
   0% free
The software package object is the seventh object listed in this display. Use dobj to look at the software package object:
dobj 040002F8
| $040002F8 # SoftwarePackage       size:$0000C8   #:$0000001C
Displaying SoftwarePackage at 040002F8
o           AbstractList
o           040002F8  length          00000020 
o         FixedList
o       ObjectList
o         HasIndexing
o     RootList
o       HasDate
o       040002FC  dateCreated         0000C289 
o       04000300  timeCreated         FFFFFFFF 
o       04000304  dateModified        0000C289 
o       04000308  timeModified        FFFFFFFF 
o   PackageRootList
o   0400030C  author                  B0000001 
o   04000310  installList             B0000002 
o   04000314  receivers               B0000003 
o   04000318  installFlags            00000000 
o   0400031C  installParameters       00000000 
o   04000320  installTargets          00000000 
o   04000324  autoActivate            1
o   04000324  pad1                    0000000000000000000000000000000
o SoftwarePackage
o 04000328  citation                  B0000004 
o 0400032C  publisher                 B0000001 
o 04000330  persistentShadowSize      00000000 
o 04000334  persistentChangesSize     00000000 
o 04000338  transientSize             00000000 
o 0400033C  gotoActionSelector        0003 
o 0400033E  hidden                    0
o 0400033E  dontSaveData              0
o 0400033E  copyOnActivate            0
o 0400033E  dontDeactivate            0
o 0400033E  needsReset                0
o 0400033E  systemPackageReserved6    0
o 0400033E  systemPackageReserved7    0
o 0400033E  systemPackageReserved8    0
o 0400033F  systemPackageReserved9    0
o 0400033F  systemPackageReserved10   0
o 0400033F  systemPackageReserved11   0
o 0400033F  systemPackageReserved12   0
o 0400033F  systemPackageReserved13   0
o 0400033F  systemPackageReserved14   0
o 0400033F  systemPackageReserved15   0
o 0400033F  systemPackageReserved16   0
o 04000340  entry1                    00000000
o 04000344  entry2                    00000000
o 04000348  entry3                    00000000
o 0400034C  entry4                    00000000
o 04000350  entry5                    00000000
o 04000354  entry6                    B0000005
o 04000358  entry7                    00000000
o 0400035C  entry8                    00000000
o 04000360  entry9                    B0000006
o 04000364  entry10                   B0000007
o 04000368  entry11                   00000000
o 0400036C  entry12                   00000000
o 04000370  entry13                   83050007
o 04000374  entry14                   00000000
o 04000378  entry15                   8300C0B7
o 0400037C  entry16                   00000000
o 04000380  entry17                   00000000
o 04000384  entry18                   00000000
o 04000388  entry19                   00000000
o 0400038C  entry20                   00000000
o 04000390  entry21                   00000000
o 04000394  entry22                   00000000
o 04000398  entry23                   00000000
o 0400039C  entry24                   00000000
o 040003A0  entry25                   00000000
o 040003A4  entry26                   00000000
o 040003A8  entry27                   00000000
o 040003AC  entry28                   00000000
o 040003B0  entry29                   00000000
o 040003B4  entry30                   00000000
o 040003B8  entry31                   00000000
o 040003BC  entry32                   00000000
  
You can use the software package object to see the install list and the receiver list, the structures that tell Magic Cap which package objects to install and where to put them. The installList and receivers fields refer to these lists. First, look at the install list:
dobj B0000002
| $040003E0 # ObjectList          $B0000002  size:$00000C   #:$00000002  flags:´´´NVA´´´´
# Name: Install
Displaying ObjectList at 040003E0
o     AbstractList
o     040003E0  length                00000002 
o   FixedList
o ObjectList
o   HasIndexing
o 040003E4  entry1                    B000000C
o 040003E8  entry2                    B000000D
  
The install list has two entries. You can look at them with dobj:
dobj B000000C
| $0007BA78 # Scene               $B000000C  size:$000054   #:$0000000C  flags:´´´NV´´´´´
# Name: HelloWorld
Displaying Scene at 0007BA78
o           SingleLinkable
o           0007BA78  next            8000030F 
o         Linkable
o           HasIndexing
o         0007BA7C  previous          00000000 
o       Viewable
o       0007BA80  superview           80000448 
o       0007BA84  subview             B000000E 
o       0007BA88  relativeOrigin      00 00 00 00 FF FF F8 00 
o       0007BA90  contentSize         00 01 E0 00 00 01 00 00 
o       0007BA98  viewFlags           11005220 
o       0007BA9C  labelStyle          83078001 
o       0007BAA0  color               FF555555 
o       0007BAA4  altColor            FF000000 
o       0007BAA8  shadow              00000000 
o       0007BAAC  sound               00000000 
o     Box
o       HasBorder
o       0007BAB0  border              00000000 
o   Panel
o Scene
o 0007BAB4  sceneFlags                00000000 
o 0007BAB8  stepBackScene             8000051F 
o 0007BABC  stepBackSpot              800024BE 
o 0007BAC0  image                     00000000 
o 0007BAC4  additions                 00000000 
o 0007BAC8  screen                    00000000 

This display shows that the first object in the install list is HelloWorld's scene. Now look at the other object to be installed:

dobj B000000D
| $00088F40 # NameCard            $B000000D  size:$00004C   #:$0000000D  flags:´´´NV´´´´´
# Name: General Magic DTS
Displaying NameCard at 00088F40
o         SingleLinkable
o         00088F40  next              00000000 
o       Linkable
o         HasIndexing
o       00088F44  previous            00000000 
o     Viewable
o     00088F48  superview             00000000 
o     00088F4C  subview               00000000 
o     00088F50  relativeOrigin        FF FF E4 00 00 00 08 00 
o     00088F58  contentSize           00 01 88 00 00 00 E5 00 
o     00088F60  viewFlags             50005200 
o     00088F64  labelStyle            83078001 
o     00088F68  color                 00000000 
o     00088F6C  altColor              00000000 
o     00088F70  shadow                00000000 
o     00088F74  sound                 00000000 
o   Card
o   00088F78  form                    8306C00B 
o   00088F7C  stack                   800000DF 
o   00088F80  cardFlags               404000E7 
o NameCard
o 00088F84  addressCard               B0000001 
o 00088F88  profile                   00000000 
  
The second object to be installed is the name card for General Magic DTS. Now you can look at the receiver list, getting the list's object ID from the software package object's receivers field:
dobj B0000003
l $040003F8 # ObjectList          $B0000003  size:$00000C   #:$00000003  flags:´´´NVA´´´´
# Name: Receiver
Displaying ObjectList at 040003F8
o     AbstractList
o     040003F8  length                00000002 
o   FixedList
o ObjectList
o   HasIndexing
o 040003FC  entry1                    83050007
o 04000400  entry2                    8307A006

You can check the entries in the receiver list to see if they match with the objects to be installed in them. The first entry:

dobj 83050007
l $040003F8 # ObjectList          $B0000003  size:$00000C   #:$00000003  flags:´´´NVA´´´´
# Name: Receiver
Displaying ObjectList at 040003F8
o     AbstractList
o     040003F8  length                00000002 
o   FixedList
o ObjectList
o   HasIndexing
o 040003FC  entry1                    83050007
o 04000400  entry2                    8307A006

The digit 3 in the second nibble of an object ID indicates that the ID is an indexical. This object is the hallway; it corresponds to the HelloWorld scene, the first entry in the install list. Magic Cap recognizes the scene-hallway install-receive pair and creates a door in the hallway that leads to the given scene.

Now look at the second entry in the receiver list:

dobj 8307A006
# Indexical $8307A006 "iNameCardsStack" (list 61, entry 6) is:
l $0008FD70 # NameCardsStack      $800000DF  size:$000080   #:$000000DF  flags:´´´NV´´´´´
# Name: all
Displaying NameCardsStack at 0008FD70
o           AbstractList
o           0008FD70  length          0000001A 
o         FixedList
o       ObjectList
o         HasIndexing
o     DenseObjectList
o   StackOfCards
o   0008FD74  protoCard               800000AD 
o   0008FD78  stackFlags              00000003 
o   0008FD7C  stackScene              800000AE 
o NameCardsStack
o 0008FD80  displaySize               00000000 
o 0008FD84  entry1                    800000AF
o 0008FD88  entry2                    8200246B
o 0008FD8C  entry3                    82002464
o 0008FD90  entry4                    800000B0
o 0008FD94  entry5                    800000B1
o 0008FD98  entry6                    800000B2
o 0008FD9C  entry7                    800000B3
o 0008FDA0  entry8                    800000B4
o 0008FDA4  entry9                    800000B5
o 0008FDA8  entry10                   800000B6
o 0008FDAC  entry11                   800000B7
o 0008FDB0  entry12                   820024CB
o 0008FDB4  entry13                   800000B8
o 0008FDB8  entry14                   82002471
o 0008FDBC  entry15                   800000B9
o 0008FDC0  entry16                   800000BA
o 0008FDC4  entry17                   800000BB
o 0008FDC8  entry18                   800000BC
o 0008FDCC  entry19                   8200247B
o 0008FDD0  entry20                   800000BD
o 0008FDD4  entry21                   82002454
o 0008FDD8  entry22                   800000BE
o 0008FDDC  entry23                   82002479
o 0008FDE0  entry24                   800000BF
o 0008FDE4  entry25                   800000C0
o 0008FDE8  entry26                   800000C1
  
This entry, the name cards stack, gets the second installed object, the DTS name card. When the package is unpacked, the DTS name card goes into the name cards stack where it belongs.

If the communicator is running, you can quit Telebug by typingcommand-esc. If the communicator is stopped when you quit Telebug, it will remain stopped and you will have to reset it or restart Telebug to get the communicator going again.

That's the end of the tour. This tour covered several of the most important Telebug commands, including br, dobj, con, and cdump, and demonstrated how you can use the commands to navigate through your objects and find information. For complete information on Telebug commands, see Telebug's online help or the Telebug Reference section below.

Telebug Reference

This section lists Telebug commands and expression syntax. You can enter Telebug commands in upper or lower case. Telebug itself includes online help, which you can see by typing command-?.

----------------------------------------------------------------------
Command              Description  
----------------------------------------------------------------------                                                                      
AUTOSOURCE <ON |       If on, display source code automatically         
OFF>                   when Telebug is entered.                         
BEEP                   Sound the Macintosh speaker.                     
BITS                   Display a value as formatted binary digits.      
BO <opname>            Set breakpoint on operation <opname>.            
BOC [<opname>]         Clear breakpoint on given operation, or all      
                       operation breakpoints if <opname> omit           
                       ted.                                             
BOD                    List operation breakpoints.                      
BR [<addr>] [`condi    If <addr> is omitted, list breakpoints. Oth      
tion;action']          erwise, set breakpoint at <addr>. If <condi      
                       tion> is given, only break if it is true. If     
                       <action> is given, perform it on break.          
BRC [<addr>]           Clear breakpoint at <addr>, or all break         
                       points if <addr> is omitted.                     
BREAK [<addr>]         Same as BR.                                      
BREAKOP <opname>       Same as BO.                                      
CDUMP <cluster>        Display all objects in given cluster, which      
[\<ClassName>]          can be specified as context slot, address, or    
                       object ID. If <ClassName> is present, only       
                       show objects of that class. Hold shift key for   
                       faster display without object names.             
CL [<addr>]            Same as BRC.                                     
CLEAR [<addr>]         Same as BRC.                                     
DB <addr>              Display byte at <addr>.                          
DL <addr>              Display long word at <addr>.                     
DM <addr> [<class> |   Display memory at <addr>. If <class> is          
<count>]               present, display memory as object of that        
                       class. If <count> is present, display            
                       <count> bytes of memory. See also DOBJ.          
DW <addr>              Display word at <addr>.                          
DX                     Enable or disable user breaks.                   
ECHO <quotedString>    Print <quotedString> to worksheet.               
EF                     Display 68349 exception frame at stack           
                       pointer.                                         
EXC <exceptionNum>     Same as EXCEPTION.                               
EXCEPTION <excep       Display name of given exception.                 
tionNum>                                                                
EXEC <filename>        Execute Telebug commands in given file.          
EXIT                   Same as QUIT                                     
FB <addr> <len>        Fill memory starting at <addr> with <byte>       
<byte>                 byte value for <len> bytes.                      
FL <addr> <len>        Fill memory starting at <addr> with <long>       
<long>                 long word value for <len> bytes.                 
FW <addr> <len>        Fill memory starting at <addr> with              
<word>                 <word> word value for <len> bytes.               
G                      Same as GO.                                      
GETCLASS <classNum>    Display name of given class.                     
GETINDEXICAL [<in      Display name of given indexical, which           
dexicalNum>]           should specified as an object ID with usable     
                       bit set. If GETINDEXICAL returns <un             
                       known>, add $04000000 to object ID and           
                       try again.                                       
GETINT [<intNum>]      Display name of given intrinsic.                 
GETOBJ <objectID>      Display information about given object.          
GETOP <opNum>          Display name of given operation.                 
GETSCREEN              Copy the communicator screen to the Mac          
                       intosh and save as PICT file.                    
GO [ASYNC]             Resume execution (same as  -1). If ASYNC         
                       parameter is present, return control to Tele     
                       bug.                                             
GT <addr>              Go until <addr>, then break.                     
HELP                   Show help window (same as  -?).                  
HOW                    Show how Telebug was entered.                    
ID <addr>              Disassemble one instruction at <addr>, or at     
                       PC if <addr> is omitted.                         
IF                     Begin conditional execution.                     
IFDEF <varname>        Begin conditional execution if variable          
                       <varname> is defined. Variables are de           
                       fined with the = operator.                       
IFNDEF <varname>       Begin conditional execution if <varname>         
                       is not defined.                                  
IL <addr>              Disassemble 16 instructions at <addr>, or at     
                       PC if <addr> is omitted.                         
INTS <ON|OFF>          Turn interrupts on or off during STEP.           
IP <addr>              Disassemble 16 instructions around <ad           
                       dr>, or around PC if <addr> is omitted.          
IR <addr>              Disassemble from <addr> to end of func           
                       tion, or from PC if <addr> is omitted.           
MR                     Go until return address on the stack is          
                       reached.                                         
MR6                    Go until return address in A6 stack frame is     
                       reached.                                         
Q                      Same as QUIT.                                    
QUIT                   Quit Telebug application.                        
RB                     Destroy persistent data in communicator          
                       and restart it, then break into Telebug.         
RE                     Same as RESET.                                   
RESET                  Restart communicator without harming             
                       persistent data, then break into Telebug.        
RS                     Same as RESET.                                   
S                      Same as STEP.                                    
SB <addr> <byte>       Set byte at <addr> to <byte>.                    
SC                     Show calling chain based on A6 links.            
SC7                    Show calling chain based on stack address        
                       es.                                              
SH                     Same as SHOWCOMMAND.                             
SHOWCOMMAND `<com      Execute given command every time Tele            
mand>`                 bug is entered and display the results in a      
                       new window.                                      
SHOWREGS               Show registers in a window (same as  -E).        
SHOWSTACK              Show CPU stack in a window (same as  -           
                       K).                                              
SL <addr> <long>       Set long word at <addr> to <long>.               
SM <addr> <data>       Set memory at <addr> to <data>.                  
SO                     Step over next instruction (same as  -T).        
SOURCE <ON|OFF>        Turn source debugging on or off. If you turn     
                       it off, then back on, reopen the symbol file     
                       with the USE command.                            
SOURCEPATH <path       Use given directory path for package             
name>                  source.                                          
SS <addr>              Step until long word at <addr> changes.          
                       This is very slow.                               
ST <addr>              Same as STEPTILL.                                
STEP <count>           Execute <count> instructions, or one in          
                       struction if <count> is omitted (same as  -      
                       S).                                              
STEPTILL <addr>        Step until PC reaches <addr>.                    
STF <addr>             Step until PC reaches <addr>, ignoring           
                       BGND instructions.                               
SW <addr> <word>       Set word at <addr> to <word>.                    
T                      Same as SO.                                      
TD                     Display all CPU registers.                       
TF                     Display recent values of PC after ST or SF.      
TRYTOEXEC <filename>   Execute Telebug commands in given file. If       
                       file doesn't exist, do nothing.                  
USE <symfile>          Use given file for debugging symbols.            
VER                    Display version of Telebug software and in       
                       terface box.                                     
WAIT                   Wait until communicator hardware returns         
                       to Telebug.                                      
WH <addr>              Display source for instruction at <addr>.        
----------------------------------------------------------------------

--------------------------------------------------------------------                                                                    
Expression Syntax           Description                             
--------------------------------------------------------------------                                                                    
!                           not                                     
!=                          not equal to                            
#                           decimal number                          
$                           hex number                              
&                           bitwise AND                          
  
&&                          logical AND                      
      
'                           quoted string                           
*                           multiplication                          
+                           addition                                
-                           subtraction                             
/                           division                                
0x                          hex number (C style)                    
<                           less than                             
 
<<                          bit shift left                     
    
<=                          less than or equal to                 
 
=                           assignment                              
==                          equality                                
>                           greater than                          
 
>=                          greater than or equal to              
 
>>                          bit shift right                    
    
@                           dereference                             
                                                                    
ATEMP                       Temporary register A                    
AVR                         hardware register                       
CS0Base                     hardware register                       
CS0Mask                     hardware register                       
CS1Base                     hardware register                       
CS1Mask                     hardware register                       
CS2Base                     hardware register                       
CS2Mask                     hardware register                       
CS3Base                     hardware register                       
CS3Mask                     hardware register                       
DDRA                        hardware register                       
DDRB                        hardware register                       
DFC                         Destination function code register      
FAR                         Fault address register                  
MBAR                        hardware register                       
PC                          Current program counter                 
PCC                         Current instruction program counter     
                            (in background mode)                    
PICR                        hardware register                       
PITR                        hardware register                       
PORTA                       hardware register                       
PORTB                       hardware register                       
PORTB1                      hardware register                       
PPARB                       hardware register                       
PPRA1                       hardware register                       
PPRA2                       hardware register                       
RPC                         Return program counter (in background   
                            mode)                                   
RSR                         hardware register                       
SFC                         Source function code register           
SIMMCR                      hardware register                       
SP                          Stack pointer                           
SR                          Status register                         
SSP                         Supervisor stack pointer                
SWIV                        hardware register                       
SWSR                        hardware register                       
SYNCR                       hardware register                       
SYPCR                       hardware register                       
USP                         User stack pointer                      
VBR                         Vector base register                    
VBR                         Vector base register                    
--------------------------------------------------------------------                                                                    

How Telebug Works

The Motorola 68349 CPU in Magic Cap-based communicators includes a special mode of operation called background mode. When the CPU enters background mode, all normal processor operation stops and only a small number of operations are supported, including memory and register reads and writes and single-step execution.

The CPU enters background mode when it executes a BGND opcode, the communicator equivalent of a debugger break. Telebug is constantly monitoring the status of the CPU during normal program execution. When Telebug notices the processor has entered background mode, it takes control. Alternately, you can force the CPU into background mode while the communicator is running by typing command- <period>.

Sample Debugging Session

This section shows you how to use MacsBug to help find and fix problems in your packages. The example used in this chapter is a modified version of the HelloWorld sample named BuggyHelloWorld. MacsBug was chosen instead of Telebug because you'll probably do most of your debugging with MacsBug. You'll probably use Telebug if you have problems that only appear when your package runs on communicators.

You can follow along by starting Magic Cap Simulator and opening BuggyHelloWorld, which is provided with CodeWarrior Magic/MPW. This version of HelloWorld has been enhanced to allow its greeter objects to accept image coupons. You can test this by opening the stamper, getting any stamp, opening the Tools window, option-touching the title bar of the Tools window to see the authoring tools, touching the Tinker tool (the wrench), then touching the stamp to tinker with it.

With the stamp's tinkering window open, drag the image coupon out and drop it on the greeter. When you release the image coupon over the greeter, Magic Cap stops and you see the debugger, with the following message:

User break at 00CEA1EE MethodNotFound+0034

 method not found (return address on stack, step over RTS to
continue)
This is a method not found error, one of the most common problems you'll find when debugging packages. This error indicates that Magic Cap tried to call an operation of a particular class, but found that neither that class nor any of its superclasses define the operation. When your package is running on Magic Cap Simulator, method not found errors cause a break into MacsBug.

NOTE: Method not found errors are detected because the simulator is a special debug version of Magic Cap that's not present in communicators. When your package is running on a communicator, method not found errors are ignored. For this reason, the simulator and MacsBug are useful for detecting these bugs.

To find out what caused the error, step through your code using the t (trace) command until you reach an RTS (return from subroutine) instruction:

t
Step (over)
  MethodNotFound
     +0034  00CEA1EE   MOVEM.L    (A7)+,D0-D2/A0/A1                       | 4CDF 0307
t
     +0038  00CEA1F2   MOVEQ      #$00,D0                                 | 7000
t
     +003A  00CEA1F4   RTS                                                | 4E75
You could also use the s (step); command. These two commands differ only in how they act when the current instruction is JSR (jump to subroutine) or BSR (branch to subroutine): t treats the whole subroutine as a single instruction, stopping again only after the subroutine has been executed, while s steps into the subroutine, stopping after the first instruction in the subroutine. Most of the time, you'll want to use t to avoid lengthy stepping through Magic Cap methods, so using t for stepping through code is a good habit to form.

After stepping past the RTS, the program counter is now at the instruction following the one that caused the error. List the code:

ip
 Disassembling from 0108D97C
  Greeter_Draw
     +0030  0108D97C   MOVE.L     D7,-(A7)                                | 2F07
     +0032  0108D97E   _Origin                                            | 7443 4EAD FFE0
     +0038  0108D984   PEA        -$0008(A6)                              | 486E FFF8
     +003C  0108D988   MOVE.L     D5,-(A7)                                | 2F05
     +003E  0108D98A   MOVE.L     D6,-(A7)                                | 2F06
     +0040  0108D98C   MOVE.L     D7,-(A7)                                | 2F07
     +0042  0108D98E   _DrawImage                                         | 343C 01C1 4EAD ƒ
     +004A  0108D996  *LEA        $0018(A7),A7                            | 4FEF 0018
     +004E  0108D99A   BRA.S      Greeter_Draw+0098          ; 0108D9E4   | 6048
     +0050  0108D99C   MOVE.L     D7,-(A7)                                | 2F07
     +0052  0108D99E   _Hilited                                           | 742C 4EAD FFFA
     +0058  0108D9A4   TST.B      D0                                      | 4A00
     +005A  0108D9A6   ADDQ.W     #$4,A7                                  | 584F
     +005C  0108D9A8   BEQ.S      Greeter_Draw+0062          ; 0108D9AE   | 6704
     +005E  0108D9AA   MOVEQ      #$03,D0                                 | 7003
     +0060  0108D9AC   BRA.S      Greeter_Draw+0064          ; 0108D9B0   | 6002
     +0062  0108D9AE   MOVEQ      #$01,D0                                 | 7001
 
The second line of this display shows that the error occurred in the Greeter_Draw method. The asterisk (*) in this listing shows the program counter, and the bullet (*) indicates the location of a breakpoint. The instruction that caused the error is always the one immediately before the program counter, the DrawImage call. MacsBug is reporting that it tried to call DrawImage on some object, but that object's class doesn't define DrawImage.

Whenever you see a method not found error, you should respond with the same commands: trace (or step) three times, then list instructions with ip.

Next, find out which object was used to call DrawImage. Following a method not found error, the parameters to the ill-fated method call are still on the stack, with the responder (the self parameter) at the top of the stack, so you can see the responder by examining the object ID at the top of the stack:

dobj @sp
 $01069720 Greeter                 $B400000E  size:$00003C   #:$0000000E  flags:´´´NV´´´´´
  Name: Hello World
  Displaying Greeter at 01069720
  o       SingleLinkable
  o       01069720  next                B000002C 
  o     Linkable
  o       HasIndexing
  o     01069724  previous              00000000 
  o   Viewable
  o   01069728  superview               B000000C 
  o   0106972C  subview                 00000000 
  o   01069730  relativeOrigin          00 00 00 00 FF FF F2 00 
  o   01069738  contentSize             00 00 5A 00 00 00 5A 00 
  o   01069740  viewFlags               7818D220 
  o   01069744  labelStyle              83078001 
  o   01069748  color                   FFFFFFFF 
  o   0106974C  altColor                FF000000 
  o   01069750  shadow                  00000000 
  o   01069754  sound                   00000000 
  o Greeter
  
Now you know that the package tried to call the DrawImage operation of the Greeter object. By checking the source for BuggyHelloWorld and using the Find Method command in Bowser Pro, you can see that neither class Greeter nor any of its superclasses define the DrawImage operation.

Look at the source for Greeter_Draw to confirm the problem:

Method void
Greeter_Draw(ObjectID self, ObjectID canvas, ObjectID clip)
{
	ObjectID	image = Image(self);
	
	if (HasObject(image)) {
		Dot		boxOrigin;
		
		Origin(self, &boxOrigin);
		DrawImage(self, canvas, clip, &boxOrigin);
	} else {
		Box 		ourContentBox;
		ulong		color;
	
		color = PartColor(self, Hilited(self) ? 
					partAltContent : partContent);
		ContentBox(self, &ourContentBox);
		FillBox(canvas, clip, &ourContentBox, color, 
					pixelDither | pixelCopy);
	}
}

The offending call to DrawImage is shown in bold. Because self is a greeter, Magic Cap tries to call Greeter_DrawImage. There is no such method, so the error occurs. Because DrawImage is defined by class Image, the most likely correction here is to call DrawImage on the greeter's image instead of self:

 
DrawImage(image, canvas, clip, &boxOrigin); 

If you want to follow along, you can quit Magic Cap, make the correction to BuggyHelloWorld.c, rebuild, and run again. If you don't want to make the correction and rebuild, just quit Magic Cap and run the package again to restore its pristine state.

BuggyHelloWorld adds a feature that lets users drop text coupons on greeter objects, then reverses the text in the coupon and uses it to rename the object. Try it: option-touch the keyboard to open it with the label maker, type some text, tear off the text coupon, and drop it on the greeter.

Magic Cap stops and you see the debugger:

User break at 00CEA1EE MethodNotFound+0034
 method not found (return address on stack, step over RTS to continue)
As before, you should respond by tracing three times, then listing instructions:
t
Step (over)
  MethodNotFound
     +0034  00CEA1EE   MOVEM.L    (A7)+,D0-D2/A0/A1                       | 4CDF 0307
t
     +0038  00CEA1F2   MOVEQ      #$00,D0                                 | 7000
t
     +003A  00CEA1F4   RTS                                                | 4E75
ip
 Disassembling from 00E36FEC
  Viewable_SetTextData
     +0030  00E36FEC   MOVEQ      #$00,D0                                 | 7000
     +0032  00E36FEE   MOVE.L     D0,-(A7)                                | 2F00
     +0034  00E36FF0   MOVE.L     D7,-(A7)                                | 2F07
     +0036  00E36FF2   _SetUseScriptName                                  | 343C 03AA 4EAD ƒ
     +003E  00E36FFA   MOVE.L     A4,-(A7)                                | 2F0C
     +0040  00E36FFC   MOVE.L     $000C(A6),-(A7)                         | 2F2E 000C
     +0044  00E37000   _TextToString                                      | 343C 04FB 4EAD ƒ
     +004C  00E37008  *MOVE.L     A4,-(A7)                                | 2F0C
     +004E  00E3700A   MOVE.L     D7,-(A7)                                | 2F07
     +0050  00E3700C   _SetName                                           | 343C 0249 4EAD ƒ
     +0058  00E37014   MOVE.L     D7,-(A7)                                | 2F07
     +005A  00E37016   _AdjustSize                                        | 343C 014A 4EAD ƒ
     +0062  00E3701E   _DoDirty                                           | 702D 4EAD FFD0
     +0068  00E37024   TST.B      D6                                      | 4A06
     +006A  00E37026   LEA        $001C(A7),A7                            | 4FEF 001C
     +006E  00E3702A   BEQ.S      Viewable_SetTextData+007A  ; 00E37036   | 670A
     +0070  00E3702C   MOVE.L     D7,-(A7)                                | 2F07

This time, the error occurred in Viewable_SetTextData when it tried to call TextToString. Viewable_SetTextData is a method that's part of Magic Cap, not the package. Does this indicate a bug in Magic Cap? You can find out by investigating further. First, check the responder. Remember that after a method not found, the parameters are still on the stack, with the responder at the top:

dobj @sp
object not found
This message from MacsBug indicates that the value at the top of the stack is either invalid or is an object ID for an object that has been destroyed. Now you know the reason for the method not found error: Magic Cap tried to find a method of an object that doesn't exist. You can take a look at the offending object ID by simply showing the value on the top of the stack and not trying to use it as an object ID:
dm sp
 Displaying memory from sp
  0102E668  B400 002C 0102 E684  B400 000E 0000 0000  ´´´,´´´´´´´´´´´´
The first four bytes, $B400 002C, are the object ID at the top of the stack. Next, look at the recent calls to see if that object ID was passed in as a parameter by a caller:
sc
  A6 Link  CallerPC Caller                  Params
  0102EAA8 00CE6988 CallMain+0074           D400 0019 0000 0000 0000 0000 0000 0000 0000 
  0102EA76 00CE3292 UserActor_Main+023E     D400 0019 0000 0000 BADD BADD BADD BADD BADD 
  0102EA4A 00CE2506 TouchInput_Dispatƒ+00CA D420 009A BADD BADD BADD BADD BADD BADD BADD 
  0102EA3A 00E20C78 TouchTool_TouchTaƒ+0012 8400 0C95 8400 04CE D420 009A BADD BA01 D420 
  0102EA0E 00CD0674 LabelMaker_Touch+0110   8400 04CE D420 009A 0102 EA76 00CE 2506 8400 
  0102E960 00E30DE0 Viewable_DragTrack+09AC 8400 24CA D420 009A 0000 0000 0000 0000 B400 
  0102E940 00E0F354 Coupon_Pressed+0022     8400 24CA D420 009A 0000 0001 0000 0001 0000 
  0102E914 00E0ED38 DropCoupon+016E         8400 24CA D420 009A B400 000E B400 000E 8400 
  0102E8DC 00E0EDC6 Coupon_ApplyAndDiƒ+0048 8400 24CA B400 000E 0102 E934 D420 009A 8400 
  0102E8C0 00E105FA TextCoupon_ApplyCƒ+0038 8400 24CA B400 000E 0102 E934 B400 000E 8400 
  0102E784 0108DB18 Greeter_SetTextDaƒ+009A B400 000E B400 002C 0000 0000 0102 E934 8400 
  0102E784 00E37008 Viewable_SetTextDƒ+004C B400 000E B400 002C 0000 0000 0102 E934 B400 

This display indicates that the object was passed to Viewable_SetTextData when it was called by Greeter_SetTextData, as indicated by the underlines (they're not present in the actual display). The display also shows that the bad object was passed in to Greeter_SetTextData by its caller. In both cases, the bad object was the second parameter passed.

Because you have the source for Greeter_SetTextData, you can look and see if anything interesting happens to its second parameter:

Method void
Greeter_SetTextData(ObjectID self, ObjectID text, Unsigned index, Dot
*where)
{
#pragma unused (index, where)
	ObjectID	textCopy;
	Str255		textData;
	ulong			endOfString;
	ulong			middleOfString;
	ushort		i;
	
	textCopy = CopyTextNear(text, self);
	Destroy(text);

	TextToString(textCopy, textData);
	
	endOfString = textData[0] + 1;
	middleOfString = endOfString >> 1;
	for (i = 1; i < middleOfString; i++) {
		uchar swappingChar;
		
		swappingChar = textData[i];
		textData[i] = textData[endOfString - i];
		textData[endOfString - i] = swappingChar;
	}
	
	ReplaceTextWithString(textCopy, textData);
	
	InheritedSetTextData(self, text, index, where);

	Assert(Sound(self) != nilObject);
	PlaySound(self);
}

The second parameter to this method is text. The first two lines of code in this method make a copy of the text, then destroy the original. The copy is then used throughout the rest of the method, until the InheritedSetTextData call, conveniently shown in bold, which passes the destroyed object as its second parameter. This is the problem: the destroyed object, which retains its object ID, is passed through until it causes a method not found error when used as the responder for a method call.

You can fix the problem by using the text copy to call the method instead:

InheritedSetTextData(self, textCopy, index, where);

This wasn't a bug in Magic Cap after all. Although Magic Cap does have bugs, you're usually better off making sure your package isn't at fault before assuming the problem is in Magic Cap. If you do find a bug in Magic Cap, please be sure to report it via your usual technical support channel.