[comp.sys.apple2] Lyons GS Debugging Tips handout from KansasFest

dlyons@Apple.COM (David A. Lyons) (07/25/90)

Apple IIgs Debugging Tips and Techniques
compiled by David A. Lyons, Apple II Developer Technical Support
July 18, 1990

(July 23: corrected "InstallNDA is new for 5.0" to "RemoveNDA is new
for 5.0, and be careful about removing DAs.  Otherwise this document
is what I handed out as the A2-Central Developers Conference.)

General Techniques

In a Desktop-based program that normally displays the super-hires
graphics screen, write debugging messages to the text screen at
selected points in your program (using the Text Tools, for example).
Then in the event loop, test the mouse position (it appears in the 
"where" field of the event record after a GetNextEvent or TaskMaster 
call).  If the mouse is in the upper left corner of the screen switch
to the text screen using the QuickDraw II call GrafOff.  If the mouse
is anywhere else, switch back to the graphics display with GrafOn. 
(Reported by Ron Lichty; technique by Allan Bell, Australia)

Check for errors on all toolbox calls that allocate memory.  Have a
scheme for dealing with low-memory situations.  See Apple IIgs
Technical Notes #51, 52, 56, and others, and read about the System 
Software 5.0 Out Of Memory Queue handling introduced (Apple IIgs
Toolbox Reference Volume 3).

Make sure the Bank register is set right.  If you're writing code
that all fits into a single 64K bank, you may want to always keep
your data inside your code segment and use PHK PLB.  If your data
is in a separate segment, this is bad (you may not discover it right
away, because two segments can wind up in the same bank most of the 
time, especially if they happen to be small).

Use safety checks possible in your development environment.  For
example, if you use macros to allocate direct-page locations, use
assemble-time error messages to check the amount of direct-page space
you're using.  If it exceeds 256 bytes, complain during assembly; 
this will be a lot more fun than trying to figure out why your code
mysteriously crashes.

Watch out for uninitialized storage locations!  Random values may
allow your code to work a lot of the time, so suspect this problem 
especially if your code works right sometimes and fails other times.
(Developer Technical Support provides "Pointer Check" routines for
use with APW C.  See Sample Code volume 2.)



Tips for using GSBug
(Thanks to Tim Swihart for some of these GSBug tips.)

Break into your application at a strategic toolbox call, such as 
TaskMaster, by using the GSBug commands SetTBrk and TBrkIn.  When
you hit r to resume your application, you will automatically drop
into GSBug when you hit the selected call.  At that point you can 
disassemble pieces of your code, start single-stepping it with s,
or whatever.   You can usually even hit Apple-Ctrl-ESC to enter your
favorite CDA (see below).

Here's a way to trace your program's code for handling a particular
menu item.  Set a tool break on TaskMaster.  Resume your code and let
it break on the TaskMaster call.  Type s to display the super-hires 
screen, and click and hold the mouse button on the menu bar.  Press 
space to execute the TaskMaster call.  Select a menu item and release
the mouse.  At this point, you are still in GSBug, and TaskMaster has
just returned.  Press T to display the text screen, and press space 
to step through your code.

Debugging a Classic Desk Accessory is hard, because the stack is
normally in $00/01xx when a CDA executes.  GSBug is not able to 
trace code reliably while the stack pointer is in this range.  
Here's something you can do instead, if you really need to trace 
that CDA code:  break into the application at a convenient point 
(like at a TaskMaster call), set D=0 and start Stepping from the
CDA's entry point (one way to determine the entry point is with
Nifty List--try c018.5000i to find the right block in memory, and 
use ;c to display the name and entry points).

Debugging a New Desk Accessory with GSBug was hard in the past,
because the debugger could not receive any keystrokes while an NDA
window was in front.  With GSBug 1.5, just push down the CapsLock 
key, and all is well (the NDA does not receive any keystrokes while
CapsLock is down and GSBug 1.5 is installed.)

Type off in GSBug to see the top 23 lines of your code's "Real" text
screen.  Type on to get the GSBug screen back. 
 
If you get really fancy, you can build the strings (used in the
SetMileStone and DebugStr calls) on the fly and imbed the values 
of key variables into them to further simplify locating the bug.

If your development languages supports imbedding names or other 
info about your source into your object, use them.  This helps you
find routines at debug-time.



Nifty List Techniques

Nifty List is a Classic Desk Accessory by Dave Lyons.  It's 
Shareware, and you can download it from GEnie or America Online, 
among other places.  If he ever happens to be right in the same room
with you, be sure to ask him for a copy.

Here are a few things I do when I'm debugging some code with Nifty
List handy.

Pop into Nifty List and type V to see if you've really started up 
all the tools you think you have, and make sure the Work Area 
Pointers are valid (most tools use their WAPs for the address you
pass to the startup routine; the Control Manager is currently an 
exception).  Most of the other tool sets have valid handles or 0 for
their WAPs.  This is not guarnateed, but it's a useful sanity check
while you're writing an application.  (A few tool sets share the same
work areas.  Don't worry; it's normal for the Window Manager and
Event Manager to share, and for QuickDraw II and QuickDraw II 
Auxiliary to share, for example.)

Use the new Nifty List 3.0 \addfree and \check commands in Big
Brother module to detect accidental memory stomping.

Use c018.1000i to locate the static code segments in your application
("Info on handles with owner $10xx and memory manager attributes 
$C018").

Use 0/0;w to dump info about your window, including the pointer to
the Content Draw routine.  Make sure the content-draw routine does
not assume that the Bank or D registers are set on entry!  If it 
changes them, make sure it puts them back.

If your window doesn't update right, check your content draw 
routine--you must not assume you are the frontmost window, so using
FrontWindow to see what window you're supposed to draw in is wrong.
Use GetPort instead, because TaskMaster sets the QuickDraw port to
your window before it calls your update routine.

Explore the toolbox by making toolbox calls directly from the Nifty 
List command line.


When you Crash

When you crash, look on the stack for return addresses to see how 
you got there.  Sometimes things went so weird this is impractical,
but it often helps.  Nifty List's ;s command looks for RTS and RTL
addresses for you automatically.  (An "RTL address" is a sequence of
3 bytes on the stack that is the address of the last byte of a JSL 
instruction your program has executed, but which has not yet
returned.)
 
Check the Direct page register on a crash--by comparing against the 
WAPs for tools, you can often determine which toolset was in control
of the machine when it crashes (that doesn't mean it isn't your 
fault, but it gives you a clue about where to look!). 



Logic Analyzers

Logic Analyzers are hardware that hooks up to your computer and
watches what's going on.  They're pretty expensive, and you don't
need one for most debugging problems.  For certain types of problems,
though, they come in very handy.  For example, if you have found a
particular byte of memory that gets changed for no reason, but your 
best efforts to find out what piece of code is actually changing 
that byte have failed, a logic analyzer can help.  (Debugging code
that gets called during interrupts can be impossible to debug with
GSBug.  If you can step through the code outside the interrupt 
environment, great--if that's impossible, consider using a logic 
analyzer.)

The general idea is to tell that logic analyzer to "trigger" on a
particular event (a read or write of a particular byte in memory)
and then to record what happens after that (storing everything that 
the processor does, or just selected operations).  This happens
quickly, and then you can scroll through the resulting list to see
exactly what happened in the next thousand or more clock cycles.

Trick:  include accesses to known ROM locations to help you trigger
the analyzer at particlar spots in your code (STA $FF0000, $FF0002,
$FF0004, etc).


Here is some specific information about HP logic analyzers used for
debugging on the Apple II Family.  The HP 16500 provides more 
sophisticated trap specification end specification of which
instructions to store when a trap is in effect.  This provides for
more trace mileage out of the 1024 instructions that can be traced 
than is possible on the HP 1630G, also used at Apple. Also, the 
16500 works just like the 1650A for a lot of things.

You can call the HP Customer Information Center at 1-800-752-0900,
extension779E.  Their catalog says that if they don't have an answer
they'll put you in touch with someone who does.

Also, the software for using these analyzers with the 65816 or 65C02
is available direct from us at Apple along with instructions for 
wiring the PODs accordingly. There are a couple of San Francisco 
area companies who rent these machines (see below).

If you prefer to rent or lease the models, HP should be able to put
you in contact with a vendor in your area that could do this.
Engineers at Apple using these systems are very happy with them and
generally prefer the touch screen capability of the 16500 model.
(Hey, this isn't an endorsement, it's just information!)
 
Also, an in-circuit emulator for the IIe and IIgs is manfactured by
the Western Design Center, Inc.  At the 1989 A2-Central Apple II
Developer's conference Andrew Hall demonstrated this ICE system,
called the Toolbox Design System, and stated that they would be open 
to rentals of the system.  You can contact The Western Design Center
at 2166 East Brown Rd., Mesa, AZ 85213,  (602) 962-4545.
 
These HP Logic Analyzer units should be rentable through the 
following companies:
 
   Continental Resources       McGrath RentCorp
   1575 McCandless Drive       2500 Grant Avenue
   Milpitas, CA  95035         San Lorenzo, CA  94580
   (408) 263-1775              (415) 276-2626
 
(Thanks to Dan Strnad of DTS for this information on HP logic 
analyzers)

-- 
David A. Lyons, Apple Computer, Inc.      |   DAL Systems
Apple II Developer Technical Support      |   P.O. Box 875
America Online: Dave Lyons                |   Cupertino, CA 95015-0875
GEnie: D.LYONS2 or DAVE.LYONS         CompuServe: 72177,3233
Internet/BITNET:  dlyons@apple.com    UUCP:  ...!ames!apple!dlyons
   
My opinions are my own, not Apple's.