aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2016-08-22 14:33:29 +0200
committerLukas Larsson <[email protected]>2016-08-22 14:33:29 +0200
commit2c1897c6ca6d4bfa4e30ebfd64dcfa807a596a51 (patch)
tree28e0aa48ec24fcaaf0ec9a1a6ac35fa9d853cdec
parent80b98dcfbb72c191aec3cead4cfe4a35d5a80cd7 (diff)
parentf5a1c56f0ab2a276b5c2add54b8b0d6d276e1361 (diff)
downloadotp-2c1897c6ca6d4bfa4e30ebfd64dcfa807a596a51.tar.gz
otp-2c1897c6ca6d4bfa4e30ebfd64dcfa807a596a51.tar.bz2
otp-2c1897c6ca6d4bfa4e30ebfd64dcfa807a596a51.zip
Merge branch 'lukas/erts/port_monitor_mem_leak/OTP-13818' into maint
* lukas/erts/port_monitor_mem_leak/OTP-13818: erts: Fix port monitor memory leak
-rw-r--r--erts/emulator/beam/erl_process.c1
-rw-r--r--erts/emulator/test/port_SUITE.erl25
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,