Description
Change "8146009: "pure virtual method called" with using new GC logging mechanism" introduced a sophisticated initialization mechanism for the logging stream. In order to avoid deconstruction of the streams before the VM exits, it creates them with a placement new into statically allocated memory:
static bool initialized;
static char stdoutmem[sizeof(LogStdoutOutput)];
static char stderrmem[sizeof(LogStderrOutput)];
LogStdoutOutput &StdoutLog = reinterpret_cast<LogStdoutOutput&>(stdoutmem);
LogStderrOutput &StderrLog = reinterpret_cast<LogStderrOutput&>(stderrmem);
LogFileStreamInitializer::LogFileStreamInitializer() {
if (!initialized) {
::new (&StdoutLog) LogStdoutOutput();
::new (&StderrLog) LogStderrOutput();
initialized = true;
}
}
Unfortunately it is not guaranteed, that the static memory (which is a char array) is well-aligned for the stream objects. Actually, the C++ standard only defines that it has to be at least 'char' aligned which is obviously not enough for a stream object.
When building 'slowdebug' on Solaris with SS12u4 we indeed observed reproducible crashes during VM initialization because of this issue.
The fix is easy - just wrap the character arrays into unions to align them appropriately:
static union {
char stdoutmem[sizeof(LogStdoutOutput)];
void* dummy;
} aligned_stdoutmem;
static union {
char stderrmem[sizeof(LogStderrOutput)];
void* dummy;
} aligned_stderrmem;
LogStdoutOutput &StdoutLog = reinterpret_cast<LogStdoutOutput&>(aligned_stdoutmem.stdoutmem);
LogStderrOutput &StderrLog = reinterpret_cast<LogStderrOutput&>(aligned_stderrmem.stderrmem);
static bool initialized;
static char stdoutmem[sizeof(LogStdoutOutput)];
static char stderrmem[sizeof(LogStderrOutput)];
LogStdoutOutput &StdoutLog = reinterpret_cast<LogStdoutOutput&>(stdoutmem);
LogStderrOutput &StderrLog = reinterpret_cast<LogStderrOutput&>(stderrmem);
LogFileStreamInitializer::LogFileStreamInitializer() {
if (!initialized) {
::new (&StdoutLog) LogStdoutOutput();
::new (&StderrLog) LogStderrOutput();
initialized = true;
}
}
Unfortunately it is not guaranteed, that the static memory (which is a char array) is well-aligned for the stream objects. Actually, the C++ standard only defines that it has to be at least 'char' aligned which is obviously not enough for a stream object.
When building 'slowdebug' on Solaris with SS12u4 we indeed observed reproducible crashes during VM initialization because of this issue.
The fix is easy - just wrap the character arrays into unions to align them appropriately:
static union {
char stdoutmem[sizeof(LogStdoutOutput)];
void* dummy;
} aligned_stdoutmem;
static union {
char stderrmem[sizeof(LogStderrOutput)];
void* dummy;
} aligned_stderrmem;
LogStdoutOutput &StdoutLog = reinterpret_cast<LogStdoutOutput&>(aligned_stdoutmem.stdoutmem);
LogStderrOutput &StderrLog = reinterpret_cast<LogStderrOutput&>(aligned_stderrmem.stderrmem);
Attachments
Issue Links
- duplicates
-
JDK-8170321 Solaris sparc slowdebug crashes at startup
-
- Closed
-
- relates to
-
JDK-8146009 "pure virtual method called" with using new GC logging mechanism
-
- Closed
-