According to the GCC documentation (look at
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html)
"the order in which constructors for C++ objects with static storage
duration and functions decorated with attribute constructor are invoked
is unspecified". This means that for example using std::cout in the
function with a constructor attribute is dangerous as the std::cout
(global object) may have not been initialized yet (see this bug report
for better explanation -
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94810).

The test tst-tls.cc compiled as PIE includes assertions executed
as part of the before_main() function which is annotated with a
constructor attribute and gets called before the regular main.
The before_main() calls report() function which uses std::cout to
print assertion result. This happens to work fine when OSv exports
all symbols including the stdc++ ones like std::cout which is
initialized by then, but crashes miserably on Linux and OSv with
most symbols and stdc++ hidden.

This patch fixes the test to make it work correctly in all cases
by changing report() function to use std::cout or printf() depending
on where in the program lifecycle it is called.

Signed-off-by: Waldemar Kozaczuk <[email protected]>
---
 tests/tst-tls.cc | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/tests/tst-tls.cc b/tests/tst-tls.cc
index 58154382..da09ca1e 100644
--- a/tests/tst-tls.cc
+++ b/tests/tst-tls.cc
@@ -50,11 +50,15 @@ __thread int v10 __attribute__ ((tls_model ("local-exec"))) 
= 1111;
 
 extern void external_library();
 
-static void report(bool ok, std::string msg)
+static void report(bool ok, std::string msg, bool use_printf = false)
 {
     ++tests;
     fails += !ok;
-    std::cout << (ok ? "PASS" : "FAIL") << ": " << msg << "\n";
+    if (use_printf) {
+        printf("%s: %s\n", ok ? "PASS" : "FAIL", msg.c_str());
+    } else {
+        std::cout << (ok ? "PASS" : "FAIL") << ": " << msg << "\n";
+    }
 }
 
 int main(int argc, char** argv)
@@ -124,8 +128,8 @@ int main(int argc, char** argv)
 static void before_main(void) __attribute__((constructor));
 static void before_main(void)
 {
-    report(v7 == 987UL, "v7 in init function");
-    report(v9 == 0, "v8 in init function");
+    report(v7 == 987UL, "v7 in init function", true);
+    report(v9 == 0, "v8 in init function", true);
 }
 #endif
 
-- 
2.31.1

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/20220109011732.903007-1-jwkozaczuk%40gmail.com.

Reply via email to