@@ -421,8 +421,19 @@ stringStream::~stringStream() {
421421 }
422422}
423423
424+ // tty needs to be always accessible since there are code paths that may write to it
425+ // outside of the VM lifespan.
426+ // Examples for pre-VM-init accesses: Early NMT init, Early UL init
427+ // Examples for post-VM-exit accesses: many, e.g. NMT C-heap bounds checker, signal handling, AGCT, ...
428+ // During lifetime tty is served by an instance of defaultStream. That instance's deletion cannot
429+ // be (easily) postponed or omitted since it has ties to the JVM infrastructure.
430+ // The policy followed here is a compromise reached during review of JDK-8292351:
431+ // - pre-init: we silently swallow all output. We won't see anything, but at least won't crash
432+ // - post-exit: we write to a simple fdStream, but somewhat mimic the behavior of the real defaultStream
433+ static nullStream tty_preinit_stream;
434+ outputStream* tty = &tty_preinit_stream;
435+
424436xmlStream* xtty;
425- outputStream* tty;
426437extern Mutex* tty_lock;
427438
428439#define EXTRACHARLEN 32
@@ -615,6 +626,9 @@ void fileStream::flush() {
615626 }
616627}
617628
629+ fdStream fdStream::_stdout_stream (1 );
630+ fdStream fdStream::_stderr_stream (2 );
631+
618632void fdStream::write (const char * s, size_t len) {
619633 if (_fd != -1 ) {
620634 // Make an unused local variable to avoid warning from gcc compiler.
@@ -961,13 +975,13 @@ void ostream_exit() {
961975 if (ostream_exit_called) return ;
962976 ostream_exit_called = true ;
963977 ClassListWriter::delete_classlist ();
964- if ( tty != defaultStream::instance) {
965- delete tty;
966- }
967- if (defaultStream::instance != NULL ) {
968- delete defaultStream::instance ;
978+ // Make sure tty works after VM exit by assigning an always-on functioning fdStream.
979+ outputStream* tmp = tty;
980+ tty = DisplayVMOutputToStderr ? fdStream::stdout_stream () : fdStream::stderr_stream ();
981+ if (tmp != &tty_preinit_stream && tmp != defaultStream::instance ) {
982+ delete tmp ;
969983 }
970- tty = NULL ;
984+ delete defaultStream::instance ;
971985 xtty = NULL ;
972986 defaultStream::instance = NULL ;
973987}
0 commit comments