Follow-up Comment #33, bug #64421 (project groff): Link-time optimization is doing something clever that I don't understand.
The problem, not surprisingly, is the reading of an uninitialized variable. Our problematic friend is an object named `default_color`. It belongs to the `color` class. https://git.savannah.gnu.org/cgit/groff.git/tree/src/include/color.h?h=1.23.0#n26 Notice that the color class has a public member of type 'symbol', another class that is used for fairly broad purposes, but approximately speaking, anything that can have an identifier in the _groff_ language possesses a 'symbol' naming it. https://git.savannah.gnu.org/cgit/groff.git/tree/src/include/color.h?h=1.23.0#n36 Looking at the symbol class, we notice that it has a private C string member called "s", accessed via the public member function "contents". https://git.savannah.gnu.org/cgit/groff.git/tree/src/include/color.h?h=1.23.0#n36 Another thing we might notice is that is always at least one object of type 'symbol' exists even before the formatter enters `main`-- it's named "default". https://git.savannah.gnu.org/cgit/groff.git/tree/src/libs/libgroff/symbol.cpp?h=1.23.0#n157 Observe that "default_symbol" is *constructed*. symbol default_symbol("default"); There is also always a default color. It has a bare declaration in the global scope; it is therefore backed by storage, and ends up in the BSS section (all zeroes, conventionally). $ objdump -x ~/groff-stable/bin/troff |grep default_color 00000000000b6320 g O .bss 0000000000000028 default_color Importantly, observe that this object is *not constructed*. It experiences no initialization. https://git.savannah.gnu.org/cgit/groff.git/tree/src/libs/libgroff/color.cpp?h=1.23.0#n398 And link-time optimization *changes this symbol*. It's still in BSS, but... $ objdump -x ./build/troff |grep default_color 00000000000af4e0 g O .bss 0000000000000028 .hidden default_color Now it's `.hidden`. Whatever that means. Time to find out by grubbing around in ELF x86-64 ABI documentation I guess--printed copies of it are the cobblestones of the byways of Hell--to see if this is a bug in link-time optimization. I would guess not, though--I anticipate the response would be that we (groff) did something stupid by not RAIIing and therefore we gave the LTO machine free rein to screw us. Feel free to play around with this patch if you need more convincing. diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index 94ad67279..a2e7876a1 100644 --- a/src/roff/troff/input.cpp +++ b/src/roff/troff/input.cpp @@ -8378,6 +8378,8 @@ int main(int argc, char **argv) } if (!no_rc) process_startup_file(FINAL_STARTUP_FILE); + debug("GBR: default color is '%1'", default_color.nm.contents()); + //assert(0 == strcmp(default_color.nm.contents(), "")); for (i = optind; i < argc; i++) process_input_file(argv[i]); if (optind >= argc || iflag) This patch fixes the problem. diff --git a/src/libs/libgroff/color.cpp b/src/libs/libgroff/color.cpp index 388c2ee9e..32a1bc8e7 100644 --- a/src/libs/libgroff/color.cpp +++ b/src/libs/libgroff/color.cpp @@ -395,7 +395,7 @@ char *color::print_color() return s; } -color default_color; +color default_color(""); // Local Variables: // fill-column: 72 Comments? I think I'm going to pour myself a strong drink and go to sleep. _______________________________________________________ Reply to this item at: <https://savannah.gnu.org/bugs/?64421> _______________________________________________ Message sent via Savannah https://savannah.gnu.org/