Fix std::cout/std::cerr static initialization order fiasco.
The benchmark library internals write to std::cout/std::cerr during program
startup. This can cause segfaults when the user doesn't include <iostream> in
the benchmark (which init's the streams). This patch fixes this by emitting
a dynamic initializer in every TU which initializes the streams.
diff --git a/include/benchmark/benchmark_api.h b/include/benchmark/benchmark_api.h
index ddfcb01..8deee87 100644
--- a/include/benchmark/benchmark_api.h
+++ b/include/benchmark/benchmark_api.h
@@ -214,6 +214,10 @@
// registered benchmark.
Benchmark* RegisterBenchmarkInternal(Benchmark*);
+// Ensure that the standard streams are properly initialized in every TU.
+int InitializeStreams();
+static int stream_init_anchor = InitializeStreams();
+
} // end namespace internal
diff --git a/src/benchmark.cc b/src/benchmark.cc
index 3a199e5..fca23e9 100644
--- a/src/benchmark.cc
+++ b/src/benchmark.cc
@@ -1199,6 +1199,11 @@
return bench;
}
+int InitializeStreams() {
+ static std::ios_base::Init init;
+ return 0;
+}
+
} // end namespace internal
void Initialize(int* argc, char** argv) {