I'm planning to bust the C/C++ code freeze for my next push... ...but only with an ice auger and monofilament fishing line (that is, on a tightly limited basis), to fix the assertion failure Deri observed (and which anyone should be able to reproduce).
We only got 3 opinions on the other SEGV, which is many years old and
the "vote" was 2-to-1 (with many abstentions) against busting the freeze
for it, whereas this one is a regression from groff 1.23.0.
At 2026-01-28T18:23:46-0600, G. Branden Robinson wrote:
> At 2026-01-28T23:03:28+0000, Deri wrote:
> > I only discovered it when doing the research for the pdf attached to
> > <https:// savannah.gnu.org/bugs/?67544#comment8>. I wanted to attach
> > a .png at the top of the page:-
> >
[snipping down to reproducer]
> > \X'pdf: pdfpic ne-pic.png -L \n[LL]z'
> > .sp 1.4c
> > .NH 1 ghostscript
> > Ghostscript
> >
> > It only avoided the SIGSEGV if I added a .LP before it.
>
> Insofar as you had to issue an `LP` call before populating your ms(7)
> document with content, then it's not a bug that you got an undesirable
> outcome when you omitted it.
[...]
> However, a core dump should not be GNU troff's means of informing you
> that you erred.
>
> I'll test my excessively advanced input stream pointer hypothesis
> presently.
I didn't get the problem root-caused but I have backed off slightly from
this hypothesis, because I can cause _almost_ the same problem without
using an escape sequence, or selecting the "pdf" output driver.
$ ~/groff-HEAD/bin/groff -version | head -n 1
GNU groff version 1.24.0.rc2
$ printf '\\X"pdf: xrev"' | ~/groff-HEAD/bin/groff -ms
troff: src/roff/troff/input.cpp:3107: const char* token::description():
Assertion `0 == "unhandled case of `type` (token)"' failed.
/home/branden/groff-HEAD/bin/groff: error: troff: Aborted (core dumped)
$ echo '.device pdf: xrev' | ~/groff-HEAD/bin/groff -ms -a
<beginning of page>
troff:<standard input>:1: error: spurious end trap token detected!
df: xrev
Notice how there's no core dump, just an ill-formatted document. And
the ill-formatting is an outcome of which ms(7) users have been warned
since at least 1976 (before `\X` even existed).
The output still suggests input stream pointer shenanigans to me, but
not located quite where I thought they were (in the `\X` escape sequence
handler). Something else could be amiss.
And rather than go chasing down how to make the formatter or the macro
package recover better from ill-formed input, knowing that if I choose
(or am compelled to) the latter, fixes to me(7) and mm(7) will likely
_also_ be required because they too are designed to require macro calls
before they complete initialization, and knowing myself well enough that
if I start down this road I'm likely to see other problems I develop an
animal lust to fix, I think I'd rather just--to adapt Deri's analogy
from discussion of an unrelated issue--put a sticking plaster over this
one.
Here's the patch:
$ git diff --cached
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 944f9bcd9..1fe5b1631 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -3103,6 +3103,19 @@ const char *token::description()
return "an escaped ':'";
case TOKEN_EOF:
return "end of input";
+ // troff generates the following token types internally; the input
+ // can't (directly), so seeing them described likely suggests a bug in
+ // the formatter. We consequently don't attempt to make their
+ // descriptions intelligible to the novice.
+ case TOKEN_BEGIN_TRAP:
+ return "a \"begin trap\" token";
+ case TOKEN_END_TRAP:
+ return "an \"end trap\" token";
+ // TOKEN_NODE is handled above
+ case TOKEN_PAGE_EJECTOR:
+ return "a \"page ejector\" token";
+ case TOKEN_REQUEST:
+ return "a \"request\" token";
default:
assert(0 == "unhandled case of `type` (token)");
return "an undescribed token";
Turns out there were only four token types unhandled. That's not even
really a sticking plaster; as the comment notes, we can leave this
diagnostic information in there forever, because these descriptions
should only ever come up when a groff developer has erred.
Result?
$ printf '\\X"pdf: xrev"' | ./build/test-groff -ms -a
<beginning of page>
troff:<standard input>:1: warning: a "begin trap" token is not encodable in
device-independent output ('asciify' might help)
troff:<standard input>:1: error: spurious end trap token detected!
. pdf: xrev"
Code reviews? Any objections?
Savannah ticket: https://savannah.gnu.org/bugs/?67990
Regards,
Branden
signature.asc
Description: PGP signature
