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 <
jwkoz...@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