@node Debugging
@chapter Debugging

@cindex debugging
@cindex gdb
@cindex breakpoints
@cindex watch variables
@cindex call stack
@cindex User Screen

xwpe integrates with gdb to provide a source-level debugging
environment.  You can set breakpoints, inspect variables, step through
code, view the call stack, and see program output --- all from within
the editor, without screen flicker.

This chapter was verified on 2026-05-29 with xwpe 1.6.2, gdb 17.2,
gcc 15.2, g++ 15.2, gfortran 15.2, fpc 3.2.2, and OpenJDK jdb 25.

@section Quick start

@enumerate
@item
Open a source file: @command{wpe debug_test.c} (use @command{wpe},
not @command{we} --- the debugger requires programming mode).

@item
Move to a line inside @code{main()} and press @kbd{Ctrl-G B} to set
a breakpoint.  The line is highlighted.

@item
Press @kbd{Ctrl-G R} to compile, link, and start gdb.  Execution
stops at the breakpoint.

@item
Press @key{F8} to step over lines.  Press @key{F7} to step into
function calls.  The cursor follows execution in the source code.

@item
Press @kbd{Ctrl-G W}, type a variable name, press @key{Return}.
The Watch Window shows its value, updated after each step.

@item
Press @kbd{Ctrl-G K} to see the call stack.

@item
Press @kbd{Ctrl-G P} to see program output (printf, etc.).
Press any key to return to the editor.

@item
Press @kbd{Ctrl-G Q} to quit the debugger.
@end enumerate

@section Debug menu reference

All commands are available from the @samp{Debug} menu (@kbd{Alt-D})
and via @kbd{Ctrl-G} prefix shortcuts:

@multitable @columnfractions .30 .18 .18 .34
@headitem Command @tab Menu key @tab Shortcut @tab Description
@item Toggle Breakpoint @tab B @tab Ctrl-G B @tab Set/remove breakpoint at cursor
@item Remove all Breakp. @tab M @tab Ctrl-G M @tab Clear all breakpoints
@item Make Watch @tab W @tab Ctrl-G W @tab Add variable to Watch Window
@item Edit watch @tab E @tab Ctrl-G E @tab Edit a watched expression
@item Delete watch @tab D @tab Ctrl-G D @tab Remove a watched variable
@item Remove All watches @tab A @tab Ctrl-G A @tab Clear all watches
@item Show stacK @tab K @tab Ctrl-G K @tab Show call stack
@item Goto cursor @tab U @tab Ctrl-G U @tab Run until cursor line
@item Finish function @tab F @tab Ctrl-G F @tab Run until function returns
@item Trace (step into) @tab T @tab Ctrl-G T @tab Execute one line, enter functions
@item Step (step over) @tab S @tab Ctrl-G S @tab Execute one line, skip functions
@item Run/Continue @tab R @tab Ctrl-G R @tab Start or continue execution
@item Program output @tab P @tab Ctrl-G P @tab Show program's stdout
@item debugger Options @tab O @tab Ctrl-G O @tab Select debugger backend
@item Quit @tab Q @tab Ctrl-G Q @tab Stop debugger
@end multitable

@noindent
Alternative keys (when function keys are available):
Ctrl-F8 = Toggle Breakpoint, Ctrl-F7 = Make Watch, Ctrl-F6 = Stack,
F7 = Trace, F8 = Step, Ctrl-F10 = Run, Ctrl-F2 = Quit.

@section Compiling for debugging

Compile with debug symbols (@code{-g}) and no optimisation
(@code{-O0}) for best results.  xwpe's default compiler options
include @code{-g}.  To add @code{-O0}, go to
@samp{Options @result{} Compiler} and append it to Compiler Options.

@section Program output (User Screen)

@cindex User Screen
@cindex Ctrl-G P
@cindex program output
@cindex pty

Program output (e.g.@: @code{printf}, @code{System.out.println}) is
captured invisibly --- no screen switching, no flicker.  For gdb
backends, output is captured via a pseudoterminal (pty): the program's
stdout is redirected to a pty slave and xwpe reads the pty master.
For jdb, output is extracted from jdb's command pipe.

Press @kbd{Ctrl-G P} (or @samp{Debug @result{} Program output}) to
view the captured output.  The screen clears and shows the output.
Press any key to return to the editor.

@strong{Important}: the output appears only after the line that
produces it has been @emph{executed}.  If the cursor is on the
@code{printf} line, that line has not run yet.  Press @key{F8} once
more to step past it, then @kbd{Ctrl-G P} to see the output.

After each step, xwpe sends @code{call (void)fflush(0)} to gdb to
flush the program's stdout buffer.  This ensures output is available
immediately, even if the program uses buffered I/O.

@section Debugger backends

@cindex debugger selection

xwpe supports five backends, selectable via @samp{Debug @result{}
debugger Options} (@kbd{Ctrl-G O}).  For @file{.java} files, jdb is
auto-selected.

@table @strong
@item gdb (GNU Debugger)
The default backend for C, C++, Fortran, and Pascal.  Tested with
gdb 17.2.  Supports all features: breakpoints, stepping, watches,
stack, program output capture via pty.

@item jdb (Java Debugger)
Backend for Java.  Auto-selected for @file{.java} files.  Uses
@code{poll()} for async JVM startup.  Breakpoints, stepping,
program output capture all work.  Tested with OpenJDK 25.

@item sdb (Symbolic Debugger)
Legacy UNIX debugger.  Not available on modern Linux.

@item dbx
Berkeley UNIX debugger.  Available on some BSD systems.

@item xdb
HP-UX debugger.  Historical compatibility only.
@end table

@section Debugging C++ programs

gdb handles C++ natively.  xwpe selects @command{g++} as the compiler
for @file{.cpp} files and @command{gdb} as the debugger.  All debug
features work: breakpoints in member functions, stepping through
constructors, watching @code{this->member} expressions.

@section Debugging Fortran programs

gdb supports Fortran.  xwpe selects @command{gfortran} for
@file{.f90} files.  Set breakpoints on subroutine entries, step
through loops, watch local variables.  Array inspection is limited
by gdb's Fortran support.

@section Debugging Pascal programs

gdb has basic Free Pascal support.  Compile with @command{fpc -g}
(xwpe's default).  Breakpoints and stepping work.  Variable
inspection may be limited for Pascal-specific types (strings, sets).

@section Debugging Java programs

@cindex Java debugging
@cindex jdb

xwpe auto-selects jdb when opening a @file{.java} file.  No manual
configuration is needed.  If gdb was previously selected, xwpe
switches to jdb automatically with an informational message.

jdb differences from gdb:

@itemize @bullet
@item
@strong{Slower startup}: the JVM takes 2--3 seconds to initialise.
xwpe uses @code{poll()} with a 10-second timeout to wait without
consuming CPU.

@item
@strong{Breakpoints are deferred}: jdb sets breakpoints after the
class is loaded.  You see ``Deferring breakpoint'' in the Messages
window -- this is normal.

@item
@strong{Program output}: captured from jdb's pipe (not via pty like
gdb).  View with @kbd{Ctrl-G P}.

@item
@strong{No redirect}: jdb does not support @code{> /dev/pts/N}
redirection.  xwpe handles this transparently.
@end itemize

Requires @command{default-jdk} (Debian/Ubuntu) or equivalent JDK
package that provides @command{javac} and @command{jdb}.

@section Example session: C with factorial

@example
$ wpe debug_test.c
@end example

@enumerate
@item
Move cursor to line 9 (@code{int x = 5;}).  Press @kbd{Ctrl-G B}.
The line is highlighted as a breakpoint.

@item
Press @kbd{Ctrl-G R}.  xwpe compiles with @code{gcc -c -g},
links, starts gdb, and stops at the breakpoint.

@item
Press @kbd{Ctrl-G W}, type @code{x}, @key{Return}.  Watch Window
shows @code{x = 5}.

@item
Press @key{F8} three times.  The cursor advances through:
@code{int result = factorial(x)} @result{} @code{printf(...)}
@result{} next line.

@item
Press @kbd{Ctrl-G P}.  The User Screen shows:
@example
--- Program output ---
factorial(5) = 120
--- Press any key to return to editor ---
@end example

@item
Press any key to return.  Press @kbd{Ctrl-G K} to see the stack.

@item
Press @kbd{Ctrl-G Q} to quit the debugger.
@end enumerate

@section Known issues

@itemize @bullet
@item
Debugging leaks memory.  The exact source is unknown (present since
the Payne era).

@item
The sdb and dbx backends are untested on modern systems.

@item
Use @command{wpe} (not @command{we}) for debugging.  The editor-only
binary does not include debugger support.

@item
On keyboards where Ctrl+Function keys are not transmitted (e.g.@:
Keychron with multimedia F-keys), use the @kbd{Ctrl-G} prefix
shortcuts instead.

@item
Program output capture requires @code{libutil} (for @code{openpty}).
This is part of @code{libc6-dev} on Debian and is always available.
@end itemize

@noindent
Verified on 2026-05-29 with xwpe @value{VERSION} and gdb 17.2.
