memset (&hashes, 0, sizeof (MonoStackHash));
MonoContext *ctx = NULL;
+ while (!mono_dump_start ())
+ g_usleep (1000); // wait around for other dump to finish
+
mono_get_runtime_callbacks ()->install_state_summarizer ();
mono_summarize_timeline_start ();
g_free (scratch);
mono_summarize_timeline_phase_log (MonoSummaryDone);
+
+ mono_dump_complete ();
#else
*portable_hash = 0;
*unportable_hash = 0;
#include <mono/metadata/gc-internals.h>
#include <mono/metadata/mono-debug.h>
#include <mono/utils/mono-mmap.h>
+#include <mono/utils/mono-state.h>
#include "mini.h"
#include "mini-amd64.h"
}
#endif
- mono_handle_native_crash ("SIGSEGV", NULL, NULL);
+ if (mono_dump_start ())
+ mono_handle_native_crash ("SIGSEGV", NULL, NULL);
return EXCEPTION_CONTINUE_SEARCH;
}
gboolean stack_ovf = (flags & 1) != 0;
gboolean nullref = (flags & 2) != 0;
- if (!ji || (!stack_ovf && !nullref))
- mono_handle_native_crash ("SIGSEGV", ctx, NULL);
+ if (!ji || (!stack_ovf && !nullref)) {
+ if (mono_dump_start ())
+ mono_handle_native_crash ("SIGSEGV", ctx, NULL);
+ // if couldn't dump or if mono_handle_native_crash returns, abort
+ abort ();
+ }
mctx = *ctx;
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/exception.h>
#include <mono/metadata/mono-debug.h>
+#include <mono/utils/mono-state.h>
#include "mini.h"
#include "mini-ppc.h"
abort ();
}
if (!ji)
- mono_handle_native_crash ("SIGSEGV", sigctx, siginfo);
+ if (mono_dump_start ())
+ mono_handle_native_crash ("SIGSEGV", sigctx, siginfo);
/* setup a call frame on the real stack so that control is returned there
* and exception handling can continue.
* The frame looks like:
#include <mono/metadata/gc-internals.h>
#include <mono/metadata/mono-debug.h>
#include <mono/utils/mono-mmap.h>
+#include <mono/utils/mono-state.h>
#include "mini.h"
#include "mini-x86.h"
return (*mono_old_win_toplevel_exception_filter)(ep);
}
#endif
-
- mono_handle_native_crash ("SIGSEGV", NULL, NULL);
+ if (mono_dump_start ())
+ mono_handle_native_crash ("SIGSEGV", NULL, NULL);
return EXCEPTION_CONTINUE_SEARCH;
}
if (!ji) {
MonoContext mctx;
mono_sigctx_to_monoctx (sigctx, &mctx);
- mono_handle_native_crash ("SIGSEGV", &mctx, siginfo);
+ if (mono_dump_start ())
+ mono_handle_native_crash ("SIGSEGV", &mctx, siginfo);
+ else
+ abort ();
}
/* setup a call frame on the real stack so that control is returned there
* and exception handling can continue.
if (mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
return;
mono_sigctx_to_monoctx (ctx, &mctx);
- mono_handle_native_crash ("SIGABRT", &mctx, info);
+ if (mono_dump_start ())
+ mono_handle_native_crash ("SIGABRT", &mctx, info);
+ else
+ abort ();
}
}
// Will return when the dumping is done, so this thread can continue
// running. Returns FALSE on unrecoverable error.
- if (!mono_threads_summarize_execute (&mctx, &output, &hashes, FALSE, NULL, 0))
- g_error ("Crash reporter dumper exited due to fatal error.");
+ if (mono_dump_start ()) {
+ // Process was killed from outside since crash reporting wasn't running yet.
+ mono_handle_native_crash ("SIGTERM", &mctx, NULL);
+ } else {
+ // Crash reporting already running and we got a second SIGTERM from as part of thread-summarizing
+ if (!mono_threads_summarize_execute (&mctx, &output, &hashes, FALSE, NULL, 0))
+ g_error ("Crash reporter dumper exited due to fatal error.");
+ }
#endif
mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
dump_for_merp = mono_merp_enabled ();
#endif
+#ifndef DISABLE_STRUCTURED_CRASH
+ mini_register_sigterm_handler ();
+#endif
+
if (!dump_for_merp) {
#ifdef DISABLE_STRUCTURED_CRASH
leave = TRUE;
-#else
- mini_register_sigterm_handler ();
#endif
}
g_async_safe_printf("\nThe MERP upload step has succeeded.\n");
mono_summarize_timeline_phase_log (MonoSummaryDone);
}
-
mono_summarize_toggle_assertions (FALSE);
} else {
g_async_safe_printf("\nMerp dump step not run, no dump created.\n");
mono_dump_native_crash_info (const char *signal, MonoContext *mctx, MONO_SIG_HANDLER_INFO_TYPE *info)
{
dump_native_stacktrace (signal, mctx);
-
dump_memory_around_ip (mctx);
}
#include <mono/utils/checked-build.h>
#include <mono/utils/mono-compiler.h>
#include <mono/utils/mono-proclib.h>
+#include <mono/utils/mono-state.h>
#include <mono/metadata/w32handle.h>
#include <mono/metadata/threadpool.h>
goto exit;
mono_sigctx_to_monoctx (ctx, &mctx);
- mono_handle_native_crash ("SIGFPE", &mctx, info);
+ if (mono_dump_start ())
+ mono_handle_native_crash ("SIGFPE", &mctx, info);
if (mono_do_crash_chaining) {
mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
goto exit;
exit (1);
mono_sigctx_to_monoctx (ctx, &mctx);
- mono_handle_native_crash ("SIGILL", &mctx, info);
+ if (mono_dump_start ())
+ mono_handle_native_crash ("SIGILL", &mctx, info);
if (mono_do_crash_chaining) {
mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
return;
if (!mono_domain_get () || !jit_tls) {
if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
return;
- mono_handle_native_crash ("SIGSEGV", &mctx, info);
+ if (mono_dump_start())
+ mono_handle_native_crash ("SIGSEGV", &mctx, info);
if (mono_do_crash_chaining) {
mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
return;
mono_arch_handle_altstack_exception (ctx, info, info->si_addr, FALSE);
} else {
// FIXME: This shouldn't run on the altstack
- mono_handle_native_crash ("SIGSEGV", &mctx, info);
+ if (mono_dump_start ())
+ mono_handle_native_crash ("SIGSEGV", &mctx, info);
}
#endif
}
if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
return;
- mono_handle_native_crash ("SIGSEGV", &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info);
+ if (mono_dump_start ())
+ mono_handle_native_crash ("SIGSEGV", &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info);
if (mono_do_crash_chaining) {
mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
if (mono_is_addr_implicit_null_check (fault_addr)) {
mono_arch_handle_exception (ctx, NULL);
} else {
- mono_handle_native_crash ("SIGSEGV", &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info);
+ if (mono_dump_start ())
+ mono_handle_native_crash ("SIGSEGV", &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info);
}
#endif
}
* (C) 2018 Microsoft, Inc.
*
*/
-#ifndef DISABLE_CRASH_REPORTING
-
#include <config.h>
#include <glib.h>
#include <mono/utils/mono-state.h>
+#include <mono/utils/atomic.h>
+
+#ifndef DISABLE_CRASH_REPORTING
+
#include <mono/utils/mono-threads-coop.h>
#include <mono/metadata/object-internals.h>
#include <mono/metadata/mono-config-dirs.h>
}
#endif // DISABLE_CRASH_REPORTING
+
+static volatile int32_t dump_status;
+
+gboolean
+mono_dump_start (void)
+{
+ return (mono_atomic_xchg_i32(&dump_status, 1) == 0); // return true if we started the dump
+}
+
+gboolean
+mono_dump_complete (void)
+{
+ return (mono_atomic_xchg_i32(&dump_status, 0) == 1); // return true if we completed the dump
+}
mono_state_free_mem (MonoStateMem *mem);
#endif // DISABLE_CRASH_REPORTING
+
+// Dump context functions (enter/leave)
+
+gboolean
+mono_dump_start (void);
+gboolean
+mono_dump_complete (void);
+
#endif // MONO_UTILS_NATIVE_STATE
<ClInclude Include="$(MonoSourceLocation)\mono\utils\refcount.h" />
<ClInclude Include="$(MonoSourceLocation)\mono\utils\w32api.h" />
<ClInclude Include="$(MonoSourceLocation)\mono\utils\unlocked.h" />
+ <ClCompile Include="$(MonoSourceLocation)\mono\utils\mono-state.c" />
+ <ClInclude Include="$(MonoSourceLocation)\mono\utils\mono-state.h" />
</ItemGroup>
<ItemGroup Label="libmonoutilsinclude_headers">
<ClInclude Include="$(MonoSourceLocation)\mono\utils\mono-logger.h" />
<ClInclude Include="$(MonoSourceLocation)\mono\utils\unlocked.h">
<Filter>Header Files$(MonoUtilsFilterSubFolder)\common</Filter>
</ClInclude>
+ <ClCompile Include="$(MonoSourceLocation)\mono\utils\mono-state.c">
+ <Filter>Header Files$(MonoUtilsFilterSubFolder)\common</Filter>
+ </ClCompile>
+ <ClInclude Include="$(MonoSourceLocation)\mono\utils\mono-state.h">
+ <Filter>Header Files$(MonoUtilsFilterSubFolder)\common</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup Label="libmonoutilsinclude_headers">
<ClInclude Include="$(MonoSourceLocation)\mono\utils\mono-logger.h">