diff options
Diffstat (limited to 'erts/etc')
-rw-r--r-- | erts/etc/common/erlexec.c | 1 | ||||
-rw-r--r-- | erts/etc/common/heart.c | 38 | ||||
-rw-r--r-- | erts/etc/unix/Makefile | 3 | ||||
-rw-r--r-- | erts/etc/unix/cerl.src | 29 | ||||
-rw-r--r-- | erts/etc/unix/etp-commands.in | 30 | ||||
-rw-r--r-- | erts/etc/unix/etp-rr-run-until-beam.py | 45 |
6 files changed, 125 insertions, 21 deletions
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index 0cb01fd4ef..23bbb86333 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -174,6 +174,7 @@ static char *plusz_val_switches[] = { "dbbl", "dntgc", "ebwt", + "tma", NULL }; diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c index bd218ff725..bb843a616b 100644 --- a/erts/etc/common/heart.c +++ b/erts/etc/common/heart.c @@ -500,7 +500,7 @@ message_loop(erlin_fd, erlout_fd) #if defined(__WIN32__) static void -kill_old_erlang(void){ +kill_old_erlang(int reason){ HANDLE erlh; DWORD exit_code; char* envvar = NULL; @@ -536,7 +536,8 @@ kill_old_erlang(void){ } #else static void -kill_old_erlang(void){ +kill_old_erlang(int reason) +{ pid_t pid; int i, res; int sig = SIGKILL; @@ -546,14 +547,25 @@ kill_old_erlang(void){ if (envvar && strcmp(envvar, "TRUE") == 0) return; - envvar = get_env(HEART_KILL_SIGNAL); - if (envvar && strcmp(envvar, "SIGABRT") == 0) { - print_error("kill signal SIGABRT requested"); - sig = SIGABRT; - } - if(heart_beat_kill_pid != 0){ - pid = (pid_t) heart_beat_kill_pid; + pid = (pid_t) heart_beat_kill_pid; + if (reason == R_CLOSED) { + print_error("Wait 5 seconds for Erlang to terminate nicely"); + for (i=0; i < 5; ++i) { + res = kill(pid, 0); /* check if alive */ + if (res < 0 && errno == ESRCH) + return; + sleep(1); + } + print_error("Erlang still alive, kill it"); + } + + envvar = get_env(HEART_KILL_SIGNAL); + if (envvar && strcmp(envvar, "SIGABRT") == 0) { + print_error("kill signal SIGABRT requested"); + sig = SIGABRT; + } + res = kill(pid,sig); for(i=0; i < 5 && res == 0; ++i){ sleep(1); @@ -677,7 +689,7 @@ do_terminate(int erlin_fd, int reason) { if(!command) print_error("Would reboot. Terminating."); else { - kill_old_erlang(); + kill_old_erlang(reason); /* High prio combined with system() works badly indeed... */ SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); win_system(command); @@ -685,7 +697,7 @@ do_terminate(int erlin_fd, int reason) { } free_env_val(command); } else { - kill_old_erlang(); + kill_old_erlang(reason); /* High prio combined with system() works badly indeed... */ SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); win_system(&cmd[0]); @@ -697,13 +709,13 @@ do_terminate(int erlin_fd, int reason) { if(!command) print_error("Would reboot. Terminating."); else { - kill_old_erlang(); + kill_old_erlang(reason); ret = system(command); print_error("Executed \"%s\" -> %d. Terminating.",command, ret); } free_env_val(command); } else { - kill_old_erlang(); + kill_old_erlang(reason); ret = system((char*)&cmd[0]); print_error("Executed \"%s\" -> %d. Terminating.",cmd, ret); } diff --git a/erts/etc/unix/Makefile b/erts/etc/unix/Makefile index 83c64d35fd..21a725cb88 100644 --- a/erts/etc/unix/Makefile +++ b/erts/etc/unix/Makefile @@ -30,7 +30,8 @@ opt debug lcnt: etc etc: etp-commands etp-commands: etp-commands.in - $(gen_verbose)sed 's:@ERL_TOP@:${ERL_TOP}:g' etp-commands.in > etp-commands + $(gen_verbose)sed -e 's:@ERL_TOP@:${ERL_TOP}:g' \ + etp-commands.in > etp-commands .PHONY: docs docs: diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src index 2e034513b0..bcd64d242e 100644 --- a/erts/etc/unix/cerl.src +++ b/erts/etc/unix/cerl.src @@ -224,7 +224,13 @@ while [ $# -gt 0 ]; do shift cargs="$cargs -rr" run_rr=yes - skip_erlexec=yes + case "$1" in + "replay"|"ps") + ;; + *) + skip_erlexec=yes + ;; + esac ;; *) break @@ -307,7 +313,26 @@ if [ "x$GDB" = "x" ]; then exec $taskset1 valgrind $valgrind_xml $valgrind_log $valgrind_misc_flags $BINDIR/$EMU_NAME $sched_arg $emu_xargs "$@" elif [ $run_rr = yes ]; then - exec rr record --ignore-nested $BINDIR/$EMU_NAME $emu_xargs "$@" + if [ $1 = replay ]; then + shift + cmdfile="/tmp/.cerlgdb.$$" + echo "set \$etp_beam_executable = \"$BINDIR/$EMU_NAME\"" > $cmdfile + if [ "$1" = "-p" ]; then + echo 'set $etp_rr_run_until_beam = 1' >> $cmdfile + fi + cat $ROOTDIR/erts/etc/unix/etp-commands.in >> $cmdfile + exec rr replay -x $cmdfile $* + elif [ $1 = ps ]; then + shift + rr ps $* | head -1 + ChildSetup=`rr ps $* | grep 'erl_child_setup' | awk '{ print $2 }'` + for CS in $ChildSetup; do + rr ps $* | grep -E "^$CS" + done + exit 0 + else + exec rr record --ignore-nested $BINDIR/$EMU_NAME $emu_xargs "$@" + fi else exec $EXEC $xargs ${1+"$@"} fi diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in index b12a205ba7..bb7b1a73f5 100644 --- a/erts/etc/unix/etp-commands.in +++ b/erts/etc/unix/etp-commands.in @@ -149,7 +149,7 @@ define etp-1 else # (($arg0) & 0x3) == 0 if (($arg0) == etp_the_non_value) - printf "<the non-value>" + printf "<the-non-value>" else etp-cp-1 ($arg0) end @@ -1241,7 +1241,7 @@ define etp-sig-int if $etp_sig_tag != etp_the_non_value etp-1 $etp_sig_tag 0 else - print "!ENCODED-DIST-MSG" + printf "!ENCODED-DIST-MSG" end if ($arg0)->m[1] != $etp_nil printf " @token= " @@ -1251,7 +1251,7 @@ define etp-sig-int etp-1 ($arg0)->m[2] 0 else if ($etp_sig_tag & 0x3f) != 0x30 - print "!INVALID-SIGNAL" + printf "!INVALID-SIGNAL" else set $etp_sig_op = (($etp_sig_tag >> 6) & 0xff) set $etp_sig_type = (($etp_sig_tag >> 14) & 0xff) @@ -4326,6 +4326,20 @@ document etp-show %--------------------------------------------------------------------------- end +define etp-rr-run-until-beam + source @ERL_TOP@/erts/etc/unix/etp-rr-run-until-beam.py +end + +document etp-rr-run-until-beam +%--------------------------------------------------------------------------- +% etp-rr-run-until-beam +% +% Use this gdb macro to make cerl -rr replay -p PID walk until +% the correct execute has been made. You may have to change the +% file that is used to debug with. +%--------------------------------------------------------------------------- +end + ############################################################################ # Init # @@ -4363,7 +4377,13 @@ define hook-run set $_exitsignal = -1 end +handle SIGPIPE nostop + etp-init help etp-init -etp-show -etp-system-info +if $etp_rr_run_until_beam + help etp-rr-run-until-beam +else + etp-show + etp-system-info +end diff --git a/erts/etc/unix/etp-rr-run-until-beam.py b/erts/etc/unix/etp-rr-run-until-beam.py new file mode 100644 index 0000000000..078998b910 --- /dev/null +++ b/erts/etc/unix/etp-rr-run-until-beam.py @@ -0,0 +1,45 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2013-2016. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# %CopyrightEnd% +# + +has_exited = False + +def stop_handler (event): + global has_exited + if isinstance(event, gdb.SignalEvent): + print("exit code: %s" % (event.stop_signal)) + has_exited = True + +gdb.events.stop.connect (stop_handler) + +gdb.execute('continue') + +while not has_exited: + r = gdb.execute('when', to_string=True) + m = re.match("[^0-9]*([0-9]+)", r) + if m: + event = int(m.group(1)); + gdb.execute('start ' + str(event + 1)); + gdb.execute('continue') + +gdb.events.stop.disconnect (stop_handler) + +gdb.execute('file ' + str(gdb.parse_and_eval("$etp_beam_executable"))) +gdb.execute('break main') +gdb.execute('reverse-continue') |