Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorAlexis Christoforides <alexis@thenull.net>2019-08-09 10:31:57 +0300
committerGitHub <noreply@github.com>2019-08-09 10:31:57 +0300
commit2c4b60fe24bfbccb3fa1553aed1065ce072343e1 (patch)
tree4bb49c6a8dc60edb3cb2ee8ac1b01ca774e2df7f /tools
parent6a459c25d771dec436bb6a8785c683f6b15fe6f7 (diff)
[merp] Use a separate program as the hang supervisor. (#15715)
* [merp] Use a separate program as the hang supervisor. Fixes https://github.com/mono/mono/issues/15646 macOS does not like signals being sent from the forked supervisor process, possibly towards anywhere but definitely when sent to the parent process. The following message is currently spewed after the supervisor process attempting to send a SIGSEGV to a hanged Mono process: "The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec()." We follow that direction and introduce a new binary that, when available in the mono executable's binary directory, is used to abort the parent process for us.
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile.am2
-rw-r--r--tools/mono-hang-watchdog/Makefile.am12
-rw-r--r--tools/mono-hang-watchdog/mono-hang-watchdog.c51
3 files changed, 64 insertions, 1 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 7a810890200..831f7548310 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = locale-builder sgen pedump
+SUBDIRS = locale-builder sgen pedump mono-hang-watchdog
diff --git a/tools/mono-hang-watchdog/Makefile.am b/tools/mono-hang-watchdog/Makefile.am
new file mode 100644
index 00000000000..596c7cd63e4
--- /dev/null
+++ b/tools/mono-hang-watchdog/Makefile.am
@@ -0,0 +1,12 @@
+
+AM_CPPFLAGS = $(SHARED_CFLAGS)
+
+if DISABLE_EXECUTABLES
+bin_PROGRAMS =
+else
+bin_PROGRAMS = mono-hang-watchdog
+endif
+
+CFLAGS = $(filter-out @CXX_REMOVE_CFLAGS@, @CFLAGS@)
+
+mono_hang_watchdog_SOURCES = mono-hang-watchdog.c
diff --git a/tools/mono-hang-watchdog/mono-hang-watchdog.c b/tools/mono-hang-watchdog/mono-hang-watchdog.c
new file mode 100644
index 00000000000..d703d8c2f96
--- /dev/null
+++ b/tools/mono-hang-watchdog/mono-hang-watchdog.c
@@ -0,0 +1,51 @@
+/* Given a external process' id as argument, the program waits for a set timeout then attempts to abort that process */
+/* Used by the Mono runtime's crash reporting. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "config.h"
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#define TIMEOUT 30
+
+static char* program_name;
+void program_exit (int exit_code, const char* message);
+
+int main (int argc, char* argv[])
+{
+ program_name = argv [0];
+ if (argc != 2)
+ program_exit (1, "Please provide one argument (pid)");
+ errno = 0;
+ pid_t pid = (pid_t)strtoul (argv [1], NULL, 10);
+ if (errno)
+ program_exit (2, "Invalid pid");
+
+ sleep (TIMEOUT);
+
+ /* if we survived the timeout, we consider the Mono process as hung */
+
+#ifndef HAVE_KILL
+ /* just inform the user */
+ printf ("Mono process with pid %llu appears to be hung", (uint64_t)pid);
+ return 0;
+#else
+ printf ("Mono process hang detected, sending kill signal to pid %llu\n", (uint64_t)pid);
+ return kill (pid, SIGKILL);
+#endif
+}
+
+void program_exit (int exit_code, const char* message)
+{
+ if (message)
+ printf ("%s\n", message);
+ printf ("Usage: '%s [pid]'\t\t[pid]: The id for the Mono process\n", program_name);
+ exit (exit_code);
+}