diff options
author | Björn-Egil Dahlberg <[email protected]> | 2016-04-15 12:26:47 +0200 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2016-04-15 12:26:47 +0200 |
commit | 8d2ea920456c5db3f123ebc19b8b8e398db2e2d5 (patch) | |
tree | e269654e6506c4c3c1d0a53fb261ee30caf3ec8c /erts | |
parent | f3c2071cc0bbe776f1d301d4fc346c1d261c1533 (diff) | |
parent | 0fc3412387a889663f55515f123f1168e8f66be2 (diff) | |
download | otp-8d2ea920456c5db3f123ebc19b8b8e398db2e2d5.tar.gz otp-8d2ea920456c5db3f123ebc19b8b8e398db2e2d5.tar.bz2 otp-8d2ea920456c5db3f123ebc19b8b8e398db2e2d5.zip |
Merge branch 'egil/erts/fix-erlang-system_profile/ERL-126/OTP-13494'
* egil/erts/fix-erlang-system_profile/ERL-126/OTP-13494:
erts: Enhance system_profile tests
erts: Don't use function location when process is terminating
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/erl_trace.c | 16 | ||||
-rw-r--r-- | erts/emulator/test/system_profile_SUITE.erl | 32 |
2 files changed, 42 insertions, 6 deletions
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c index fb3f0d4e62..1654ea58d9 100644 --- a/erts/emulator/beam/erl_trace.c +++ b/erts/emulator/beam/erl_trace.c @@ -3020,6 +3020,7 @@ profile_runnable_proc(Process *p, Eterm status){ Eterm *hp, msg; Eterm where = am_undefined; ErlHeapFragment *bp = NULL; + int use_current = 1; #ifndef ERTS_SMP #define LOCAL_HEAP_SIZE (4 + 6 + ERTS_TRACE_PATCH_TS_MAX_SIZE) @@ -3032,12 +3033,19 @@ profile_runnable_proc(Process *p, Eterm status){ Uint hsz = 4 + 6 + patch_ts_size(erts_system_profile_ts_type)-1; #endif - if (!p->current) { - p->current = find_function_from_pc(p->i); + if (ERTS_PROC_IS_EXITING(p)) { + use_current = 0; + /* could probably set 'where' to 'exiting' here, + * though it's not documented as such */ + } else { + if (!p->current) { + p->current = find_function_from_pc(p->i); + } + use_current = p->current != NULL; } #ifdef ERTS_SMP - if (!p->current) { + if (!use_current) { hsz -= 4; } @@ -3045,7 +3053,7 @@ profile_runnable_proc(Process *p, Eterm status){ hp = bp->mem; #endif - if (p->current) { + if (use_current) { where = TUPLE3(hp, p->current[0], p->current[1], make_small(p->current[2])); hp += 4; } else { where = make_small(0); diff --git a/erts/emulator/test/system_profile_SUITE.erl b/erts/emulator/test/system_profile_SUITE.erl index a56b394765..2e359b11ce 100644 --- a/erts/emulator/test/system_profile_SUITE.erl +++ b/erts/emulator/test/system_profile_SUITE.erl @@ -27,7 +27,7 @@ system_profile_on_and_off/1, runnable_procs/1, runnable_ports/1, dont_profile_profiler/1, - scheduler/1]). + scheduler/1, sane_location/1]). -export([profiler_process/1, ring_loop/1, port_echo_start/0, list_load/0, run_load/2]). @@ -40,7 +40,8 @@ suite() -> all() -> [system_profile_on_and_off, runnable_procs, - runnable_ports, scheduler, dont_profile_profiler]. + runnable_ports, scheduler, dont_profile_profiler, + sane_location]. %% No specification clause needed for an init function in a conf case!!! @@ -183,6 +184,33 @@ dont_profile_profiler(Config) when is_list(Config) -> exit(Pid,kill), ok. +%% Check sane location (of exits) +sane_location(Config) when is_list(Config) -> + Check = spawn_link(fun() -> flush_sane_location() end), + erlang:system_profile(Check, [runnable_procs]), + Me = self(), + Pids = [spawn_link(fun() -> wat(Me) end) || _ <- lists:seq(1,100)], + [receive {Pid,ok} -> ok end || Pid <- Pids], + Check ! {Me, done}, + receive {Check,ok} -> ok end, + ok. + +wat(Pid) -> + Pid ! {self(), ok}. + +flush_sane_location() -> + receive + {profile,_,_,{M,F,A},_} when is_atom(M), is_atom(F), + is_integer(A) -> + flush_sane_location(); + {profile,_,_,0,_} -> + flush_sane_location(); + {Pid,done} when is_pid(Pid) -> + Pid ! {self(), ok}; + M -> + ct:fail({badness,M}) + end. + %%% Check scheduler profiling |