erlang: exit-signal propagation + trap_exit (+11 tests)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

This commit is contained in:
2026-04-25 02:51:32 +00:00
parent c363856df6
commit 1a5a2e8982
6 changed files with 193 additions and 8 deletions

View File

@@ -502,6 +502,65 @@
(= (len (er-proc-field (er-mk-pid 1) :monitored-by)) 0)))
true)
;; ── exit-signal propagation + trap_exit ────────────────────────
(er-eval-test "process_flag default false"
(nm (ev "process_flag(trap_exit, true)")) "false")
(er-eval-test "process_flag returns prev"
(nm (ev "process_flag(trap_exit, true), process_flag(trap_exit, false)"))
"true")
;; Monitor fires on normal exit.
(er-eval-test "monitor DOWN normal"
(nm (ev "P = spawn(fun () -> ok end), monitor(process, P), receive {'DOWN', _, process, _, R} -> R end"))
"normal")
;; Monitor fires on abnormal exit.
(er-eval-test "monitor DOWN abnormal"
(nm (ev "P = spawn(fun () -> exit(boom) end), monitor(process, P), receive {'DOWN', _, process, _, R} -> R end"))
"boom")
;; Monitor's ref appears in DOWN message.
(er-eval-test "monitor DOWN ref matches"
(nm (ev "P = spawn(fun () -> exit(bye) end), Ref = monitor(process, P), receive {'DOWN', Ref, process, _, _} -> ok_match end"))
"ok_match")
;; Two monitors -> both fire.
(er-eval-test "two monitors both fire"
(ev "P = spawn(fun () -> exit(crash) end), monitor(process, P), monitor(process, P), receive {'DOWN', _, _, _, _} -> ok end, receive {'DOWN', _, _, _, _} -> 2 end")
2)
;; trap_exit + link + abnormal exit -> {'EXIT', From, Reason} message.
(er-eval-test "trap_exit catches abnormal"
(nm (ev "process_flag(trap_exit, true), P = spawn(fun () -> exit(boom) end), link(P), receive {'EXIT', _, R} -> R end"))
"boom")
;; trap_exit + link + normal exit -> {'EXIT', From, normal}.
(er-eval-test "trap_exit catches normal"
(nm (ev "process_flag(trap_exit, true), P = spawn(fun () -> ok end), link(P), receive {'EXIT', _, R} -> R end"))
"normal")
;; Cascade exit: A links B, B dies abnormally, A dies with same reason.
(er-eval-test "cascade reason"
(do
(ev "A = spawn(fun () -> B = spawn(fun () -> exit(crash) end), link(B), receive forever -> ok end end), receive after 0 -> ok end")
(nm (er-proc-field (er-mk-pid 1) :exit-reason)))
"crash")
;; Normal exit doesn't cascade (without trap_exit) — A's body returns
;; "survived" via the `after` clause and A dies normally.
(er-eval-test "normal exit no cascade"
(do
(ev "A = spawn(fun () -> B = spawn(fun () -> ok end), link(B), receive {'EXIT', _, _} -> got_exit after 50 -> survived end end), receive after 0 -> ok end")
(list
(nm (er-proc-field (er-mk-pid 1) :exit-reason))
(nm (er-proc-field (er-mk-pid 1) :exit-result))))
(list "normal" "survived"))
;; Monitor without trap_exit: monitored proc abnormal doesn't kill the monitor.
(er-eval-test "monitor doesn't cascade"
(nm (ev "P = spawn(fun () -> exit(boom) end), monitor(process, P), receive {'DOWN', _, _, _, _} -> alive end"))
"alive")
(define
er-eval-test-summary
(str "eval " er-eval-test-pass "/" er-eval-test-count))