Re: Does Gnulib replace exit(3) under any circumstances?
"G. Branden Robinson" <[email protected]> Thu, 23 Jul 2026 21:43:01 -0500
| Newsgroups | gmane.comp.lib.gnulib.bugs,gmane.comp.printing.groff.general |
|---|---|
| Message-ID | <20260724024301.twqns5vzei7f4ztb@illithid> |
--a5vexcpswcrswy5e Content-Type: text/plain; protected-headers=v1; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Subject: Re: Does Gnulib replace exit(3) under any circumstances? MIME-Version: 1.0 Hi Paul, At 2026-07-23T19:15:19-0700, Paul Eggert wrote: > On 2026-07-23 17:25, G. Branden Robinson wrote: > > The good news is that this seems_not_ to be a release blocker for > > groff. If the problem ain't in groff, I can't fix it in groff. >=20 > What Collin said. >=20 > For what it's worth, when I tried to debug this on Fedora 44 I found > that I couldn't build groff head (commit > d6675ad14d71b4b36b2274b889cd1e2594bfc79c), because groff's build > procedure assumes that because stdckdint.h works with C it also works > with C++, which is not true on Fedora 44. Rut-roh. > I worked around that problem by syncing with current Gnulib (which > fixes this problem), and I assume you'll do something similar before a > groff release. I'm using stable/2026-07. That's not fresh enough? [more below this long quote] > Also for what it's worth I built with this shell command: >=20 > ASAN_OPTIONS=3Ddetect_leaks=3D0 make CXXFLAGS=3D'-g3 -O2 -fsanitize=3Dadd= ress' > CFLAGS=3D'-g3 -O2 -fsanitize=3Daddress' >=20 > and when that failed, with this shell command: >=20 > ASAN_OPTIONS=3Ddetect_leaks=3D0,alloc_dealloc_mismatch=3D0 make CXXFLAGS= =3D'-g3 -O2 > -fsanitize=3Daddress' CFLAGS=3D'-g3 -O2 -fsanitize=3Daddress' >=20 > and got the following failures, the first with the first command and the > second with the second: >=20 > ... > GROFF doc/groff-man-pages.pdf > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > =3D=3D484606=3D=3DERROR: AddressSanitizer: alloc-dealloc-mismatch (malloc= vs > operator delete []) on 0x7b6448be0560 > #0 0x7f044a0f104f in operator delete[](void*) > (/lib64/libasan.so.8+0xf104f) (BuildId: > 5395ec74f54d9ec7bf97c06583dd39a96c230822) > #1 0x00000043027d in block_entry::~block_entry() > src/preproc/tbl/table.cpp:654 > #2 0x00000043027d in left_block_entry::~left_block_entry() > src/preproc/tbl/table.cpp:324 > #3 0x00000043027d in left_block_entry::~left_block_entry() > src/preproc/tbl/table.cpp:324 > #4 0x000000419d1b in table::~table() src/preproc/tbl/table.cpp:1293 > #5 0x00000040e249 in process_table(table_input&) > src/preproc/tbl/main.cpp:1618 > #6 0x00000040ec10 in process_input_file(_IO_FILE*) > src/preproc/tbl/main.cpp:256 > #7 0x000000402237 in main src/preproc/tbl/main.cpp:1710 > #8 0x7f0449a0a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) > (BuildId: 17f2e1fd905f485786f6fd6e3bede4ad737137e7) > #9 0x7f0449a0a797 in __libc_start_main@GLIBC_2.2.5 > (/lib64/libc.so.6+0x3797) (BuildId: > 17f2e1fd905f485786f6fd6e3bede4ad737137e7) > #10 0x000000402af4 in _start (/home/eggert/src/gnu/groff/tbl+0x402af4) > (BuildId: c478463b4fa0a8213180485cd5ed9b4c8f3f7067) >=20 > 0x7b6448be0560 is located 0 bytes inside of 62-byte region > [0x7b6448be0560,0x7b6448be059e) > allocated by thread T0 here:=1B[1m=1B[0m > #0 0x7f044a0ef41f in malloc (/lib64/libasan.so.8+0xef41f) (BuildId: > 5395ec74f54d9ec7bf97c06583dd39a96c230822) > #1 0x000000436cc9 in string::extract() const > src/libs/libgroff/string.cpp:308 >=20 > SUMMARY: AddressSanitizer: alloc-dealloc-mismatch > src/preproc/tbl/table.cpp:654 in block_entry::~block_entry() > =3D=3D484606=3D=3DHINT: if you don't care about these errors you may set > ASAN_OPTIONS=3Dalloc_dealloc_mismatch=3D0 > =3D=3D484606=3D=3DABORTING > troff: warning: name '3rele' not defined > troff: error: automatically ending diversion '3section' on exit > pdfmom: fatal error: groff exited with status 4 >=20 >=20 > ... > fonts_n.roff: listing fonts in ./font/devps > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > =3D=3D484862=3D=3DERROR: AddressSanitizer: heap-use-after-free on address > 0x7c88d65e52c0 at pc 0x7f78d7aaf861 bp 0x7fffdd9e1100 sp 0x7fffdd9e08c0 > READ of size 1 at 0x7c88d65e52c0 thread T0 > #0 0x7f78d7aaf860 in strcmp.part.0 (/lib64/libasan.so.8+0xaf860) > (BuildId: 5395ec74f54d9ec7bf97c06583dd39a96c230822) > #1 0x000000455a7f in file_iterator::get_location(bool, char const**, > int*) src/roff/troff/input.cpp:499 > #2 0x000000455a7f in input_stack::get_location(bool, char const**, in= t*) > src/roff/troff/input.cpp:800 > #3 0x000000493830 in macro::macro() src/roff/troff/input.cpp:3509 > #4 0x000000493830 in do_define_string(define_mode, comp_mode) > src/roff/troff/input.cpp:4478 > #5 0x000000495133 in request::invoke(symbol, bool) > src/roff/troff/input.cpp:3334 > #6 0x000000495133 in interpolate_macro src/roff/troff/input.cpp:4072 > #7 0x0000004a09f2 in process_input_stack() src/roff/troff/input.cpp:3= 100 > #8 0x0000004a2c4d in process_input_file src/roff/troff/input.cpp:8801 > #9 0x00000040a271 in main src/roff/troff/input.cpp:9153 > #10 0x7f78d740a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) > (BuildId: 17f2e1fd905f485786f6fd6e3bede4ad737137e7) > #11 0x7f78d740a797 in __libc_start_main@GLIBC_2.2.5 > (/lib64/libc.so.6+0x3797) (BuildId: > 17f2e1fd905f485786f6fd6e3bede4ad737137e7) > #12 0x00000040be74 in _start (/home/eggert/src/gnu/groff/troff+0x40be= 74) > (BuildId: cf528e78ad252e121bde02c92df44d512e25e23d) >=20 > 0x7c88d65e52c0 is located 0 bytes inside of 256-byte region > [0x7c88d65e52c0,0x7c88d65e53c0) > freed by thread T0 here: > #0 0x7f78d7af104f in operator delete[](void*) > (/lib64/libasan.so.8+0xf104f) (BuildId: > 5395ec74f54d9ec7bf97c06583dd39a96c230822) > #1 0x00000048c64c in pipe_source_request() src/roff/troff/input.cpp:6= 661 >=20 > previously allocated by thread T0 here: > #0 0x7f78d7af065f in operator new[](unsigned long) > (/lib64/libasan.so.8+0xf065f) (BuildId: > 5395ec74f54d9ec7bf97c06583dd39a96c230822) > #1 0x00000046a477 in read_string() src/roff/troff/input.cpp:8423 >=20 > SUMMARY: AddressSanitizer: heap-use-after-free src/roff/troff/input.cpp:4= 99 > in file_iterator::get_location(bool, char const**, int*) > Shadow bytes around the buggy address: > 0x7c88d65e5000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 > 0x7c88d65e5080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 0x7c88d65e5100: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa > 0x7c88d65e5180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 0x7c88d65e5200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > =3D>0x7c88d65e5280: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd > 0x7c88d65e5300: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd > 0x7c88d65e5380: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa > 0x7c88d65e5400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 0x7c88d65e5480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 0x7c88d65e5500: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd > Shadow byte legend (one shadow byte represents 8 application bytes): > Addressable: 00 > Partially addressable: 01 02 03 04 05 06 07 > Heap left redzone: fa > Freed heap region: fd > Stack left redzone: f1 > Stack mid redzone: f2 > Stack right redzone: f3 > Stack after return: f5 > Stack use after scope: f8 > Global redzone: f9 > Global init order: f6 > Poisoned by user: f7 > Container overflow: fc > Array cookie: ac > Intra object redzone: bb > ASan internal: fe > Left alloca redzone: ca > Right alloca redzone: cb > =3D=3D484862=3D=3DABORTING > make[2]: *** [Makefile:17135: contrib/hdtbl/examples/fonts_n.ps] Error 4 > make[2]: *** Deleting file 'contrib/hdtbl/examples/fonts_n.ps' > make[2]: Leaving directory '/home/eggert/src/gnu/groff' > make[1]: *** [Makefile:12162: all-recursive] Error 1 > make[1]: Leaving directory '/home/eggert/src/gnu/groff' > make: *** [Makefile:6996: all] Error 2 Thanks. Unfortunately, making groff ASAN-quiet is not a scheduled goal. As I put it elsewhere earlier today: "I see lots of memory leaks. Not a surprise at all--most of the C/C++ parts of [the] code base are up to 37 years old. Resolving sloppy memory management is part of a technical debt clearance war that is happening on many fronts. References available on request." https://savannah.gnu.org/bugs/?68544#comment2 If someone has a case for gating the release on either of Paul's ASAN problems, I'd like to hear it. It's possible the use-after-free report qualifies as gating, but the alloc_dealloc_mismatch doesn't. I concede the possibility of the use-after-free being of recent vintage, as I've had my fingers in `pipe_source_request()` and `read_string()` in this development cycle, but not in tbl's `block_entry` destructor. On the other hand, I recently refactored groff's `string` class _aggressively_, so it's possible I exposed a latent bug here. Thoughts? Regards, Branden --a5vexcpswcrswy5e Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEh3PWHWjjDgcrENwa0Z6cfXEmbc4FAmpi0S4ACgkQ0Z6cfXEm bc6l3Q//XcAWXZmdV7O0ZF0AB5V3o3mB6+ugmpfObxHc1+QQMSA3Dee9PWt7wdd5 WFS6O4Qm9yZe1W6/7UA01kZkwrutCAkeR59wZl1xdQPqKvcV5UlgDg4JTTW3M3Lb bW9QnjjKWRLMjq7Hll7mz60KaMH4dEpPLU8aUtry8MYa5CHcu7eQ6PbTdgegtaJr 4ad7rynyAonfTnv/EOTD1ZbSCb2b73H2HpS3KXEOwnHtdu1c4c+nTvxcAZa5Jljk eKFlDn6FTlsFaTRzUkvHjBpE+VP828puZiBPKECsnVS9W8NvFCS9isgfp06tt4n1 zFDWPXAIu/jAshEAR/1RCAvXTJdTI0NPAgd39lPL2ww0AtpJLKZ9PzqgXKWadqJJ tLafe7asxDUE2xEdgg0rqcPabdJJQtsxWxnJvM15H5FnccrOzFu35UdFpVTpCudn KIyez6i6QtVNSzdVrEMCXX6Ya4g4PzVCFDDCpvnJnA90jzdO8D5mXLAqgILu+yN7 YUmOrycO4vQKlkZQ34kBetWUys3hh7NhH67R8jW9GRoEB6tgUV9UcU3EOtLEgpba IDjQl04jvTHVEGqaMWdWqYSOWFIHtuAS0e3/McY+Samjza68pqVHqWXYWWaYhc8G dDnGUgF6Wf3YhOyc/vY3MIfypiUkk8JlOvikSajL1uHZDbOrE8Y= =kcFr -----END PGP SIGNATURE----- --a5vexcpswcrswy5e--