Skip to content

Commit 79ebb2b

Browse files
author
Erlang/OTP
committed
Merge branch 'sverker/erts/call_memory-delay-gc-bug/OTP-19581' into maint-27
* sverker/erts/call_memory-delay-gc-bug/OTP-19581: kernel: Fix trace call_memory specs and docs erts: Fix `call_memory` tracing bug at delayed GC
2 parents 99979ac + 576b6e2 commit 79ebb2b

File tree

3 files changed

+62
-9
lines changed

3 files changed

+62
-9
lines changed

erts/emulator/beam/erl_gc.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -543,11 +543,6 @@ delay_garbage_collection(Process *p, int need, int fcalls)
543543

544544
p->hend = hend;
545545

546-
/* Keep the high water mark pointing into the current heap to ensure
547-
* that the test for the safe range in the update_record_in_place (JIT)
548-
* stays honest. */
549-
p->high_water = p->heap;
550-
551546
if (p->abandoned_heap) {
552547
/*
553548
* Active heap already in a fragment; adjust it and
@@ -577,6 +572,11 @@ delay_garbage_collection(Process *p, int need, int fcalls)
577572
erts_adjust_memory_break(p, orig_htop - p->high_water);
578573
}
579574

575+
/* Keep the high water mark pointing into the current heap to ensure
576+
* that the test for the safe range in the update_record_in_place (JIT)
577+
* stays honest. */
578+
p->high_water = p->heap;
579+
580580
#ifdef CHECK_FOR_HOLES
581581
p->last_htop = p->htop;
582582
p->heap_hfrag = hfrag;

erts/emulator/test/trace_call_memory_SUITE.erl

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
spawn_memory/0, spawn_memory/1, spawn_memory_internal/1,
4242
spawn_memory_lambda/1,
4343
conflict_traces/0, conflict_traces/1,
44-
big_words/0, big_words/1
44+
big_words/0, big_words/1, delayed_gc/1
4545
]).
4646

4747
suite() ->
@@ -55,7 +55,7 @@ groups() ->
5555

5656
testcases() ->
5757
[basic, on_load, late_trace, skip, message, parallel_map, trace_all, spawn_memory,
58-
spawn_memory_lambda, conflict_traces, big_words].
58+
spawn_memory_lambda, conflict_traces, big_words, delayed_gc].
5959

6060
init_per_suite(Config) ->
6161
trace_sessions:init_per_suite(Config, ?MODULE).
@@ -116,6 +116,10 @@ end_per_testcase(conflict_traces, Config) ->
116116
end_per_testcase(big_words, Config) ->
117117
erlang_trace_pattern({?MODULE,alloc_tuples,2}, false, [call_memory]),
118118
erlang_trace(self(), false, [call]),
119+
trace_sessions:end_per_testcase(Config);
120+
end_per_testcase(delayed_gc, Config) ->
121+
erlang_trace_pattern({?MODULE, build_on_heap, 1}, false, [call_memory]),
122+
erlang_trace(self(), false, [call]),
119123
trace_sessions:end_per_testcase(Config).
120124

121125

@@ -451,3 +455,47 @@ alloc_tuples(0, _) ->
451455
alloc_tuples(N, TupleSz) ->
452456
erlang:make_tuple(TupleSz, []),
453457
alloc_tuples(N-1, TupleSz).
458+
459+
460+
%% OTP-19581
461+
%% Verify that reported memory is correct after getting disabled GC with "need".
462+
delayed_gc(Config) when is_list(Config) ->
463+
AIS = erts_debug:set_internal_state(available_internal_state, true),
464+
try
465+
Self = self(),
466+
Traced = {?MODULE, build_on_heap, 1},
467+
1 = erlang_trace_pattern(Traced, true, [call_memory]),
468+
1 = erlang_trace(Self, true, [call]),
469+
470+
{heap_size, HeapSize} = process_info(self(), heap_size),
471+
[begin
472+
%% Disable GC and fill up heap to trigger GC with need != 0
473+
%% which will provoke the abandoned heap scenario.
474+
true = erts_debug:set_internal_state(gc_state, false),
475+
Term = build_on_heap(Words),
476+
false = erts_debug:set_internal_state(gc_state, true),
477+
478+
?assertEqual(Words, erts_debug:flat_size(Term)),
479+
?assertEqual({call_memory, [{Self, 1, Words}]},
480+
erlang_trace_info(Traced, call_memory)),
481+
1 = erlang_trace_pattern(Traced, restart, [call_memory])
482+
end
483+
|| Words <- lists:seq(HeapSize, HeapSize*10, HeapSize)],
484+
485+
1 = erlang_trace(Self, false, [call]),
486+
1 = erlang_trace_pattern(Traced, false, [call_memory])
487+
after
488+
erts_debug:set_internal_state(available_internal_state, AIS)
489+
end,
490+
ok.
491+
492+
493+
build_on_heap(Words) ->
494+
build_on_heap(Words, []).
495+
496+
build_on_heap(0, Acc) ->
497+
Acc;
498+
build_on_heap(3, Acc) ->
499+
{3, Acc};
500+
build_on_heap(Words, Acc) when Words > 1 ->
501+
build_on_heap(Words-2, [Words | Acc]).

lib/kernel/src/trace.erl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,10 @@ being destroyed when the last strong handle is garbage collected.
208208
{meta, module(), term() } |
209209
{meta_match_spec, trace_match_spec() | false | undefined} |
210210
{call_count, non_neg_integer() | boolean() | undefined} |
211-
{call_time | call_memory, [{pid(), non_neg_integer(),
212-
non_neg_integer(), non_neg_integer()}] | boolean() | undefined}.
211+
{call_time, [{pid(), non_neg_integer(), non_neg_integer(), non_neg_integer()}]
212+
| boolean() | undefined} |
213+
{call_memory, [{pid(), non_neg_integer(), non_neg_integer()}]
214+
| boolean() | undefined}.
213215

214216
-type trace_info_return() ::
215217
undefined |
@@ -870,6 +872,9 @@ Argument **`FlagList`** is a list of options. The following are the valid option
870872

871873
- **`call_memory`**{: #call_memory } - Start (`MatchSpec == true`) or stop
872874
(`MatchSpec == false`) call memory tracing for all types of function calls.
875+
For every function, a counter is incremented when the function is called and
876+
the memory consumed by the function is measured and accumulated in another
877+
counter. Separate counters are stored for each call traced process.
873878

874879
If call memory tracing is started while already running, counters and
875880
allocations restart from zero. To pause running counters, use

0 commit comments

Comments
 (0)