diff --git a/apps/emqx/src/emqx_sys_mon.erl b/apps/emqx/src/emqx_sys_mon.erl index cdc4677f3..35c8035f0 100644 --- a/apps/emqx/src/emqx_sys_mon.erl +++ b/apps/emqx/src/emqx_sys_mon.erl @@ -187,11 +187,20 @@ suppress(Key, SuccFun, State = #{events := Events}) -> procinfo(Pid) -> [{pid, Pid} | procinfo_l(emqx_vm:get_process_gc_info(Pid))] ++ + get_proc_lib_initial_call(Pid) ++ procinfo_l(emqx_vm:get_process_info(Pid)). procinfo_l(undefined) -> []; procinfo_l(List) -> List. +get_proc_lib_initial_call(Pid) -> + case proc_lib:initial_call(Pid) of + false -> + []; + InitialCall -> + [{proc_lib_initial_call, InitialCall}] + end. + portinfo(Port) -> [{port, Port} | erlang:port_info(Port)]. diff --git a/apps/emqx/src/emqx_vm.erl b/apps/emqx/src/emqx_vm.erl index 2c19df1ea..06e17513b 100644 --- a/apps/emqx/src/emqx_vm.erl +++ b/apps/emqx/src/emqx_vm.erl @@ -61,7 +61,7 @@ ]). -define(PROCESS_INFO_KEYS, [initial_call, - current_function, + current_stacktrace, registered_name, status, message_queue_len, diff --git a/apps/emqx/test/emqx_sys_mon_SUITE.erl b/apps/emqx/test/emqx_sys_mon_SUITE.erl index 1997312c7..b62aa16ef 100644 --- a/apps/emqx/test/emqx_sys_mon_SUITE.erl +++ b/apps/emqx/test/emqx_sys_mon_SUITE.erl @@ -71,23 +71,42 @@ init_per_testcase(t_sys_mon2, Config) -> (_) -> ok end), Config; +init_per_testcase(t_procinfo, Config) -> + emqx_common_test_helpers:boot_modules(all), + emqx_common_test_helpers:start_apps([]), + ok = meck:new(emqx_vm, [passthrough, no_history]), + Config; init_per_testcase(_, Config) -> emqx_common_test_helpers:boot_modules(all), emqx_common_test_helpers:start_apps([]), Config. +end_per_testcase(t_procinfo, _Config) -> + ok = meck:unload(emqx_vm), + emqx_common_test_helpers:stop_apps([]); end_per_testcase(_, _Config) -> emqx_common_test_helpers:stop_apps([]). t_procinfo(_) -> - ok = meck:new(emqx_vm, [passthrough, no_history]), - ok = meck:expect(emqx_vm, get_process_info, fun(_) -> [] end), - ok = meck:expect(emqx_vm, get_process_gc_info, fun(_) -> [] end), - ?assertEqual([{pid, undefined}], emqx_sys_mon:procinfo(undefined)), ok = meck:expect(emqx_vm, get_process_info, fun(_) -> [] end), ok = meck:expect(emqx_vm, get_process_gc_info, fun(_) -> undefined end), - ?assertEqual([{pid, self()}], emqx_sys_mon:procinfo(self())), - ok = meck:unload(emqx_vm). + ?assertEqual([{pid, self()}], emqx_sys_mon:procinfo(self())). + +t_procinfo_initial_call_and_stacktrace(_) -> + SomePid = proc_lib:spawn(?MODULE, some_function, [arg1, arg2]), + ProcInfo = emqx_sys_mon:procinfo(SomePid), + ?assertEqual( + {?MODULE, some_function, ['Argument__1','Argument__2']}, + proplists:get_value(proc_lib_initial_call, ProcInfo)), + ?assertMatch( + [{?MODULE, some_function, 2, + [{file, _}, + {line, _}]}, + {proc_lib, init_p_do_apply, 3, + [{file, _}, + {line, _}]}], + proplists:get_value(current_stacktrace, ProcInfo)), + SomePid ! stop. t_sys_mon(_Config) -> lists:foreach( @@ -119,3 +138,9 @@ validate_sys_mon_info(PidOrPort, SysMonName, ValidateInfo, InfoOrPort) -> emqtt:stop(C). fmt(Fmt, Args) -> lists:flatten(io_lib:format(Fmt, Args)). + +some_function(_Arg1, _Arg2) -> + receive + stop -> + ok + end.