5.37 Debugging

Standard troff voodoo, just put a power of two backslashes in front of it until it works and if you still have problems add a \c. — Ron Natalie

GNU troff is not the easiest language to debug, in part thanks to its design features of recursive interpolation and the use of multi-stage pipeline processing in the surrounding system. Nevertheless there exist several features useful for troubleshooting.

Preprocessors use the lf request to preserve the identity of the line numbers and names of input files. GNU troff emits a variety of error diagnostics and supports several categories of warning; the output of these can be selectively suppressed. A trace of the formatter’s input processing stack can be emitted when errors or warnings occur by means of GNU troff’s -b option, or produced on demand with the backtrace request. The tm and related requests can be used to emit customized diagnostic messages or for instrumentation while troubleshooting. The ex and ab requests cause early termination with successful and error exit codes respectively, to halt further processing when continuing would be fruitless. Examine the state of the formatter with requests that write lists of defined names (macros, strings, and diversions), environments, registers, and page location traps to the standard error stream.

Request: .lf line [file]

Set the input line number (and, optionally, the file name) GNU troff shall use for error and warning messages. line is the input line number of the next line. Without an argument, the request is ignored.

lf’s primary purpose is to aid the debugging of documents that undergo preprocessing. Programs like tbl that transform input in their own languages into roff requests use it so that any diagnostic messages emitted by troff correspond to the source document.

Request: .tm message
Request: .tm1 message
Request: .tmc message

Send message, which consumes the remainder of the input line and cannot contain special characters, to the standard error stream, followed by a newline. Leading spaces in message are ignored.

tm1 is similar, but recognizes and strips a leading neutral double quote from message to allow the embedding of leading spaces.

tmc works as tm1, but does not append a newline.

Request: .ab [message]

Write any message to the standard error stream (like tm) and then abort GNU troff; that is, stop processing and terminate with a failure status.

Request: .ex

Exit GNU troff; that is, stop processing and terminate with a successful status. To stop processing only the current file, use the nx request; see I/O.

When doing something involved, it is useful to leave the debugging statements in the code and have them turned on by a command-line flag.

.if \n[DB] .tm debugging output

To activate such statements, use the -r option to set the register.

groff -rDB=1 file

If it is known in advance that there are many errors and no useful output, GNU troff can be forced to suppress formatted output with the -z option.

Request: .pev

Report the state of the current environment followed by that of all other environments to the standard error stream.

Request: .pm

Report, to the standard error stream, the names of all defined macros, strings, and diversions with their sizes in bytes.

Request: .pnr

Report the names and contents of all currently defined registers to the standard error stream.

Request: .ptr

Report the names and positions of all page location traps to the standard error stream. Empty slots in the list, where a trap has been planted but subsequently (re)moved, are printed as well.

Request: .fl

Instruct gtroff to flush its output immediately. The intent is for interactive use, but this behaviour is currently not implemented in gtroff. Contrary to Unix troff, TTY output is sent to a device driver also (grotty), making it non-trivial to communicate interactively.

This request causes a line break.

Request: .backtrace

Write the state of the input stack to the standard error stream.

Consider the following in a file test.

.de xxx
.  backtrace
..
.de yyy
.  xxx
..
.
.yyy
    error→ troff: backtrace: 'test':2: macro 'xxx'
    error→ troff: backtrace: 'test':5: macro 'yyy'
    error→ troff: backtrace: file 'test':8

The -b option of GNU troff causes a backtrace to be generated on each error or warning. Some warnings have to be enabled; See Warnings.

Register: \n[slimit]

If greater than 0, sets the maximum quantity of objects on GNU troff’s internal input stack. If less than or equal to 0, there is no limit: recursion can continue until program memory is exhausted. The default is 1,000.

Request: .warnscale su

Set the scaling unit used in certain warnings to su, which can take the values ‘u’, ‘i’, ‘c’, ‘p’, and ‘P’. The default is ‘i’.

Request: .spreadwarn [limit]

Emit a break warning if the additional space inserted for each space between words in an output line adjusted to both margins with ‘.ad b is larger than or equal to limit. A negative value is treated as zero; an absent argument toggles the warning on and off without changing limit. The default scaling unit is ‘m’. At startup, spreadwarn is inactive and limit is 3m.

For example,

.spreadwarn 0.2m

causes a warning if break warnings are not suppressed and gtroff must add 0.2m or more for each inter-word space in a line. See Warnings.

GNU troff has command-line options for reporting warnings (-w) and backtraces (-b) when a warning or an error occurs.

Request: .warn [n]
Register: \n[.warn]

Select the categories, or “types”, of reported warnings. n is the sum of the numeric codes associated with each warning category that is to be enabled; all other categories are disabled. The categories and their associated codes are listed in Warnings. For example, ‘.warn 0’ disables all warnings, and ‘.warn 1’ disables all warnings except those about missing glyphs. If no argument is given, all warning categories are enabled.

The read-only register .warn contains the sum of the numeric codes of enabled warning categories.