617 lines
30 KiB
Plaintext
617 lines
30 KiB
Plaintext
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GSBug is Your Friend
|
|
(a quick intro to GSBug)
|
|
v.1.2
|
|
by: Tim Swihart
|
|
|
|
|
|
|
|
So, you just got GSBug installed for the first time and don't have a clue how
|
|
to use it. Sure, you could call APDA (1-800-282-2732) and order the complete
|
|
package (part #A0037LL/A, price $30), but you're not sure if GSBug will really
|
|
help you find those nasty bugs in the Apple IIGS software you're developing.
|
|
Well, from the next paragraph until the end of this file, I'll present a quick
|
|
introduction to some of the reasons why GSBug is a "MUST HAVE" tool for all
|
|
IIGS developers. It doesn't matter what language you program in, or which
|
|
environment you use, GSBug is the key to tracking down and exterminating those
|
|
nasty bugs that make your software look shabby.
|
|
|
|
The version of GSBug that APDA currently stocks is older than the version found
|
|
on the disk containing this tutorial. So why buy APDA's version? To get the
|
|
full manual - it's well worth the thirty bucks they're asking!
|
|
|
|
|
|
Installation:
|
|
|
|
Before we can really get into it, you need to install GSBug and the
|
|
GSBug.Templates file and reboot your IIGS. If you only have one computer,
|
|
then print this file and continue reading from the printout. GSBug is an INIT
|
|
with the file name "GSBug.INIT" - install it by copying this file into your
|
|
boot disk's SYSTEM/SYSTEM.SETUP folder. Copy the "GSBug.Templates" file into
|
|
the same folder.
|
|
|
|
Over the course of time, the name used for the GSBug init file has changed
|
|
slightly. To be certain you don't accidently install two (or more) copies
|
|
of GSBug, carefully examine the contents of your boot disk's
|
|
System/System.Setup folder. If you see more than one file with a name
|
|
similar to "GSBug.init" (such as "debug.init" or "GSBug1.5B11init") then
|
|
take out all but the most recent one. Having more than one copy of GSBug
|
|
installed tends to cause problems (such as crashes during booting).
|
|
|
|
|
|
Care & Feeding of GSBug:
|
|
|
|
Now that everything is installed, reboot your computer. No need to launch any
|
|
particular application just yet, I have to explain the various parts of
|
|
GSBug's screen and I want to cover a few basic GSBug commands before we go bug
|
|
hunting. I'll assume you're running the Finder right now, but it really
|
|
doesn't matter a whole lot what application is running, as long as it is a
|
|
16-bit application (i.e.: a true IIGS desktop application).
|
|
|
|
You can pop into GSBug at any time (assuming interrupts aren't disabled) by
|
|
pressing OPEN APPLE-OPTION-CONTROL-ESC (if you're having troubles remembering
|
|
all of those keys at once, just think of it as the same keys that you use to
|
|
get to the built-in control panel plus the OPTION key). You'll be presented
|
|
with a rather busy-looking 80-column text screen. (there's a screen dump
|
|
right below this paragraph - I told you it was busy-looking screen)
|
|
|
|
|
|
------ cut here to start the screen dump ------
|
|
|
|
KEY BRK DebugD K/PC B D S A X Y M Q L P nvmxdizc e d
|
|
00 o d 9500 FD/688D FD 2500 1FE0 0000 4D95 0044 0C BE 1 03 00000011 0 0
|
|
|
|
1FF2:60 00/0000: BE '>' 00/0000-00-00
|
|
1FF1:43 00/0000: BE '>' 00/0000-00-00
|
|
1FF0:FE 00/0000: BE '>' 00/0000-00-00
|
|
1FEF:01 00/0000: BE '>' 00/0000-00-00
|
|
1FEE:37 00/0000: BE '>' 00/0000-00-00
|
|
1FED:0C 00/0000: BE '>' 00/0000-00-00
|
|
1FEC:00 00/0000: BE '>' 00/0000-00-00
|
|
1FEB:4D 00/0000: BE '>' 00/0000-00-00
|
|
1FEA:7A 00/0000: BE '>' 00/0000-00-00
|
|
1FE9:C0 00/0000: BE '>'
|
|
1FE8:00 00/0000: BE '>' E1/0000.000F-T
|
|
1FE7:2C 00/0000: BE '>' 00/0000.0000-?
|
|
1FE6:00 00/0000: BE '>' 00/0000.0000-?
|
|
1FE5:E0 00/0000: BE '>' 00/0000.0000-?
|
|
1FE4:6A 00/0000: BE '>' 00/0000.0000-?
|
|
1FE3:B4 00/0000: BE '>' 00/0000.0000-?
|
|
1FE2:62 00/0000: BE '>' 00/0000.0000-?
|
|
1FE1:DA 00/0000: BE '>' 00/0000.0000-?
|
|
1FE0:FD 00/0000: BE '>' 00/0000.0000-?
|
|
|
|
:GSBug V1.5b9 w/Glue Support -(C)1986-90 Apple Computer,Inc.
|
|
|
|
------ cut here to end the screen dump ------
|
|
|
|
|
|
Top Two Lines:
|
|
|
|
The first two lines of the screen show the contents of various registers. The
|
|
top line of the screen starts off with "KEY BRK DebugD" - those are headings
|
|
for the items in the second line of the screen. The meanings of those
|
|
headings (and the items under them) are:
|
|
|
|
Heading Meaning
|
|
------- -------------------------------------------
|
|
KEY Modifiers used to separate debugger keys from application keys
|
|
BRK (beyond the scope of this quick intro - see the manual)
|
|
|
|
DebugD Debugger's direct page (1K in size) - in bank $00
|
|
K/PC K=program bank, PC=program counter
|
|
|
|
B app's data bank
|
|
D current direct page in bank zero
|
|
|
|
S current stack pointer
|
|
A accumulator's value
|
|
|
|
X X register's value
|
|
Y Y register's value
|
|
|
|
M machine state register's value
|
|
Q quagmire register's value
|
|
|
|
L Language card bank
|
|
P processor-status register's value
|
|
|
|
nvmxdizc bits that make up "P" (n=negative, c=carry, etc)
|
|
e emulation mode flag
|
|
d disassembly mode flag (0=recognize SEP & REP during "L"isting)
|
|
|
|
|
|
If you want more information on a specific register's meaning then look it up
|
|
in the IIGS Hardware reference manual, the GSBug manual, or any good book that
|
|
covers the IIGS's internal hardware. Any of these register's values can be
|
|
changed - we'll show how to do that in a few paragraphs or so...
|
|
|
|
|
|
The Left-Hand Side:
|
|
|
|
The next major area of the screen is the 4-digit column of numbers running
|
|
down the far left side. There is a colon on each line after the fourth
|
|
digit, and then there is a column (two digits wide) of numbers. All of these
|
|
numbers are in hex and this area is the stack. The four digit column, the
|
|
colons, and the two digit column are collectively known as the "stack
|
|
subdisplay area" - remember that, there's a test at the end of this file.
|
|
The column on the left of the colon is the address of the stack and the
|
|
column on the right (the two digit column) are the values on the stack.
|
|
The bottom-most four digit stack address is the "top" of the stack (i.e.:
|
|
if your app pushes anything on the stack, that's the address it would wind
|
|
up at). As you step through your application (we'll show how in a minute,
|
|
patience...) the stack will scroll upwards as things are pushed onto it and
|
|
downwards as things are pulled off of it.
|
|
|
|
|
|
The Not-So-Left-Hand Side:
|
|
|
|
The next major area should be a column of "00/0000: BE '>'" known as the
|
|
"RAM subdisplay area". This area is used to display any 19 memory locations
|
|
that you want to keep an eye on. The value at each of those locations is
|
|
shown in hex (that's what the "BE" means - location 00/0000 contains hex "BE"
|
|
when I wrote this) and in ASCII (the ASCII version is between the single quote
|
|
marks, i.e.: the "'>'"). It is possible to have this subdisplay show a
|
|
two-byte or a three-byte value instead of the one-byte value. You lose the
|
|
ASCII display if you opt for the 2 or 3 byte values.
|
|
|
|
After I finish explaining the rest of the screen, I'll come back and describe
|
|
how to change these 19 "windows on memory" to look at what you want to
|
|
monitor.
|
|
|
|
|
|
The Center Part:
|
|
|
|
The next major area of the screen is the 9 lines of "00/0000-00-00", better
|
|
known as the "Breakpoint subdisplay" (they're on the top half of the screen).
|
|
GSBug lets you set up to 17 breakpoints in your program (not counting BRK
|
|
instructions you imbed in your program yourself). Curious about how you set
|
|
17 break points when there are only 9 lines in this section? Did I mention
|
|
that APDA stocks the manual (which has full details)? <grin> Seriously, you
|
|
can "extend" the breakpoint subdisplay by shrinking the section under it
|
|
(which we haven't described yet). For the purposes of this quick intro, I'm
|
|
not going to show how to do this (you need some kind of reason to get the
|
|
manual). I'll just describe this area and later show how to set up to 9 break
|
|
points.
|
|
|
|
The "00/0000" part of the breakpoint subdisplay is obviously an address - in
|
|
fact, it's the address you want to break on. The next part "-00-" is the
|
|
trigger value. GSBug is smart enough to count how many times an address has
|
|
been executed and break on a certain number (i.e.: put a "03" here and GSBug
|
|
will break the third time that address is executed). The last part of this
|
|
area is the running count - this is how GSBug lets you know how many times
|
|
that area has been executed (rather than leave you wondering, it tells you and
|
|
you can be ready for the break). You set the address and trigger portions and
|
|
GSBug sets the count portion.
|
|
|
|
|
|
The Bottom Part of the Center Part:
|
|
|
|
The bottom half of the center of the screen is known as the "Memory
|
|
Protection Subdisplay" and starts off with "E1/0000.000F-T". This area can
|
|
be expanded (or shrunk) by trading lines of this area for lines of the one
|
|
above it (the "Breakpoint subdisplay"). If you want to know how to do this,
|
|
read the manual from APDA, it's big (roughly 150 pages) and I'm not
|
|
retyping all of it here! <grin>
|
|
|
|
The "E1/0000.000F" is the address range starting at E1/0000 and ending at
|
|
E1/000F. The "T" at the end means that this range of memory is protected from
|
|
code tracing. If you're tracing through your code and it jumps (JSR's, JSL's,
|
|
whatever) into this range of memory, then the code in this range will NOT be
|
|
traced - it will be executed at full speed instead.
|
|
|
|
There are two other options for code protection ("W" and "H"). They are
|
|
beyond the scope of this quick tutorial (I'm only trying to cover the
|
|
basics here).
|
|
|
|
|
|
Where You Type Commands:
|
|
|
|
The bottom line on the screen is the command line subdisplay (catchy name,
|
|
eh?). When you first enter GSBug, this line will contain the copyright
|
|
message and version number for GSBug (unless you've used the DebugStr or
|
|
SetMileStone "tool" calls to change this string). As soon as you press a
|
|
key, the copyright message vanishes and your keypress shows up next to the
|
|
blinking cursor. This is where you'll type various commands to make GSBug
|
|
help you get the kinks out of your software.
|
|
|
|
|
|
What's the Big Blank Spot For?:
|
|
|
|
The big blank area towards the far right of the screen is officially known as
|
|
the "disassembly subdisplay" (it's one of the big reasons you're using GSBug -
|
|
even if you don't know it yet). As you single-step through your software,
|
|
trace through it, or just list areas of memory this area will show you the
|
|
disassembled version of your program. One of the really slick things about
|
|
this area is that it's smart enough to know about the names of GS/OS calls and
|
|
Toolbox calls - so you see things like "_CheckUpdate" instead of "JSL E10000".
|
|
That makes if VERY easy to line up pieces of your source with the disassembly
|
|
if you're working in a high-level language. It also makes it a LOT easier to
|
|
see what you're doing!
|
|
|
|
GSBug also knows about the alternate Toolbox entry point (E10004) and will
|
|
display those as tool calls also. The leading underscore ("_") lets you know
|
|
that GSBug is substituting the tool's name for you. If the tool call is being
|
|
made through "glue", then the underscore is preceded by an asterisk ("*").
|
|
|
|
If you've ever used the built in "monitor" (I'm not talking about your RGB
|
|
monitor, I'm talking about the disassembler that's been built into Apple II's
|
|
for a LONGGGGGGG time now), then you'll be able to quickly figure out that
|
|
the left-most part of the disassembly subdisplay is the address, the inside
|
|
columns are the hex bytes making up the code about to be disassembled, and the
|
|
right-most part is the disassembled version of your software.
|
|
|
|
|
|
Your First GSBug Command:
|
|
|
|
OK, you now know what all of the various areas of this rather busy-looking
|
|
screen are for, so let's get down to business! The first thing to do is press
|
|
the "L" key (upper or lower case work the same these days) and then press
|
|
RETURN. This will fill the disassembly subdisplay with 19 lines of
|
|
disassembled code (which 19 lines were disassembled really doesn't matter).
|
|
Study it until you can tell at a glance which parts are the address, which
|
|
parts are the hex bytes, and which parts are the disassembled code.
|
|
|
|
Type "L" and press RETURN again - you get the next 19 lines of memory (see,
|
|
I told you it was a lot like the built-in monitor).
|
|
|
|
Now, let's do something a tad more useful... Press the "S" key and RETURN
|
|
(you just told GSBug to start single-stepping through your application). Be
|
|
careful what keys you press while in the single step mode - lots of
|
|
weird-looking things can happen (they're all normal, but if you don't expect
|
|
them you can get confused). For now, ONLY press the keys this tutorial tells
|
|
you to. If you can't wait and just HAVE to bang on all of the various keys,
|
|
then go ahead - reboot once you've totally confused yourself, pop back into
|
|
GSBug and catch up with the rest of the folks reading this.
|
|
|
|
To tell GSBug to execute the highlighted instruction, press the SPACE BAR one
|
|
time. Heck, press it several times so that you get a bunch of lines of
|
|
disassembled code on the screen. Notice that the code scrolls up and the
|
|
"highlighted" area stays in the same place? Notice it's kind of close to the
|
|
bottom of the screen? Later I'll tell you how to move it up higher.
|
|
|
|
Press the ESC key. That takes you out of single-step and returns you to the
|
|
command line. Press "S" and RETURN again to restart single stepping. Notice
|
|
that the lines ABOVE the highlighted area have been erased? Remember that -
|
|
if you halt single-stepping and need some piece of info above the highlighted
|
|
area, then write it down because it'll be wiped out when you restart
|
|
single-stepping (or when you do any of a bunch of different things). If you
|
|
have your printer connected to slot 1, then you can print GSBug's screen using
|
|
the "P" command (press "P" and RETURN - be sure you're NOT single-stepping
|
|
when you do this, "P" only prints from the command line).
|
|
|
|
|
|
Lock a Tractor Beam onto Them...:
|
|
|
|
Want an easy way to have the computer step through source for you without
|
|
having to bang again and again on the SPACE BAR? Start single-stepping
|
|
("S" and RETURN), then press RETURN again. VRRRROOOOMMMMMM! Can't read all
|
|
the stuff flying by? No sweat, press SPACE BAR and you'll be back to
|
|
single-stepping. Pressing the RETURN key a second time kicked GSBug into
|
|
"Trace" mode.
|
|
|
|
Trace actually has two speeds, the default is fast (we like to test
|
|
developers' speed reading skills). To kick TRACE into low gear, press the
|
|
left arrow key. If you're in single-step mode, then you won't see the speed
|
|
change (after all, it affects TRACE, not SINGLE-STEP), but fear not brave
|
|
developer, the speed change has been made. Press RETURN again (to be sure
|
|
you're in TRACE mode) and press the left arrow key (if you didn't a few lines
|
|
ago) to kick TRACE into low gear. Want to get back into high gear? Press the
|
|
right arrow key (sneaky, eh?).
|
|
|
|
|
|
RED ALERT!:
|
|
|
|
Do _NOT_ press the down arrow key while TRACING or single-stepping (unless
|
|
you know what you're doing). The down arrow key tells GSBug to SKIP the
|
|
highlighted instruction! This is a great way to step over BRK instructions,
|
|
but it's not a real smart thing to do at random while TRACING through an
|
|
application (randomly skipping an instruction generally results in a crash).
|
|
|
|
|
|
Move That Line Up:
|
|
|
|
If you want to raise the highlighted line within the disassembly subdisplay,
|
|
then press ESC (to get back to the command line) and type "SET" (don't type
|
|
the quotes, ok?) and press RETURN. The up and down arrows now control the
|
|
vertical position of the highlighted bar within the disassembly subdisplay.
|
|
Position the bar where you want it and press ESC. That position will be
|
|
remembered until the next time you move it or until you reboot (then it goes
|
|
back to the default position). The manual for GSBug tells you how to save
|
|
this new position to a configuration file (it also tells you that pressing the
|
|
left and right arrow will move the stack subdisplay up and down, and that
|
|
pressing a number less than eight will change the slot used to print the
|
|
screen).
|
|
|
|
|
|
Reaching the Breaking Point:
|
|
|
|
Alright, time for some fancy stuff! The next couple of sections will assume
|
|
you were running the IIGS Finder when you popped into GSBug (other apps will
|
|
work just fine, but why be difficult?). GSBug will let you break on any tool
|
|
call (or calls) that you specify, so let's set a few tool breaks and learn how
|
|
to use this feature.
|
|
|
|
From GSBug's command line (press ESC if you're still stepping or tracing),
|
|
type "settbrk _sysbeep" and press RETURN. If GSBug beeps at you instead of
|
|
accepting this line, then you didn't type it right (there are two t's in
|
|
"settbrk" and don't type the quotes). Type "settbrk #090E" and press RETURN.
|
|
You just added two tool calls to GSBug's list of tools to break on. The first
|
|
one was added by naming the tool to break on ("_sysbeep") and the second one
|
|
was added by specifying the tool's number ("#090E"). This lets you set tool
|
|
breaks regardless of whether you know the tool's name or number.
|
|
|
|
Type "showbrks" and press RETURN to see the complete list of tool breaks that
|
|
GSBug has been told about. Notice that the left hand side of the screen now
|
|
implies that you can set breaks on GS/OS calls? That's because you can!
|
|
GS/OS breaks have to be set by number (not by name).
|
|
|
|
All we've done so far is make a list of tools for GSBug to break on. We
|
|
haven't actually told GSBug to break on them, that requires a separate
|
|
command. Type "tbrkin" to tell GSBug to break on all of the tool calls in
|
|
its list. Now, when either a call to SysBeep or a call to NewWindow
|
|
(tool $090E is NewWindow) is made, we'll be dropped back into GSBug.
|
|
|
|
|
|
Oh Yeah? Prove It!:
|
|
|
|
Make sure you're at GSBug's command line (press ESC if you aren't). Type "R"
|
|
and RETURN. This resumes full execution of your application. To test the
|
|
tool breaks we just set, we need to force the Finder (or whatever app you
|
|
stubborn folks decided to use instead of the Finder) to make a call to
|
|
NewWindow and/or to SysBeep. Double click on a disk icon, get info on a file,
|
|
open a folder, open a desk accessory, etc to get the Finder to open a new
|
|
window. Notice that you land in GSBug?
|
|
|
|
Press "S" and RETURN to enter single-stepping. Notice that the highlighted
|
|
instruction is "NewWindow". Ah, the tool break works. Now, press SPACE BAR
|
|
to execute the NewWindow call, press ESC to stop single-stepping, and type "R"
|
|
and RETURN to resume running the Finder. (if we didn't bother to single step
|
|
across the NewWindow call, we would just fall right back into the debugger
|
|
since we have a break point set on that call).
|
|
|
|
|
|
Take it Out, Wise Guy!;
|
|
|
|
Tired of falling into GSBug everything a new window is opened? There are
|
|
several ways to remove tool breaks. The easiest way is to type "tbrkout" to
|
|
stop breaking on the listed tool calls without trashing the list. Typing
|
|
"tbrkin" makes GSBug start breaking on them again.
|
|
|
|
To clear the list of tool breaks, either type "clrtbrk _sysbeep" (to remove
|
|
the sysbeep break we put in earlier) and repeat that for "_newwindow" or wipe
|
|
the all out with "clralltbrks". I'll let you decide...
|
|
|
|
|
|
Cheap Trick #1:
|
|
|
|
Being able to break into the debugger based on a tool call is VERY handy! But
|
|
what if you want to see the stack being set up BEFORE your code gets all the
|
|
way down to the tool call itself? After all, if you're not putting enough
|
|
parameters on the stack (or too many), then breaking on the tool call itself
|
|
is too late to watch the stack being built. There's an easy solution for
|
|
this - stick a SysBeep call in your source ABOVE the tool call you really
|
|
want to break on and set a tool break on SysBeep. This will let you
|
|
single-step through the stack setup for the call you're really interested in.
|
|
OK, so it's a cheap trick, but it's darned effective...
|
|
|
|
This trick was invented in the dark ages before DebugStr was part of GSBug
|
|
(DebugStr is explained near the very end of this document and is a little
|
|
trickier to use than Cheap Trick #1).
|
|
|
|
|
|
I Don't Like My Registers:
|
|
|
|
Remember earlier when I mentioned that you can change the values of the
|
|
various registers from within GSBug? This lets you change values that are
|
|
about to be pushed on the stack and do all kinds of neat things. You're
|
|
sharp, so I won't bore you with all the things this lets you do, I'll just
|
|
cut right to the description of HOW to do it...
|
|
|
|
To change the accumulator's value, type "a=value" on the command line.
|
|
Replace "value" with the hex value you want to stuff into the accumulator.
|
|
Type "x=value" to set the x register, "y=value" to set the y register, etc.
|
|
You can't type "a=x" to set the accumulator to the value in the x register,
|
|
but since you can see the x register's value, this isn't that big of a loss.
|
|
|
|
|
|
Cheap Trick #2:
|
|
|
|
If you accidently SKIP an instruction that you didn't mean to (and you haven't
|
|
executed any more since then), you can "unskip" it by exiting single-step
|
|
mode, then type "pc=value" where "value" is the address (all three bytes just
|
|
to be safe) that the skipped instruction is at. Press RETURN and then resume
|
|
single-stepping (notice that you're back at the skipped instruction now).
|
|
|
|
This tricks works because the "pc" register is the program counter (the thing
|
|
that determines what address will have its instruction executed next).
|
|
|
|
|
|
Cheap Trick #3:
|
|
|
|
Fudging the program counter (pc=value) will let you push extra info on the
|
|
stack in cases where you didn't push enough for a call. Be careful with
|
|
this - you may need to set the accumulator before re-executing an
|
|
already-executed PHA and you could totally trash the stack if you're not
|
|
paying attention. One place this is handy is to compensate for passing a
|
|
WORD instead of a LONG (easy to do with C when you're dealing with resource
|
|
ID's). If you don't understand this trick, don't use it!
|
|
|
|
A minor modification on this stunt is (obviously) to pull extra bytes OFF of
|
|
the stack in cases where you left something on there that shouldn't have been
|
|
left on. Once you spot problems like too much or too little data on the
|
|
stack, FIX YOUR SOURCE CODE AND RECOMPILE IT!!!! You don't really want to
|
|
have to find this bug a second time do you?
|
|
|
|
|
|
Cheap Trick #4:
|
|
|
|
GSBug is a lot like the monitor in certain respects. That means many of the
|
|
commands you're used to from the monitor will work under GSBug. Setting
|
|
values in memory under GSBug is done just like it is under the monitor
|
|
(i.e.: address : value1 value2 value3 value4 ...). addressT and RETURN
|
|
starts tracing at the memory location specified by "address". addressS and
|
|
RETURN starts single-stepping at the memory location specified by "address".
|
|
addressL and RETURN lists 19 lines of disassemby starting at the memory
|
|
location specific by "address". You can even use the built-in mini assembler
|
|
if you want (type "asm" and RETURN).
|
|
|
|
|
|
Peering Into Memory:
|
|
|
|
The 19 "windows on memory" can be used by typing "mem" and RETURN on the
|
|
command line. This puts the cursor on the far right of the first line in the
|
|
RAM subdisplay area. Type the address you want to watch and press RETURN.
|
|
That will move you to the next line (so you can set the address for the second
|
|
memory location). If you want to see two bytes starting at that address,
|
|
press "P". To see three bytes, press "L". "Z" toggles between direct-page
|
|
and absolute addressing, ":" toggles between direct, 2-byte indirect, and
|
|
3-byte indirect addressing. Press "?" for more info.
|
|
|
|
This provides a nice way to look at variables in memory, dereference
|
|
pointers/handles, etc. When the contents of any "peered into" location
|
|
changes, the corresponding line on GSBug's screen will change also.
|
|
|
|
|
|
Cheap Trick #5:
|
|
|
|
(this one's actually not cheap, it's pretty danged useful!) While
|
|
single-stepping or tracing, you can see other "screens" by pressing various
|
|
keys (this accounts for the weird effects I alluded to earlier). Press "S" to
|
|
see the SHR screen (i.e.: your desktop application's desktop), "D" to see the
|
|
double hi-res screen, "T" to see the text screen, "8" to see 80-column
|
|
display, "4" to see 40-column display, "H" to see the Hi-Res screen, "L" for
|
|
the Lo-Res screen, and ESC to exit single-stepping. This lets you see your
|
|
application's screen instead of GSBug's screen (makes it a LOT easier to
|
|
debug your apps when you can see their screens...).
|
|
|
|
|
|
Study For The Test:
|
|
|
|
I told you earlier that there would be a test at the end of this tutorial, so
|
|
now's your chance to kick back and study a bit. So far, we've covered what
|
|
the various parts of GSBug's screen mean, how to disassemble pieces of memory
|
|
(using "L"), how to single-step and trace (at different speeds) through your
|
|
application, how to set, use, and clear breakpoints, how to display various
|
|
screens, and how to set up the RAM subdisplay area.
|
|
|
|
|
|
Don't Touch That Dial!:
|
|
|
|
The material covered so far gives you a decent foundation to draw upon as you
|
|
hunt bugs in your own software. We've only lightly touched on what GSBug can
|
|
really do (I'm not typing all 150 or so pages of the manual into this
|
|
"introduction" to GSBug). GSBug offers a lot of power and capabilities that
|
|
should be learned by all developers.
|
|
|
|
Before I wrap up this tutorial I want to cover the use of templates and
|
|
describe some of the new features in GSBug v.1.5b11 that aren't described in
|
|
the APDA documentation (because we just added the features and haven't
|
|
replaced APDA's master manual yet).
|
|
|
|
|
|
Templates By Jim:
|
|
|
|
GSBug provides an easy way for you to view portions of memory through
|
|
templates. This allows you to "see" the data structures in memory just
|
|
like they appear in the documentation (i.e.: see them divided into the
|
|
various fields). The GSBug.Templates file that you were supposed to
|
|
have placed in the SYSTEM/SYSTEM.SETUP folder of your boot disk contains
|
|
a complete set of templates for use with our interface files. One of the
|
|
Apple II Developer Technical Support Engineers put these templates together
|
|
(and came up with a pretty neat way to build in a "help system" - so tell
|
|
Jim "thanks" next time a template bails you out of a jam).
|
|
|
|
GSBug does NOT automatically load those templates unless you rename them (see the "GSBug.Specs" file for more information). You have to tell GSBug to load
|
|
them (and you can unload them later). To load these templates, just type
|
|
"loadtemp */system/system.setup/gsbug.templates" and press RETURN. Keep
|
|
trying until you get it right - it does work (watch out for typos, etc).
|
|
|
|
To view a piece of memory with a template, simply determine the starting
|
|
address of the template. The starting address can be found in a number of
|
|
ways - you can dereference a pointer that you just pushed on the stack, etc.
|
|
Then, type an underscore, the type of structure you want used, a blank space,
|
|
and the starting address (don't forget the bank). (i.e.: if you know you
|
|
have a graf port starting at location 06/15E4, then type: "_grafport 06/15E4"
|
|
and press RETURN.
|
|
|
|
To use the built-in template help system that Jim came up with (thanks Jim!),
|
|
just type: "_template 0" and press return. This will give you a list of all
|
|
the categories of help you can get more info on (such as ADB, FONTS, etc).
|
|
The categories are grouped by toolbox manager. To get details on a particular
|
|
toolbox manager's tool calls, type "_toolmgrname 0" and press RETURN
|
|
(replace "_toolmgrname" with the name of any tool manager - lead with an
|
|
underscore or it won't work). (i.e.: "_quickdraw 0" for details on QuickDraw
|
|
data structures) For more details, read the separate documentation file on
|
|
using the templates.
|
|
|
|
If you want to create your own custom templates, then read the GSBug manual
|
|
(pages 86-88) or decipher the templates in the GSBug.Templates file. To
|
|
unload the templates (and free up the memory they're eating), type "killtemp"
|
|
and press RETURN from GSBug's command line.
|
|
|
|
|
|
The New Stuff:
|
|
|
|
As if all of this weren't reason enough to use GSBug, the man behind this
|
|
jewel added several more reasons (he calls them features). All of these are
|
|
fake tool calls that the debugger sees, intercepts, and acts on.
|
|
|
|
The new calls are SetMileStone, DebugStr, DebugVersion, and DebugStatus.
|
|
The two most important ones (in my opinion) are "SetMileStone" and "DebugStr".
|
|
|
|
SetMileStone simply changes the debugger's copyright message to be a string of
|
|
your choice and lets your app keep running. If you're having a problem
|
|
figuring out where your code was last at before it jumped off into the weeds,
|
|
then sprinkle SetMileStone calls into your source code (with different strings
|
|
on each, of course). Then, when your app chokes and dies, you'll be presented
|
|
with the text from the last SetMileStone that was executed.
|
|
|
|
DebugStr works like SetMileStone (i.e.: changes the copyright string
|
|
to something with info about your application) except it dumps you immediately
|
|
into GSBug. This is a little more work than Cheap Trick #1, but you can line
|
|
up your source easier (since you'll have the debug string's message to guide
|
|
you).
|
|
|
|
DebugVersion and DebugStatus act just like normal version and status calls for
|
|
regular tool sets - they simply allow you to verify whether GSBug is running
|
|
and if so, what version of the debugger is running before you try to make any
|
|
debugger tool calls.
|
|
|
|
The tool numbers and parameter lists for these calls are:
|
|
|
|
Name Tool # Parameter (returns)
|
|
-------------- ------ ---------------------------------------------------
|
|
DebugStatus $06FF (non-zero = true, ToolLocator error it not loaded)
|
|
DebugStr $09FF pointer to Pascal-style string
|
|
DebugVersion $04FF ($159F for v.1.5B9)
|
|
SetMileStone $0AFF pointer to Pascal-style string
|
|
|
|
|
|
Cheap (and short) Trick #6:
|
|
|
|
If you get really fancy, you can build the strings for DebugStr and
|
|
SetMileStone on the fly and imbed the values of key variables into them to
|
|
further simplify locating bugs.
|
|
|
|
|
|
Calling all Debuggers:
|
|
|
|
Do _NOT_ leave calls to these debugger tools in your software when you ship it
|
|
to customers! Why? Because making these calls on a system that doesn't have
|
|
GSBug installed makes a real mess...
|
|
|
|
|
|
Want More Info?
|
|
|
|
Contact APDA and order the full package (you have a newer version of GSBug
|
|
with this file, but APDA has the full manual). Order it by calling APDA
|
|
(1-800-282-2732) and asking for part #A0037LL/A (the price is $30). Due to recent changes in APDA, you no longer need to be a member before you can order this product.
|