aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/sys/unix/sys.c
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2014-12-04 11:09:06 +0100
committerLukas Larsson <[email protected]>2014-12-19 10:39:52 +0100
commitffd0153e6dffcc29cf79d0191860047dba0438bb (patch)
tree31a0ced512b5b243caa5933c73aa4dc70d6c0c87 /erts/emulator/sys/unix/sys.c
parente2a600341324d2ce3689119f8fd61b248702d79f (diff)
downloadotp-ffd0153e6dffcc29cf79d0191860047dba0438bb.tar.gz
otp-ffd0153e6dffcc29cf79d0191860047dba0438bb.tar.bz2
otp-ffd0153e6dffcc29cf79d0191860047dba0438bb.zip
erts: Improve crash dumps
This commit improves crash dumps in several ways: * Suspends schedulers to get a current snapshot * Dumps information about scheduler * Dumps stack trace of current running process (including Garbing processes)
Diffstat (limited to 'erts/emulator/sys/unix/sys.c')
-rw-r--r--erts/emulator/sys/unix/sys.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 74d67cbd57..57f9fbef53 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -223,6 +223,8 @@ static int sig_suspend_fds[2] = {-1, -1};
static int async_fd[2];
#endif
+jmp_buf erts_sys_sigsegv_jmp;
+
#if CHLDWTHR || defined(ERTS_SMP)
erts_mtx_t chld_stat_mtx;
#endif
@@ -683,6 +685,35 @@ void sys_sigrelease(int sig)
sigprocmask(SIG_UNBLOCK, &mask, (sigset_t *)NULL);
}
+void erts_sys_sigsegv_handler(int signo) {
+ if (signo == SIGSEGV) {
+ longjmp(erts_sys_sigsegv_jmp, 1);
+ }
+}
+
+/*
+ * Function returns 1 if we can read from all values in between
+ * start and stop.
+ */
+int
+erts_sys_is_area_readable(char *start, char *stop) {
+ int fds[2];
+ if (!pipe(fds)) {
+ /* We let write try to figure out if the pointers are readable */
+ int res = write(fds[1], start, (char*)stop - (char*)start);
+ if (res == -1) {
+ close(fds[0]);
+ close(fds[1]);
+ return 0;
+ }
+ close(fds[0]);
+ close(fds[1]);
+ return 1;
+ }
+ return 0;
+
+}
+
static ERTS_INLINE int
prepare_crash_dump(int secs)
{