The CodeProbe Debugger (cdbg)

cdbg (also called CodeProbe) is the source-level debugger bundled with SAS/C 6.58. It supports both a windowing interface and a command-line interface, and is designed to handle AmigaOS-specific concerns: multitasking programs, shared libraries, and cross-debugging across machines. Source: Vol 2 Ch.1–4.

Getting started

Compiling for debugging

To use cdbg, programs must be compiled with debug information:

sc link debug=line myapp.c

The debug=line option emits line-number tables in the hunk format. Without it, source stepping is not possible. Other relevant options:

Option Effect
debug=line Emit line-number tables (required for source stepping)
debug=symbol Emit full symbol table (default; supports print variable)
debug=local Emit local variable info (V6.58+; required for whatis and locals)
optimize=0 Recommended for debug builds; optimization confuses step
nostackcheck Disable runtime stack probing for cleaner step

The standard NDK smakefile pattern adds debug=line for debug builds.

Running CodeProbe

cdbg myapp                       # local debug
cdbg myapp -args "arg1 arg2"     # pass arguments to program
cdbg -p myapp                    # attach to an already-running task by name

CodeProbe opens its windowing interface, loads the executable and its symbols, and waits at the entry point.

The windowing interface

cdbg's default UI has three main areas:

  • Source window — top: shows the current source line and surrounding context.
  • Command window — middle: line-oriented command prompt.
  • Status line — bottom: shows the current program state (running / stopped / signal received), task name, current PC, current source line.

Mouse-driven menus are available for common operations (Step, Next, Continue, Breakpoint, Watch). Most power users prefer the command window for precision.

Basic commands

Command Action
step Single-step into function calls
next Single-step over function calls
continue Resume execution
stop Halt execution (sends signal)
break function Set breakpoint at function entry
break file:line Set breakpoint at a source line
break *address Set breakpoint at an absolute address
delete or clear Remove a breakpoint
watch variable Break when variable is written
print expr Evaluate expression
whatis name Show the type of a variable or function
backtrace Show call stack
list Show source around PC
info registers Show CPU registers
info breakpoints List all breakpoints
info locals Show local variables of current frame
quit Exit CodeProbe (program is killed if still running)

Breakpoints

A breakpoint is a virtual address at which the debugger halts execution. cdbg resolves break function to the function's entry address and break file:line to the line's address via the line-number table.

(cdbg) break Open                 # stop on entry to Open()
(cdbg) break dos/dos-library.c:142 # stop at line 142
(cdbg) break *0x40801234           # stop at absolute address
(cdbg) condition 2 i > 100         # only stop at breakpoint 2 when i > 100
(cdbg) ignore 5 3                 # skip breakpoint 5 the next 3 times
(cdbg) commands 2                 # execute commands when breakpoint 2 hits
> print *ptr
> continue
> end

Hardware vs software breakpoints

cdbg uses software breakpoints by default (writes TRAP #1 or equivalent at the target address). On systems with instruction cache (68020+), the cache must be flushed for the breakpoint to take effect. CodeProbe handles this automatically.

For read-only code (ROM, MMU-mapped) where you cannot write breakpoints, use hardware breakpoints via break with specific options — or use the watchpoint support of the 68010+.

Watchpoints

Watchpoints break when a memory location is read or written. On 68010+, cdbg uses the hardware breakpoint registers. On plain 68000, watchpoints are implemented by single-stepping and comparing after each instruction — extremely slow, use only for small regions.

(cdbg) watch myvar               # break on write to myvar
(cdbg) rwatch myvar              # break on read from myvar
(cdbg) awatch myvar              # break on either read or write

Debugging C programs

Vol 2 Ch.3 walks through a worked example. Key patterns:

  • Compile with debug=line optimize=0 for clearest stepping.
  • Set a breakpoint at main() to start exploring.
  • Use print to inspect: print argv[0], print *(struct DosList *)lock, print array[3].
  • cdbg understands most C expressions including casts, dereferences, and struct member access.

Evaluating complex expressions

(cdbg) print MyGlobal->field.nested_value
(cdbg) print ((struct MyStruct *)ptr)->x
(cdbg) print *((int *)0x100.w)     # absolute address, .w for word size
(cdbg) print sizeof(int)

Debugging C++ programs

Vol 2 Ch.4. cdbg understands C++ name mangling, classes, and inheritance. Key differences from C:

  • Set breakpoints on member functions with full qualifier: break MyClass::MyMethod.
  • Inspect objects with print obj (calls operator<< if available, otherwise dumps members).
  • whatis reports the dynamic type when RTTI is enabled.
  • The this pointer is implicit in member functions.

Limitations: templates are shown with mangled names; demangling is partial. cdbg does not run expression evaluators; it uses static analysis from debug info.

Output and logging

cdbg has commands to capture program output and debugger log to files:

(cdbg) set logging file session.log
(cdbg) set logging on
(cdbg) continue
(cdbg) set logging off

The log includes every command, every breakpoint hit, every print result. Useful for post-mortem analysis.

See Also


Sources: SAS Institute Inc., "SAS/C Development System User's Guide, Volume 2" Ch.1–4, Version 6.50 (1993), pp. 1–72. Raw: raw/sasc/sasc-debugger-codeprobe-extract.md Updated: 2026-10-02