Testlib/Windows: Output crash information on stdout instead of stderr.

Make it easier to capture information about crashing tests in log files,
since it is not possible to do something like
foo > log.txt 2> errlog.txt
on Windows.
Adapt selftest.

[ChangeLog][QtTest][Important Behavior Changes] Crash/exception
information is now logged to standard output on Windows.

Task-number: QTBUG-47370
Change-Id: I3e6a2d25855ed0f20516418a031990b562f5f757
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This commit is contained in:
Friedemann Kleint 2015-09-02 16:26:41 +02:00 committed by Simon Hausmann
parent e6a2ba7089
commit c486cacba8
2 changed files with 17 additions and 9 deletions

View File

@ -2796,7 +2796,7 @@ static LONG WINAPI windowsFaultHandler(struct _EXCEPTION_POINTERS *exInfo)
appName[0] = 0; appName[0] = 0;
const void *exceptionAddress = exInfo->ExceptionRecord->ExceptionAddress; const void *exceptionAddress = exInfo->ExceptionRecord->ExceptionAddress;
fprintf(stderr, "A crash occurred in %s.\n\n" printf("A crash occurred in %s.\n\n"
"Exception address: 0x%p\n" "Exception address: 0x%p\n"
"Exception code : 0x%lx\n", "Exception code : 0x%lx\n",
appName, exceptionAddress, exInfo->ExceptionRecord->ExceptionCode); appName, exceptionAddress, exInfo->ExceptionRecord->ExceptionCode);
@ -2805,24 +2805,25 @@ static LONG WINAPI windowsFaultHandler(struct _EXCEPTION_POINTERS *exInfo)
if (resolver.isValid()) { if (resolver.isValid()) {
DebugSymbolResolver::Symbol exceptionSymbol = resolver.resolveSymbol(DWORD64(exceptionAddress)); DebugSymbolResolver::Symbol exceptionSymbol = resolver.resolveSymbol(DWORD64(exceptionAddress));
if (exceptionSymbol.name) { if (exceptionSymbol.name) {
fprintf(stderr, "Nearby symbol : %s\n", exceptionSymbol.name); printf("Nearby symbol : %s\n", exceptionSymbol.name);
delete [] exceptionSymbol.name; delete [] exceptionSymbol.name;
} }
void *stack[maxStackFrames]; void *stack[maxStackFrames];
fputs("\nStack:\n", stderr); fputs("\nStack:\n", stdout);
const unsigned frameCount = CaptureStackBackTrace(0, DWORD(maxStackFrames), stack, NULL); const unsigned frameCount = CaptureStackBackTrace(0, DWORD(maxStackFrames), stack, NULL);
for (unsigned f = 0; f < frameCount; ++f) { for (unsigned f = 0; f < frameCount; ++f) {
DebugSymbolResolver::Symbol symbol = resolver.resolveSymbol(DWORD64(stack[f])); DebugSymbolResolver::Symbol symbol = resolver.resolveSymbol(DWORD64(stack[f]));
if (symbol.name) { if (symbol.name) {
fprintf(stderr, "#%3u: %s() - 0x%p\n", f + 1, symbol.name, (const void *)symbol.address); printf("#%3u: %s() - 0x%p\n", f + 1, symbol.name, (const void *)symbol.address);
delete [] symbol.name; delete [] symbol.name;
} else { } else {
fprintf(stderr, "#%3u: Unable to obtain symbol\n", f + 1); printf("#%3u: Unable to obtain symbol\n", f + 1);
} }
} }
} }
fputc('\n', stderr); fputc('\n', stdout);
fflush(stdout);
return EXCEPTION_EXECUTE_HANDLER; return EXCEPTION_EXECUTE_HANDLER;
} }

View File

@ -625,6 +625,13 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge
for (int n = 0; n < loggers.count(); ++n) { for (int n = 0; n < loggers.count(); ++n) {
QString logger = loggers[n]; QString logger = loggers[n];
#if defined(Q_OS_WIN)
if (n == 0 && subdir == QLatin1String("crashes")) { // Remove stack trace which is output to stdout.
const int exceptionLogStart = actualOutputs.first().indexOf("A crash occurred in ");
if (exceptionLogStart >= 0)
actualOutputs[0].truncate(exceptionLogStart);
}
#endif // Q_OS_WIN
QList<QByteArray> res = splitLines(actualOutputs[n]); QList<QByteArray> res = splitLines(actualOutputs[n]);
const QString expectedFileName = expectedFileNameFromTest(subdir, logger); const QString expectedFileName = expectedFileNameFromTest(subdir, logger);
QList<QByteArray> exp = expectedResult(expectedFileName); QList<QByteArray> exp = expectedResult(expectedFileName);