Golden Gate Debugger

A Source Level Debugger for ORCA-Compatible High-Level Languages

Copyright 2017–2018, Kelvin W Sherlock. All Rights Reserved.

ORCA/C, ORCA/M, ORCA/Pascal, ORCA/Integer Basic, ORCA/Modula-2, PRIZM, and The Byte Works are trademarks of the Byte Works, Inc. GNO and GNO/ME are trademarks of Procyon Enterprises Incorporated. Apple IIgs, ProDOS, Macintosh, HFS, and GS/OS are registered trademarks of Apple, Inc.

Contents

Starting Up

Golden Gate Debugger (iixdb) is a source-level debugger built into Golden Gate. It draws inspiration from GDB, the GNU Debugger, as well as Splat! and NiftyList. It works with the ORCA debugger protocol, similar to Splat!, PRIZM, or ORCA/Debugger. iixdb is enabled by using the iix -g flag. Software must be compiled with debugging enabled (compile +D, occ -g, or a suitable debug pragma).

Please note that the ORCA debugger protocol is intrusive (based on the 65816 COP instruction) and debugging should be disabled for redistribution. (iix will silently skip over COP debugger instructions when the -g flag is not specified; A real IIgs will crash.)

# iix -g my-buggy-program args ...

Golden Gate Debug Shell
(iixdb)

The iixdb shell initially opens after the program has loaded but before the program has begun executing. Normally, you would use this opportunity to set breakpoints and continue. Alternatively, step to quickly break at the first line (normally main in C, ~_PASMAIN in Pascal).

Breakpoints

Breakpoints come in two flavors; permanent and temporary. Temporary breakpoints are one-shot and automatically delete themselves after being triggered. Permanent breakpoints are permanent (but can be manually removed).

The break (b) command sets permanent breakpoints

Set a breakpoint at the current line:

break

Set a breakpoint at a specified function (as a string or an identifier):

break function

Set a breakpoint at a specified line number within a file. file may be a string or identifier:

break file:line

Set a breakpoint at line offset (based on the current line and file):

break +number
break -number

Temporary breakpoints are set with the tbreak command.

Breakpoints can be listed with the info break (or info tbreak) command.

Breakpoints can be removed with the delete command:

delete break number
delete tbreak number

Stepping

The continue (c) and run (r) commands will run to the next breakpoint.

The return (r) command will step out of the current function.

The next (n) command will break at the next line, stepping over function calls.

The step (s) command will break at the next line, stepping into function calls.

The quit (q) command will exit iixdb and Golden Gate.

Tip: r is short for run or return, depending on context. Before your program begins execution, r is run. Once running, r is return.

Tip: As an alternative to stepping, tracing (set trace on) will print lines as they are executed, without breaking.

Examining Source Code

The list (l) command lists source code.

List the current line (with 6 lines of context):

list

List the current line (with 10 lines of forward context):

list +

List the current line (with 10 lines of backward context):

list -

List a specified line (with 6 lines of context):

list number

List a specific range of lines:

list number,number

The disassemble (d) command disassembles memory as 65816 assembly language.

Disassemble the current line/program counter:

disassemble

Disassemble a specific address:

disassemble expression

Examining Memory

The print (p) command prints an expression or variable.

Print an expression:

print expression

Print an expression in hexadecimal:

print/x expression

The print command can also be used to set a variable:

print expression*=*expression

(The /x modifier may also be specified, of course). The left hand side expression must be a variable or register.

The hd (x) command will hexdump memory.

hd expression

Miscellaneous

The backtrace (bt) command prints the function call stack.

(iixdb) backtrace
frame #1 $0201d1 DEBUG.C at main:14
frame #2 $02003d DEBUG.C at beep:7

The * command will list the local and global symbol table entries.

(iixdb) *
Global Symbols:
(struct *) stderr
(struct *) stdin
(struct *) stdout

Local Symbols:
(int16_t) x

The info command will print miscellaneous toolbox, GS/OS, and other information.

Print profiling information (see also iix --profile):

info profile

Print register information:

info registers

Print GS/OS file information

info files

Print GS/OS Loader information:

info loader

Print ORCA Fast File information:

info fastfiles

Print Memory Manager information:

info mm

Print Resource Manager information:

info rm

The set command configures certain settings

Print current settings:

set

Set variable case-sensitivity:

set case on/off

(Default is on (case-sensitive), which is appropriate for C. Pascal is case-insensitive.)

Set the current directory, for locating source code files:

set cd string

Enable or disable tracing:

set trace on/off

With tracing enabled, source code lines are printed as they’re executed.

NiftyList Mode

The : command toggles NiftyList mode to make certain commands more familiar for Apple II users. A NiftyList command can also be entered from the iixdb shell by preceding it with a single : character.

Print an expression (in hexadecimal):

: expression

Equivalent to:

print/x expression

Hexdump memory:

: expression;h

Equivalent to:

hd expression

Disassemble (list) memory:

: expression;l

Equivalent to:

disassemble expression

Expressions

Many commands require an expression as an argument. An expression is composed of literal numbers, symbol table variables, registers, and operators.

Literal numbers may be decimal (123), hexadecimal (0xabc), binary (0b0101), or a character constant ('a').

Variables follow C naming conventions ([A-Za-z_][A-Za-z0-9_]*) but ~ and a trailing $ are also permitted for compatibility. (Use whitespace around the ~ operator). If the variable name contains other characters, it may be quoted with a back-tick (`), `like so`. On OS-X, the debug shell will attempt to tab-complete variable names. The * command will list known global and local variables.

Registers are preceded with a @ symbol. The special register @kpc is the 24-bit program counter with program bank.

Operators follow C semantics and precedence rules.

Precedence

Operator

Usage

1

[]

Array subscript

., ->

Struct Member access

2

+, -

Unary plus, unary minus

!, ~

Logical not, bitwise not

*

Indirection

&

Address of

3

*, /, %

Multiplication, division, remainder

4

+, -

Addition, subtraction

5

<<, >>

Bitwise Left shift, right shift

6

<, <=

Less than, less than or equal

>, >=

Greater than, greater than or equal

7

==, !=

Equal, not equal

8

&

Bitwise and

9

^

Bitwise exclusive or

10

|

Bitwise or

11

&&

Logical and

12

||

Logical or

Operations – other than indirection, array subscripting, and member access – are performed with 32-bit integers.

Tip: Some commands (such as hd or disassemble) expect an address. Pointer variables and array variables are addresses, as are the @pc, @d, and @s registers. The & address of operator can be used to take the address of a variable which is, of course, an address. 32-bit integers are also considered addresses; unary plus can be used to convert anything to a 32-bit integer and thus an address, if desired.

Examples:

print argv[argc-1]
print *pointer
print stdout->_flag
hd @d+5

Debugger Limitations

The ORCA debugger protocol has a number of limitations. Some of these may be fixed in future compiler updates; some of them are inherent to the protocol itself. The Byte Works originally wanted to add debugging information at the OMF level. Apple was “disagreeable” so the COP-based protocol was designed instead.