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.
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 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.
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).
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.
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 timeThe 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 0000The 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 WorldThis 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 WorldThe 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 GreeterWhen 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 00000000This 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 0000006ANote 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 00000000This 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.
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.
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
There are two techniques you can use to make sure you stop in the package context:
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% freeThis 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 D00000DBThe 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 00000000You 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 B000000DThe 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 00000000The 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 8307A006You 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 D020008BThe 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.
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.DOA
x (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.DO
x (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. -----------------------------------------------------------------------
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.
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.
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.
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 * NOPIf 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 gAs 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,#$FFECTo 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 0000The 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 WorldThis 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 GreeterWhen 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 00000000Because 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 00000591Note 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 0000000000000000100000010000000This 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 00000000This 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.
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.
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)
There are two techniques you can use to make sure you stop in the package context:
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% freeThis 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% freeThe 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 00000000You 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 B000000DThe 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 00000000The 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 8307A006The 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 800000C1This 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.
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 QUITFB <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 --------------------------------------------------------------------
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>.
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 | 4E75You 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 | 7001The 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 GreeterNow 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 foundThis 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.