aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/bif.c
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2018-12-13 16:34:38 +0100
committerLukas Larsson <[email protected]>2018-12-13 17:08:55 +0100
commit27ff974bfa155ad31dcdc338d7fecf36b08a0516 (patch)
tree13c02aedb0e3f51a5663e820d356206d9efef465 /erts/emulator/beam/bif.c
parentbe749b4f83f3b3a2fa3bd8e5a3e5e28467b137b2 (diff)
downloadotp-27ff974bfa155ad31dcdc338d7fecf36b08a0516.tar.gz
otp-27ff974bfa155ad31dcdc338d7fecf36b08a0516.tar.bz2
otp-27ff974bfa155ad31dcdc338d7fecf36b08a0516.zip
erts: Fix seq_trace:reset_trace dirty gc bug
When seq_trace:reset_trace could be called while a process was doing a dirty GC. This triggered a race where all signals was moved to the internal signal queue during the GC which in turn caused the a heap overrun problem. This fix makes it so that the main and msgq lock are taken before the clear. This will make sure that we are allowed to do the clear.
Diffstat (limited to 'erts/emulator/beam/bif.c')
-rw-r--r--erts/emulator/beam/bif.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index f18af8bcd7..79ed5a0c18 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -4486,11 +4486,12 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
ERTS_TRACER_CLEAR(&old_seq_tracer);
BIF_RET(ret);
- } else if (BIF_ARG_1 == make_small(1)) {
+ } else if (BIF_ARG_1 == am_reset_seq_trace) {
int i, max;
- erts_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
- erts_thr_progress_block();
+ erts_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_thr_progress_block();
+
max = erts_ptab_max(&erts_proc);
for (i = 0; i < max; i++) {
Process *p = erts_pix2proc(i);
@@ -4502,13 +4503,14 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
#endif
p->seq_trace_clock = 0;
p->seq_trace_lastcnt = 0;
-
+ erts_proc_lock(p, ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_MSGQ);
erts_proc_sig_clear_seq_trace_tokens(p);
+ erts_proc_unlock(p, ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_MSGQ);
}
}
- erts_thr_progress_unblock();
- erts_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
+ erts_thr_progress_unblock();
+ erts_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
BIF_RET(am_true);
} else if (BIF_ARG_1 == am_scheduler_wall_time) {