aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2018-11-16 19:49:11 +0100
committerSverker Eriksson <[email protected]>2018-11-16 19:49:11 +0100
commit625a9838ee4e494d5c055986ceff66a32c38a05c (patch)
tree94afeb496ab45affa61d5fe514a5f6a36a59a136
parent5b6eff964a61b32c1d02464e8fc6ef0c79a4badc (diff)
downloadotp-625a9838ee4e494d5c055986ceff66a32c38a05c.tar.gz
otp-625a9838ee4e494d5c055986ceff66a32c38a05c.tar.bz2
otp-625a9838ee4e494d5c055986ceff66a32c38a05c.zip
erts: Fix offheap leak of ets catree tmp iteration key
Also fix erts_debug:get_internal_status(node_and_dist_references) for catree to also search route node keys for offheap stuff.
-rw-r--r--erts/emulator/beam/erl_db_catree.c24
-rw-r--r--lib/stdlib/test/Makefile8
-rw-r--r--lib/stdlib/test/ets_SUITE.erl18
3 files changed, 31 insertions, 19 deletions
diff --git a/erts/emulator/beam/erl_db_catree.c b/erts/emulator/beam/erl_db_catree.c
index 153a720f07..b642ae009d 100644
--- a/erts/emulator/beam/erl_db_catree.c
+++ b/erts/emulator/beam/erl_db_catree.c
@@ -811,11 +811,12 @@ void destroy_root_iterator(CATreeRootIterator* iter)
{
if (iter->locked_bnode)
unlock_iter_base_node(iter);
- if (iter->search_key)
+ if (iter->search_key) {
+ destroy_route_key(iter->search_key);
erts_free(ERTS_ALC_T_DB_TMP, iter->search_key);
+ }
}
-
typedef struct
{
DbTableCATreeNode *parent;
@@ -2069,6 +2070,23 @@ static SWord db_delete_all_objects_catree(Process* p, DbTable* tbl, SWord reds)
}
+static void do_for_route_nodes(DbTableCATreeNode* node,
+ void (*func)(ErlOffHeap *, void *),
+ void *arg)
+{
+ ErlOffHeap tmp_offheap;
+
+ if (!GET_LEFT(node)->is_base_node)
+ do_for_route_nodes(GET_LEFT(node), func, arg);
+
+ tmp_offheap.first = node->u.route.key.oh;
+ tmp_offheap.overhead = 0;
+ (*func)(&tmp_offheap, arg);
+
+ if (!GET_RIGHT(node)->is_base_node)
+ do_for_route_nodes(GET_RIGHT(node), func, arg);
+}
+
static void db_foreach_offheap_catree(DbTable *tbl,
void (*func)(ErlOffHeap *, void *),
void *arg)
@@ -2083,6 +2101,8 @@ static void db_foreach_offheap_catree(DbTable *tbl,
root = catree_find_next_root(&iter, NULL);
} while (root);
destroy_root_iterator(&iter);
+
+ do_for_route_nodes(GET_ROOT(&tbl->catree), func, arg);
}
static int db_lookup_dbterm_catree(Process *p, DbTable *tbl, Eterm key, Eterm obj,
diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile
index bbe3cefa42..712b1b92fb 100644
--- a/lib/stdlib/test/Makefile
+++ b/lib/stdlib/test/Makefile
@@ -99,11 +99,9 @@ MODULES= \
maps_SUITE \
zzz_SUITE
-ERL_FILES= $(MODULES:%=%.erl)
+ERTS_MODULES= erts_test_utils
-TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
-
-INSTALL_PROGS= $(TARGET_FILES)
+ERL_FILES= $(MODULES:%=%.erl) $(ERTS_MODULES:%=$(ERL_TOP)/erts/emulator/test/%.erl)
# ----------------------------------------------------
# Release directory specification
@@ -128,7 +126,7 @@ COVERFILE=stdlib.cover
# ----------------------------------------------------
make_emakefile:
- $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) $(ERTS_MODULES) \
> $(EMAKEFILE)
tests debug opt: make_emakefile
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index cc369979f7..501588ad44 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -6052,7 +6052,7 @@ smp_ordered_iteration(Config) when is_list(Config) ->
smp_ordered_iteration_do(Opts) ->
KeyRange = 1000,
- OffHeap = fun() -> dummy end, % To exercise key copy/destroy code.
+ OffHeap = erts_test_utils:mk_ext_pid({a@b,1}, 4711, 1),
KeyFun = fun(K, Type) ->
{K div 10, K rem 10, Type, OffHeap}
end,
@@ -6129,6 +6129,9 @@ smp_ordered_iteration_do(Opts) ->
io:format("Stats = ~p\n", [ets:info(T,stats)]),
io:format("Rounds = ~p\n", [Rounds]),
true = ets:delete(T),
+
+ %% Verify no leakage of offheap key data
+ ok = erts_test_utils:check_node_dist(),
ok.
incr_counter(Name, Counters) ->
@@ -7455,9 +7458,6 @@ is_redundant_opts_combo(Opts) ->
key_range(Opts, KeyRange) ->
[{key_range, KeyRange} | Opts].
-key_range_fun(Opts, KeyRange, KeyFun) ->
- [{key_range, KeyRange}, {key_fun, KeyFun} | Opts].
-
ets_new(Name, Opts0) ->
{KeyRange, Opts1} = case lists:keytake(key_range, 1, Opts0) of
{value, {key_range, KR}, Rest1} ->
@@ -7467,14 +7467,8 @@ ets_new(Name, Opts0) ->
end,
ets_new(Name, Opts1, KeyRange).
-ets_new(Name, Opts1, KeyRange) ->
- {KeyFun, Opts2} = case lists:keytake(key_fun, 1, Opts1) of
- {value, {key_fun, KF}, Rest2} ->
- {KF, Rest2};
- false ->
- {fun id/1, Opts1}
- end,
- ets_new(Name, Opts2, KeyRange, KeyFun).
+ets_new(Name, Opts, KeyRange) ->
+ ets_new(Name, Opts, KeyRange, fun id/1).
ets_new(Name, Opts0, KeyRange, KeyFun) ->
{CATree, Stimulate, RevOpts} =