Flush the CFG visualizer output after writing to it.
This fixes test failures exposed by the ART Buildbot in
608-checker-unresolved-lse (AOT) on the hammerhead-ndebug
configuration. The test used to fail because the CFG file
dumped by second invocation of dex2oat on device would be
truncated (at the beginning of the disassembly section
of the second compiled Dex file's contents) because of
dex2oat's fast exit.
Interestingly enough, this is the only case where this
failure has been observed, which seems to be due to a
combination of:
- targeting (32-bit) ARM;
- using a secondary Dex file (used to create an unresolved
access for that test);
- compiling that secondary Dex file with dex2oat (ndebug
mode) instead of dex2oatd;
- supporting multithread CFG graph dumping (by having the
write-to-file operation in a critical section) since
https://android-review.googlesource.com/#/c/296224/.
Test: art/test/run-test -O --debuggable 608-checker-unresolved-lse
Change-Id: Ifc1a23a3708b8645fd36c148312074bb9fe00cfc
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 8c76927..19fd6f9 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -170,6 +170,15 @@
if (visualizer_enabled_) {
MutexLock mu(Thread::Current(), visualizer_dump_mutex_);
*visualizer_output_ << visualizer_oss_.str();
+ // The destructor of `visualizer_output_` is normally
+ // responsible for flushing (and closing) the stream, but it
+ // won't be invoked during fast exits in non-debug mode -- see
+ // art::Dex2Oat::~Dex2Oat, which explicitly abandons some
+ // objects (such as the compiler driver) in non-debug mode, to
+ // avoid the cost of destructing them. Therefore we explicitly
+ // flush the stream here to prevent truncated CFG visualizer
+ // files.
+ visualizer_output_->flush();
}
}