summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/users_guide/8.4.1-notes.rst4
-rw-r--r--docs/users_guide/runtime_control.rst6
-rw-r--r--includes/rts/Flags.h1
-rw-r--r--libraries/base/GHC/RTS/Flags.hsc3
-rw-r--r--libraries/base/changelog.md3
-rw-r--r--rts/Linker.c15
-rw-r--r--rts/LinkerInternals.h3
-rw-r--r--rts/RtsFlags.c15
-rw-r--r--rts/linker/PEi386.c196
-rw-r--r--rts/linker/PEi386.h2
-rw-r--r--rts/package.conf.in1
-rw-r--r--rts/win32/veh_excn.c96
-rw-r--r--rts/win32/veh_excn.h1
-rw-r--r--testsuite/tests/rts/all.T8
-rw-r--r--testsuite/tests/rts/derefnull.stdout-i386-unknown-mingw321
-rw-r--r--testsuite/tests/rts/derefnull.stdout-x86_64-unknown-mingw321
-rw-r--r--testsuite/tests/rts/divbyzero.stdout-i386-unknown-mingw321
-rw-r--r--testsuite/tests/rts/divbyzero.stdout-x86_64-unknown-mingw321
18 files changed, 346 insertions, 12 deletions
diff --git a/docs/users_guide/8.4.1-notes.rst b/docs/users_guide/8.4.1-notes.rst
index f59d266789..b787e2e626 100644
--- a/docs/users_guide/8.4.1-notes.rst
+++ b/docs/users_guide/8.4.1-notes.rst
@@ -188,6 +188,10 @@ Runtime system
the list of search directories of GCC and querying the file system directly. This results in
much better performance, especially on Windows.
+- The GHC runtime on Windows can now generate stack traces on unhandled exceptions.
+ When running in GHCi more information is displayed about the symbols if available.
+ This behavior can be controlled with the RTS flag `--generate-stack-traces=<yes|no>`.
+
Template Haskell
~~~~~~~~~~~~~~~~
diff --git a/docs/users_guide/runtime_control.rst b/docs/users_guide/runtime_control.rst
index 905048c69b..9b43277da4 100644
--- a/docs/users_guide/runtime_control.rst
+++ b/docs/users_guide/runtime_control.rst
@@ -235,6 +235,12 @@ Miscellaneous RTS options
The dumps record all code, registers and threading information at the time
of the crash. Note that this implies `--install-seh-handlers=yes`.
+.. rts-flag:: --generate-stack-traces=<yes|no>
+
+ If yes (the default), the RTS on Windows will generate a stack trace on
+ crashes if exception handling are enabled. In order to get more information
+ in compiled executables, C code or DLLs symbols need to be available.
+
.. rts-flag:: -xm ⟨address⟩
.. index::
diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h
index 4cc267072d..ff45bd378f 100644
--- a/includes/rts/Flags.h
+++ b/includes/rts/Flags.h
@@ -191,6 +191,7 @@ typedef struct _MISC_FLAGS {
bool install_signal_handlers;
bool install_seh_handlers;
bool generate_dump_file;
+ bool generate_stack_trace;
bool machineReadable;
StgWord linkerMemBase; /* address to ask the OS for memory
* for the linker, NULL ==> off */
diff --git a/libraries/base/GHC/RTS/Flags.hsc b/libraries/base/GHC/RTS/Flags.hsc
index 7d5b705fd4..1f997c80db 100644
--- a/libraries/base/GHC/RTS/Flags.hsc
+++ b/libraries/base/GHC/RTS/Flags.hsc
@@ -133,6 +133,7 @@ data MiscFlags = MiscFlags
, installSignalHandlers :: Bool
, installSEHHandlers :: Bool
, generateCrashDumpFile :: Bool
+ , generateStackTrace :: Bool
, machineReadable :: Bool
, linkerMemBase :: Word
-- ^ address to ask the OS for memory for the linker, 0 ==> off
@@ -423,6 +424,8 @@ getMiscFlags = do
<*> (toBool <$>
(#{peek MISC_FLAGS, generate_dump_file} ptr :: IO CBool))
<*> (toBool <$>
+ (#{peek MISC_FLAGS, generate_stack_trace} ptr :: IO CBool))
+ <*> (toBool <$>
(#{peek MISC_FLAGS, machineReadable} ptr :: IO CBool))
<*> #{peek MISC_FLAGS, linkerMemBase} ptr
diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index 7c521f9683..bc0f4d4189 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -64,6 +64,9 @@
* Add `generateCrashDumpFile` to `MiscFlags` in `GHC.RTS.Flags` to determine
if a core dump will be generated on crashes.
+ * Add `generateStackTrace` to `MiscFlags` in `GHC.RTS.Flags` to determine if
+ stack traces will be generated on unhandled exceptions by the RTS.
+
## 4.10.0.0 *July 2017*
* Bundled with GHC 8.2.1
diff --git a/rts/Linker.c b/rts/Linker.c
index 30d7e87f92..8f55c296a6 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -980,6 +980,21 @@ void ghci_enquire(SymbolAddr* addr)
}
#endif
+pathchar*
+resolveSymbolAddr (pathchar* buffer, int size,
+ SymbolAddr* symbol, uintptr_t* top)
+{
+#if defined(OBJFORMAT_PEi386)
+ return resolveSymbolAddr_PEi386 (buffer, size, symbol, top);
+#else /* OBJFORMAT_PEi386 */
+ (void)buffer;
+ (void)size;
+ (void)symbol;
+ (void)top;
+ return NULL;
+#endif /* OBJFORMAT_PEi386 */
+}
+
#if RTS_LINKER_USE_MMAP
//
// Returns NULL on failure.
diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h
index dd17be0992..21602f15aa 100644
--- a/rts/LinkerInternals.h
+++ b/rts/LinkerInternals.h
@@ -264,6 +264,9 @@ SymbolAddr* lookupSymbol_ (SymbolName* lbl);
extern /*Str*/HashTable *symhash;
+pathchar*
+resolveSymbolAddr (pathchar* buffer, int size,
+ SymbolAddr* symbol, uintptr_t* top);
/*************************************************
* Various bits of configuration
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c
index 5bdf9922de..c0571368cd 100644
--- a/rts/RtsFlags.c
+++ b/rts/RtsFlags.c
@@ -226,6 +226,7 @@ void initRtsFlagsDefaults(void)
RtsFlags.MiscFlags.install_signal_handlers = true;
RtsFlags.MiscFlags.install_seh_handlers = true;
+ RtsFlags.MiscFlags.generate_stack_trace = true;
RtsFlags.MiscFlags.generate_dump_file = false;
RtsFlags.MiscFlags.machineReadable = false;
RtsFlags.MiscFlags.linkerMemBase = 0;
@@ -435,6 +436,10 @@ usage_text[] = {
" Generate Windows crash dumps, requires exception handlers",
" to be installed. Implies --install-signal-handlers=yes.",
" (default: no)",
+" --generate-stack-traces=<yes|no>",
+" Generate a stack trace when your application encounters a",
+" fatal error. When symbols are available an attempt will be",
+" made to resolve addresses to names. (default: yes)",
#endif
#if defined(THREADED_RTS)
" -e<n> Maximum number of outstanding local sparks (default: 4096)",
@@ -860,6 +865,16 @@ error = true;
OPTION_UNSAFE;
RtsFlags.MiscFlags.install_seh_handlers = false;
}
+ else if (strequal("generate-stack-traces=yes",
+ &rts_argv[arg][2])) {
+ OPTION_UNSAFE;
+ RtsFlags.MiscFlags.generate_stack_trace = true;
+ }
+ else if (strequal("generate-stack-traces=no",
+ &rts_argv[arg][2])) {
+ OPTION_UNSAFE;
+ RtsFlags.MiscFlags.generate_stack_trace = false;
+ }
else if (strequal("generate-crash-dumps",
&rts_argv[arg][2])) {
OPTION_UNSAFE;
diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c
index 4378a0a61d..3dcf8c4281 100644
--- a/rts/linker/PEi386.c
+++ b/rts/linker/PEi386.c
@@ -153,6 +153,10 @@
static uint8_t* cstring_from_COFF_symbol_name(
uint8_t* name,
uint8_t* strtab);
+#include <inttypes.h>
+#include <dbghelp.h>
+#include <stdlib.h>
+#include <Psapi.h>
#if defined(x86_64_HOST_ARCH)
static size_t makeSymbolExtra_PEi386(
@@ -2059,4 +2063,196 @@ SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl)
}
}
+/* -----------------------------------------------------------------------------
+ * Debugging operations.
+ */
+
+pathchar*
+resolveSymbolAddr_PEi386 (pathchar* buffer, int size,
+ SymbolAddr* symbol, uintptr_t* top ){
+ SYMBOL_INFO sym;
+ ZeroMemory (&sym, sizeof(SYMBOL_INFO));
+ sym.MaxNameLen = sizeof(char) * 1024;
+
+ DWORD64 uDisplacement = 0;
+ HANDLE hProcess = GetCurrentProcess();
+ ObjectCode* obj = NULL;
+ uintptr_t start, end;
+ *top = 0;
+
+ pathprintf (buffer, size, WSTR("0x%" PRIxPTR), symbol);
+
+ if (SymFromAddr (hProcess, (uintptr_t)symbol, &uDisplacement, &sym))
+ {
+ /* Try using Windows symbols. */
+ wcscat (buffer, WSTR(" "));
+ pathchar* name = mkPath (sym.Name);
+ wcscat (buffer, name);
+ stgFree (name);
+ if (uDisplacement != 0)
+ {
+ int64_t displacement = (int64_t)uDisplacement;
+ pathchar s_disp[50];
+ if (displacement < 0)
+ pathprintf ((pathchar*)s_disp, 50, WSTR("-%ld"), -displacement);
+ else
+ pathprintf ((pathchar*)s_disp, 50, WSTR("+%ld"), displacement);
+
+ wcscat (buffer, s_disp);
+ }
+ }
+ else
+ {
+ /* Try to calculate from information inside the rts. */
+ uintptr_t loc = (uintptr_t)symbol;
+ for (ObjectCode* oc = objects; oc; oc = oc->next) {
+ for (int i = 0; i < oc->n_sections; i++) {
+ Section section = oc->sections[i];
+ start = (uintptr_t)section.start;
+ end = start + section.size;
+ if (loc > start && loc <= end)
+ {
+ wcscat (buffer, WSTR(" "));
+ if (oc->archiveMemberName)
+ {
+ pathchar* name = mkPath (oc->archiveMemberName);
+ wcscat (buffer, name);
+ stgFree (name);
+ }
+ else
+ {
+ wcscat (buffer, oc->fileName);
+ }
+ pathchar s_disp[50];
+ pathprintf (s_disp, 50, WSTR("+0x%" PRIxPTR), loc - start);
+ wcscat (buffer, s_disp);
+ obj = oc;
+ goto exit_loop;
+ }
+ }
+ }
+
+ /* If we managed to make it here, we must not have any symbols nor be
+ dealing with code we've linked. The only thing left is an internal
+ segfault or one in a dynamic library. So let's enumerate the module
+ address space. */
+ HMODULE *hMods = NULL;
+ DWORD cbNeeded;
+ EnumProcessModules (hProcess, hMods, 0, &cbNeeded);
+ hMods = stgMallocBytes (cbNeeded, "resolveSymbolAddr_PEi386");
+ if (EnumProcessModules (hProcess, hMods, cbNeeded, &cbNeeded))
+ {
+ uintptr_t loc = (uintptr_t)symbol;
+ MODULEINFO info;
+ for (uint32_t i = 0; i < cbNeeded / sizeof(HMODULE); i++) {
+ ZeroMemory (&info, sizeof (MODULEINFO));
+ if (GetModuleInformation (hProcess, hMods[i], &info,
+ sizeof(MODULEINFO)))
+ {
+ uintptr_t start = (uintptr_t)info.lpBaseOfDll;
+ uintptr_t end = start + info.SizeOfImage;
+ if (loc >= start && loc < end)
+ {
+ /* Hoera, finally found some information. */
+ pathchar tmp[MAX_PATH];
+ if (GetModuleFileNameExW (hProcess, hMods[i], tmp, MAX_PATH))
+ {
+ wcscat (buffer, WSTR(" "));
+ wcscat (buffer, tmp);
+ pathprintf (tmp, MAX_PATH, WSTR("+0x%" PRIxPTR), loc - start);
+ wcscat (buffer, tmp);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ stgFree(hMods);
+ }
+
+ /* Finally any file/line number. */
+ IMAGEHLP_LINE64 lineInfo = {0};
+ DWORD dwDisplacement = 0;
+ exit_loop:
+ if (SymGetLineFromAddr64(hProcess, (uintptr_t)symbol, &dwDisplacement,
+ &lineInfo))
+ {
+ /* Try using Windows symbols. */
+ pathchar s_line[512];
+ pathprintf ((pathchar*) s_line, 512, WSTR(" %ls (%lu)"),
+ lineInfo.FileName, lineInfo.LineNumber);
+ wcscat (buffer, s_line);
+ if (dwDisplacement != 0)
+ {
+ pathprintf ((pathchar*) s_line, 512, WSTR(" +%lu byte%s"),
+ dwDisplacement,
+ (dwDisplacement == 1 ? WSTR("") : WSTR("s")));
+ }
+ wcscat (buffer, s_line);
+ }
+ else if (obj)
+ {
+ /* Try to calculate from information inside the rts. */
+ typedef struct _SymX { SymbolName* name; uintptr_t loc; } SymX;
+ SymX* locs = stgCallocBytes (sizeof(SymX), obj->n_symbols,
+ "resolveSymbolAddr");
+ int blanks = 0;
+ for (int i = 0; i < obj->n_symbols; i++) {
+ SymbolName* sym = obj->symbols[i];
+ if (sym == NULL)
+ {
+ blanks++;
+ continue;
+ }
+ RtsSymbolInfo* a = NULL;
+ ghciLookupSymbolInfo(symhash, sym, &a);
+ if (a) {
+ SymX sx = {0};
+ sx.name = sym;
+ sx.loc = (uintptr_t)a->value;
+ locs[i] = sx;
+ }
+ }
+ int comp (const void * elem1, const void * elem2)
+ {
+ SymX f = *((SymX*)elem1);
+ SymX s = *((SymX*)elem2);
+ if (f.loc > s.loc) return 1;
+ if (f.loc < s.loc) return -1;
+ return 0;
+ }
+ qsort (locs, obj->n_symbols, sizeof (SymX), comp);
+ uintptr_t key = (uintptr_t)symbol;
+ SymX* res = NULL;
+
+ for (int x = blanks; x < obj->n_symbols; x++) {
+ if (x < (obj->n_symbols -1)) {
+ if (locs[x].loc >= key && key < locs[x+1].loc) {
+ res = &locs[x];
+ break;
+ }
+ }
+ else
+ {
+ if (locs[x].loc >= key) {
+ res = &locs[x];
+ break;
+ }
+ }
+ }
+
+ if (res) {
+ pathchar s_disp[512];
+ *top = (uintptr_t)res->loc;
+ pathprintf ((pathchar*)s_disp, 512,
+ WSTR("\n\t\t (%s+0x%" PRIxPTR ")"),
+ res->name, res->loc - key);
+ wcscat (buffer, s_disp);
+ }
+ stgFree (locs);
+ }
+
+ return buffer;
+}
#endif /* mingw32_HOST_OS */
diff --git a/rts/linker/PEi386.h b/rts/linker/PEi386.h
index e84e05232a..e6fef74af8 100644
--- a/rts/linker/PEi386.h
+++ b/rts/linker/PEi386.h
@@ -57,6 +57,8 @@ SymbolAddr *lookupSymbol_PEi386(SymbolName *lbl);
bool ocAllocateSymbolExtras_PEi386 ( ObjectCode* oc );
SymbolAddr *lookupSymbolInDLLs ( unsigned char *lbl );
/* See Note [mingw-w64 name decoration scheme] */
+pathchar* resolveSymbolAddr_PEi386 ( pathchar* buffer, int size,
+ SymbolAddr* symbol, uintptr_t* top );
char *
allocateImageAndTrampolines (
diff --git a/rts/package.conf.in b/rts/package.conf.in
index 4eb75fc704..52d7ef8be2 100644
--- a/rts/package.conf.in
+++ b/rts/package.conf.in
@@ -46,6 +46,7 @@ extra-libraries:
,"gdi32" /* for the linker */
,"winmm" /* for the linker */
,"Dbghelp" /* for crash dump */
+ ,"Psapi" /* for process information. */
#endif
#if NEED_PTHREAD_LIB
, "pthread" /* for pthread_getthreadid_np, pthread_create, etc. */
diff --git a/rts/win32/veh_excn.c b/rts/win32/veh_excn.c
index 5105d7676f..3ac008d780 100644
--- a/rts/win32/veh_excn.c
+++ b/rts/win32/veh_excn.c
@@ -9,8 +9,12 @@
#include "Rts.h"
#include "ghcconfig.h"
#include "veh_excn.h"
+#include "LinkerInternals.h"
#include <assert.h>
#include <stdbool.h>
+#include <dbghelp.h>
+#include <shellapi.h>
+#include <shlobj.h>
#include <wchar.h>
#include <windows.h>
#include <stdio.h>
@@ -117,9 +121,14 @@ long WINAPI __hs_exception_handler(struct _EXCEPTION_POINTERS *exception_data)
case EXCEPTION_ACCESS_VIOLATION:
what = exception_data->ExceptionRecord->ExceptionInformation[0];
fprintf(stdout, "Access violation in generated code"
- " when %s %p\n"
- , what == 0 ? "reading" : what == 1 ? "writing" : what == 8 ? "executing data at" : "?"
- , (void*) exception_data->ExceptionRecord->ExceptionInformation[1]
+ " when %s 0x%" PRIxPTR "\n"
+ , what == 0 ? "reading"
+ : what == 1 ? "writing"
+ : what == 8 ? "executing data at"
+ : "?"
+ , (uintptr_t) exception_data
+ ->ExceptionRecord
+ ->ExceptionInformation[1]
);
action = EXCEPTION_CONTINUE_EXECUTION;
break;
@@ -132,6 +141,7 @@ long WINAPI __hs_exception_handler(struct _EXCEPTION_POINTERS *exception_data)
if (EXCEPTION_CONTINUE_EXECUTION == action)
{
fflush(stdout);
+ generateStack (exception_data);
generateDump (exception_data);
stg_exit(EXIT_FAILURE);
}
@@ -153,7 +163,6 @@ long WINAPI __hs_exception_filter(struct _EXCEPTION_POINTERS *exception_data)
}
crash_dump = true;
-
return result;
}
@@ -240,3 +249,82 @@ void generateDump (EXCEPTION_POINTERS* pExceptionPointers)
fprintf (stdout, "Crash dump created. Dump written to:\n\t%ls", szFileName);
}
+
+// Generate stack trace information, we can piggy back on information we know
+// about in the runtime linker to resolve symbols. So this is a good opportunity
+// to make the output more useful.
+void generateStack (EXCEPTION_POINTERS* pExceptionPointers)
+{
+ if (!RtsFlags.MiscFlags.generate_stack_trace)
+ return;
+
+ PCONTEXT context = pExceptionPointers->ContextRecord;
+ STACKFRAME64 stackFrame = {0};
+ DWORD machineType;
+
+#if defined(x86_64_HOST_ARCH)
+ machineType = IMAGE_FILE_MACHINE_AMD64;
+ stackFrame.AddrPC.Offset = context->Rip;
+ stackFrame.AddrPC.Mode = AddrModeFlat;
+
+ stackFrame.AddrFrame.Offset = context->Rbp;
+ stackFrame.AddrFrame.Mode = AddrModeFlat;
+
+ stackFrame.AddrStack.Offset = context->Rsp;
+ stackFrame.AddrStack.Mode = AddrModeFlat;
+#else
+ machineType = IMAGE_FILE_MACHINE_I386;
+ stackFrame.AddrPC.Offset = context->Eip;
+ stackFrame.AddrPC.Mode = AddrModeFlat;
+
+ stackFrame.AddrFrame.Offset = context->Ebp;
+ stackFrame.AddrFrame.Mode = AddrModeFlat;
+
+ stackFrame.AddrStack.Offset = context->Esp;
+ stackFrame.AddrStack.Mode = AddrModeFlat;
+#endif
+ fprintf (stdout, "\n Attempting to reconstruct a stack trace...\n\n");
+ if (!SymInitialize (GetCurrentProcess (), NULL, true))
+ fprintf (stdout, " \nNOTE: Symbols could not be loaded. Addresses may"
+ " be unresolved.\n\n");
+
+ /* Maximum amount of stack frames to show. */
+ /* Phyx: I'm not sure if I should make this configurable or not. Would a
+ longer stack really be more useful? usually you only care about the top
+ few. */
+ int max_frames = 35;
+
+ fprintf (stdout, " Frame\tCode address\n");
+ DWORD64 lastBp = 0; /* Prevent loops with optimized stackframes. */
+ while (StackWalk64 (machineType, GetCurrentProcess(), GetCurrentThread(),
+ &stackFrame, context, NULL, SymFunctionTableAccess64,
+ SymGetModuleBase64, NULL) && max_frames > 0)
+ {
+ if (stackFrame.AddrPC.Offset == 0)
+ {
+ fprintf (stdout, "Null address\n");
+ break;
+ }
+ wchar_t buffer[1024];
+ uintptr_t topSp = 0;
+ fprintf (stdout, " * 0x%" PRIxPTR "\t%ls\n",
+ (uintptr_t)stackFrame.AddrFrame.Offset,
+ resolveSymbolAddr ((wchar_t*)&buffer, 1024,
+ (SymbolAddr*)stackFrame.AddrPC.Offset,
+ &topSp));
+ if (lastBp >= stackFrame.AddrFrame.Offset)
+ {
+ fprintf (stdout, "Stack frame out of sequence...\n");
+ break;
+ }
+ lastBp = stackFrame.AddrFrame.Offset;
+
+ max_frames--;
+ if (max_frames ==0)
+ {
+ fprintf (stdout, "\n ... (maximum recursion depth reached.)\n");
+ }
+ }
+ fprintf (stdout, "\n");
+ fflush(stdout);
+}
diff --git a/rts/win32/veh_excn.h b/rts/win32/veh_excn.h
index 4a2134861c..e0a11ade58 100644
--- a/rts/win32/veh_excn.h
+++ b/rts/win32/veh_excn.h
@@ -71,3 +71,4 @@ void __unregister_hs_exception_handler( void );
// prototypes for dump methods.
void generateDump(EXCEPTION_POINTERS* pExceptionPointers);
+void generateStack (EXCEPTION_POINTERS* pExceptionPointers);
diff --git a/testsuite/tests/rts/all.T b/testsuite/tests/rts/all.T
index e81940479e..935e10ecad 100644
--- a/testsuite/tests/rts/all.T
+++ b/testsuite/tests/rts/all.T
@@ -35,12 +35,12 @@ test('derefnull',
when(platform('i386-apple-darwin'), [ignore_stderr, exit_code(139)]),
when(platform('x86_64-apple-darwin'), [ignore_stderr, exit_code(139)]),
when(platform('powerpc-apple-darwin'), [ignore_stderr, exit_code(139)]),
- when(opsys('mingw32'), [exit_code(1), normalise_fun(normalise_address)]),
+ when(opsys('mingw32'), [ignore_stderr, exit_code(127)]),
# since these test are supposed to crash the
# profile report will be empty always.
# so disable the check for profiling
when(opsys('mingw32'), omit_ways(prof_ways))],
- compile_and_run, [''])
+ compile_and_run, ['-with-rtsopts="--generate-stack-traces=no"'])
test('divbyzero',
[# SIGFPE on Linux
exit_code(136),
@@ -54,7 +54,7 @@ test('divbyzero',
# C programs compiled with gcc exit normally, so do we.
when(platform('powerpc64-unknown-linux'), [ignore_stdout, exit_code(0)]),
when(platform('powerpc64le-unknown-linux'), [ignore_stdout, exit_code(0)]),
- when(opsys('mingw32'), exit_code(1)),
+ when(opsys('mingw32'), [ignore_stderr, exit_code(127)]),
# The output under OS X is too unstable to readily compare
when(platform('i386-apple-darwin'), [ignore_stderr, exit_code(136)]),
when(platform('x86_64-apple-darwin'), [ignore_stderr, exit_code(136)]),
@@ -63,7 +63,7 @@ test('divbyzero',
# profile report will be empty always.
# so disable the check for profiling
when(opsys('mingw32'), omit_ways(prof_ways))],
- compile_and_run, [''])
+ compile_and_run, ['-with-rtsopts="--generate-stack-traces=no"'])
test('outofmem', when(opsys('darwin'), skip),
run_command, ['$MAKE -s --no-print-directory outofmem'])
diff --git a/testsuite/tests/rts/derefnull.stdout-i386-unknown-mingw32 b/testsuite/tests/rts/derefnull.stdout-i386-unknown-mingw32
deleted file mode 100644
index 4541b7fb28..0000000000
--- a/testsuite/tests/rts/derefnull.stdout-i386-unknown-mingw32
+++ /dev/null
@@ -1 +0,0 @@
-Access violation in generated code when reading ADDRESS
diff --git a/testsuite/tests/rts/derefnull.stdout-x86_64-unknown-mingw32 b/testsuite/tests/rts/derefnull.stdout-x86_64-unknown-mingw32
deleted file mode 100644
index 4541b7fb28..0000000000
--- a/testsuite/tests/rts/derefnull.stdout-x86_64-unknown-mingw32
+++ /dev/null
@@ -1 +0,0 @@
-Access violation in generated code when reading ADDRESS
diff --git a/testsuite/tests/rts/divbyzero.stdout-i386-unknown-mingw32 b/testsuite/tests/rts/divbyzero.stdout-i386-unknown-mingw32
deleted file mode 100644
index 466709b368..0000000000
--- a/testsuite/tests/rts/divbyzero.stdout-i386-unknown-mingw32
+++ /dev/null
@@ -1 +0,0 @@
-divide by zero
diff --git a/testsuite/tests/rts/divbyzero.stdout-x86_64-unknown-mingw32 b/testsuite/tests/rts/divbyzero.stdout-x86_64-unknown-mingw32
deleted file mode 100644
index 466709b368..0000000000
--- a/testsuite/tests/rts/divbyzero.stdout-x86_64-unknown-mingw32
+++ /dev/null
@@ -1 +0,0 @@
-divide by zero