From: Siraaj Khandkar Date: Tue, 22 Sep 2015 22:08:02 +0000 (-0400) Subject: fix: handling 'undefined' from erlang:process_info/2 X-Git-Tag: 0.8.2^0 X-Git-Url: https://git.xandkar.net/?a=commitdiff_plain;h=2cd7cf62e9b1e456c0ccc963d92a9170c3af8251;p=beam_stats.git fix: handling 'undefined' from erlang:process_info/2 Process could die between the time we get its PID from erlang:processes() and when we start calling erlang:process_info/2 on it; or even somewhere between the process_info calls. The choice is between returning partial info (that we were able to collect before process died) and just skipping the process. For now, I'm choosing to skip the process (throwing away any partial info collected). --- diff --git a/src/beam_stats.app.src b/src/beam_stats.app.src index 1597668..2dbb0cf 100644 --- a/src/beam_stats.app.src +++ b/src/beam_stats.app.src @@ -1,7 +1,7 @@ {application, beam_stats, [ {description, "Periodic VM stats production and consumption."}, - {vsn, "0.8.1"}, + {vsn, "0.8.2"}, {registered, []}, {applications, [ kernel diff --git a/src/beam_stats_process.erl b/src/beam_stats_process.erl index e2751ea..b0b7da4 100644 --- a/src/beam_stats_process.erl +++ b/src/beam_stats_process.erl @@ -43,25 +43,33 @@ %% ============================================================================ -spec of_pid(pid()) -> - t(). + none % when process is dead + | {some, t()} % when process is alive + . of_pid(Pid) -> - Dict = pid_info_exn(Pid, dictionary), - Ancestry = - #beam_stats_process_ancestry - { raw_initial_call = pid_info_exn(Pid, initial_call) - , otp_initial_call = hope_kv_list:get(Dict, '$initial_call') - , otp_ancestors = hope_kv_list:get(Dict, '$ancestors') - }, - ?T - { pid = Pid - , registered_name = pid_info_opt(Pid, registered_name) - , ancestry = Ancestry - , status = pid_info_exn(Pid, status) - , memory = pid_info_exn(Pid, memory) - , total_heap_size = pid_info_exn(Pid, total_heap_size) - , stack_size = pid_info_exn(Pid, stack_size) - , message_queue_len = pid_info_exn(Pid, message_queue_len) - }. + try + Dict = pid_info_exn(Pid, dictionary), + Ancestry = + #beam_stats_process_ancestry + { raw_initial_call = pid_info_exn(Pid, initial_call) + , otp_initial_call = hope_kv_list:get(Dict, '$initial_call') + , otp_ancestors = hope_kv_list:get(Dict, '$ancestors') + }, + T = + ?T + { pid = Pid + , registered_name = pid_info_opt(Pid, registered_name) + , ancestry = Ancestry + , status = pid_info_exn(Pid, status) + , memory = pid_info_exn(Pid, memory) + , total_heap_size = pid_info_exn(Pid, total_heap_size) + , stack_size = pid_info_exn(Pid, stack_size) + , message_queue_len = pid_info_exn(Pid, message_queue_len) + }, + {some, T} + catch throw:{process_dead, _} -> + none + end. -spec print(t()) -> ok. @@ -122,6 +130,7 @@ pid_info_opt(Pid, Key) -> case {Key, beam_stats_source:erlang_process_info(Pid, Key)} of {registered_name, []} -> none ; {_ , {Key, Value}} -> {some, Value} + ; {_ , undefined} -> throw({process_dead, Pid}) end. %% ============================================================================ diff --git a/src/beam_stats_processes.erl b/src/beam_stats_processes.erl index 90c3886..1b3fcb2 100644 --- a/src/beam_stats_processes.erl +++ b/src/beam_stats_processes.erl @@ -22,7 +22,8 @@ t(). collect() -> Pids = beam_stats_source:erlang_processes(), - Ps = [beam_stats_process:of_pid(P) || P <- Pids], + PsOpts = [beam_stats_process:of_pid(P) || P <- Pids], + Ps = [P || {some, P} <- PsOpts], ?T { individual_stats = Ps