diff options
author | Lukas Larsson <[email protected]> | 2016-08-12 16:18:25 +0200 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2016-08-12 16:18:36 +0200 |
commit | f5a1c56f0ab2a276b5c2add54b8b0d6d276e1361 (patch) | |
tree | c06a5753c46fde851074d5c0d06a8f385281b802 | |
parent | a88ac9abceb661a8878b8e18379c5403c3e08074 (diff) | |
download | otp-f5a1c56f0ab2a276b5c2add54b8b0d6d276e1361.tar.gz otp-f5a1c56f0ab2a276b5c2add54b8b0d6d276e1361.tar.bz2 otp-f5a1c56f0ab2a276b5c2add54b8b0d6d276e1361.zip |
erts: Fix port monitor memory leak
-rw-r--r-- | erts/emulator/beam/erl_process.c | 1 | ||||
-rw-r--r-- | erts/emulator/test/port_SUITE.erl | 25 |
2 files changed, 25 insertions, 1 deletions
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index b5d8c5bc75..aa6af7427c 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -12276,7 +12276,6 @@ static void doit_exit_monitor(ErtsMonitor *mon, void *vpcontext) erts_port_demonitor(pcontext->p, ERTS_PORT_DEMONITOR_ORIGIN_ON_DEATHBED, prt, mon->ref, NULL); - return; /* let erts_port_demonitor do the deletion */ } else { /* remote by pid */ ASSERT(is_external_pid(mon->pid)); dep = external_pid_dist_entry(mon->pid); diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl index 5c0bfdffd4..a9814d7df9 100644 --- a/erts/emulator/test/port_SUITE.erl +++ b/erts/emulator/test/port_SUITE.erl @@ -104,6 +104,7 @@ mon_port_name_demonitor/1, mon_port_named/1, mon_port_origin_dies/1, + mon_port_owner_dies/1, mon_port_pid_demonitor/1, mon_port_remote_on_remote/1, mon_port_driver_die/1, @@ -173,6 +174,7 @@ all() -> mon_port_remote_on_remote, mon_port_bad_remote_on_local, mon_port_origin_dies, + mon_port_owner_dies, mon_port_named, mon_port_bad_named, mon_port_pid_demonitor, @@ -2637,6 +2639,29 @@ mon_port_origin_dies(Config) -> Port5 ! {self(), {command, <<"1">>}}, % make port quit ok. +%% Port and Monitor owner dies before port is closed +%% This testcase checks for a regression memory leak in erts +%% when the controlling and monitoring process is the same process +%% and the process dies +mon_port_owner_dies(Config) -> + Self = self(), + Proc = spawn(fun() -> + Port = create_port(Config, ["-h1", "-q"]), + Self ! {test_started, Port}, + erlang:monitor(port, Port), + receive stop -> ok end + end), + erlang:monitor(process, Proc), % we want to sync with its death + Port = receive {test_started,P} -> P + after 1000 -> ?assert(false) end, + ?assertMatch({proc_monitors, true, port_monitored_by, true}, + port_is_monitored(Proc, Port)), + Proc ! stop, + %% receive from monitor + receive ExitP5 -> ?assertMatch({'DOWN', _, process, Proc, _}, ExitP5) + after 1000 -> ?assert(false) end, + ok. + %% Monitor a named port mon_port_named(Config) -> Name6 = test_port6, |