fix: handling 'undefined' from erlang:process_info/2 0.8.2
authorSiraaj Khandkar <siraaj@khandkar.net>
Tue, 22 Sep 2015 22:08:02 +0000 (18:08 -0400)
committerSiraaj Khandkar <siraaj@khandkar.net>
Tue, 22 Sep 2015 22:08:02 +0000 (18:08 -0400)
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).

src/beam_stats.app.src
src/beam_stats_process.erl
src/beam_stats_processes.erl

index 1597668..2dbb0cf 100644 (file)
@@ -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
index e2751ea..b0b7da4 100644 (file)
 %% ============================================================================
 
 -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.
 
 %% ============================================================================
index 90c3886..1b3fcb2 100644 (file)
@@ -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
This page took 0.023711 seconds and 4 git commands to generate.