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 <jwkozac...@gmail.com>
---
 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 osv-dev+unsubscr...@googlegroups.com.
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