bug-groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #64421] [troff] link-time optimization changes `.m` register initia


From: G. Branden Robinson
Subject: [bug #64421] [troff] link-time optimization changes `.m` register initialization
Date: Wed, 6 Sep 2023 01:21:15 -0400 (EDT)

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/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]