Skip to content

Commit

Permalink
[cdv] Allow registered name as owner of timer in crashdump
Browse files Browse the repository at this point in the history
crashdump_viewer would crash if the owner of a timer was specified as
the process' regisered name. This has been corrected.
  • Loading branch information
sirihansen committed May 27, 2014
1 parent 339b641 commit dbd2604
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 12 deletions.
7 changes: 5 additions & 2 deletions lib/observer/src/cdv_timer_cb.erl
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,21 @@

%% Defines
-define(COL_OWNER, 0).
-define(COL_MSG, ?COL_OWNER+1).
-define(COL_NAME, ?COL_OWNER+1).
-define(COL_MSG, ?COL_NAME+1).
-define(COL_TIME, ?COL_MSG+1).

%% Callbacks for cdv_virtual_list_wx
col_to_elem(id) -> col_to_elem(?COL_OWNER);
col_to_elem(?COL_OWNER) -> #timer.pid;
col_to_elem(?COL_NAME) -> #timer.name;
col_to_elem(?COL_MSG) -> #timer.msg;
col_to_elem(?COL_TIME) -> #timer.time.

col_spec() ->
[{"Owner", ?wxLIST_FORMAT_LEFT, 110},
{"Message", ?wxLIST_FORMAT_LEFT, 400},
{"Owner name", ?wxLIST_FORMAT_LEFT, 150},
{"Message", ?wxLIST_FORMAT_LEFT, 300},
{"Time left (ms)", ?wxLIST_FORMAT_RIGHT, 80}].

get_info(Owner) ->
Expand Down
11 changes: 8 additions & 3 deletions lib/observer/src/cdv_virtual_list_wx.erl
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ handle_event(#wx{event=#wxList{type=command_list_item_right_click,
MenuId = ?ID_DETAILS + Col,
ColText = call(Holder, {get_row, self(), Row, Col}),
case ColText of
"[]" -> [];
Empty when Empty=="[]"; Empty=="" -> [];
_ ->
What =
case catch list_to_integer(ColText) of
Expand All @@ -284,8 +284,13 @@ handle_event(#wx{event=#wxList{type=command_list_item_right_click,
end
end,
MenuCols),
wxWindow:popupMenu(Panel, Menu),
wxMenu:destroy(Menu),
case MenuItems of
[] ->
wxMenu:destroy(Menu);
_ ->
wxWindow:popupMenu(Panel, Menu),
wxMenu:destroy(Menu)
end,
{noreply,State#state{menu_items=MenuItems}};

handle_event(#wx{event=#wxList{type=command_list_col_click, col=Col}},
Expand Down
40 changes: 36 additions & 4 deletions lib/observer/src/crashdump_viewer.erl
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ expand_binary(Pos) ->
%%--------------------------------------------------------------------
init([]) ->
ets:new(cdv_dump_index_table,[ordered_set,named_table,public]),
ets:new(cdv_reg_proc_table,[ordered_set,named_table,public]),
{ok, #state{}}.

%%--------------------------------------------------------------------
Expand Down Expand Up @@ -978,9 +979,20 @@ count() ->
%%-----------------------------------------------------------------
%% Page with all processes
procs_summary(File,WS) ->
ParseFun = fun(Fd,Pid) ->
ParseFun = fun(Fd,Pid0) ->
Pid = list_to_pid(Pid0),
Proc = get_procinfo(Fd,fun main_procinfo/5,
#proc{pid=list_to_pid(Pid)},WS),
#proc{pid=Pid},WS),
case Proc#proc.name of
undefined ->
true;
Name ->
%% Registered process - store to allow
%% lookup for timers connected to
%% registered name instead of pid.
ets:insert(cdv_reg_proc_table,{Name,Pid}),
ets:insert(cdv_reg_proc_table,{Pid0,Name})
end,
case Proc#proc.memory of
undefined -> Proc#proc{memory=Proc#proc.stack_heap};
_ -> Proc
Expand Down Expand Up @@ -1495,8 +1507,28 @@ get_internal_ets_tables(File,WS) ->
%%-----------------------------------------------------------------
%% Page with list of all timers
get_timers(File,Pid) ->
ParseFun = fun(Fd,Id) -> get_timerinfo_1(Fd,#timer{pid=list_to_pid(Id)}) end,
lookup_and_parse_index(File,{?timer,Pid},ParseFun,"timers").
ParseFun = fun(Fd,Id) -> get_timerinfo(Fd,Id) end,
T1 = lookup_and_parse_index(File,{?timer,Pid},ParseFun,"timers"),
T2 = case ets:lookup(cdv_reg_proc_table,Pid) of
[{_,Name}] ->
lookup_and_parse_index(File,{?timer,Name},ParseFun,"timers");
_ ->
[]
end,
T1 ++ T2.

get_timerinfo(Fd,Id) ->
case catch list_to_pid(Id) of
Pid when is_pid(Pid) ->
get_timerinfo_1(Fd,#timer{pid=Pid});
_ ->
case ets:lookup(cdv_reg_proc_table,Id) of
[{_,Pid}] when is_pid(Pid) ->
get_timerinfo_1(Fd,#timer{pid=Pid,name=Id});
[] ->
get_timerinfo_1(Fd,#timer{name=Id})
end
end.

get_timerinfo_1(Fd,Timer) ->
case line_head(Fd) of
Expand Down
1 change: 1 addition & 0 deletions lib/observer/src/crashdump_viewer.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@

-record(timer,
{pid,
name,
msg,
time}).

Expand Down
4 changes: 3 additions & 1 deletion lib/observer/test/crashdump_helper.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ n1_proc(Creator,_N2,Pid2,Port2,_L) ->
register(aaaaaaaa,self()),
process_flag(save_calls,3),
ets:new(cdv_test_ordset_table,[ordered_set]),
erlang:send_after(1000000,self(),cdv_test_timer_message),
erlang:send_after(1000000,self(),cdv_test_timer_message1),
erlang:send_after(1000000,aaaaaaaa,cdv_test_timer_message2),
erlang:send_after(1000000,noexistproc,cdv_test_timer_message3),
Port = hd(erlang:ports()),
Fun = fun() -> ok end,
Ref = make_ref(),
Expand Down
10 changes: 8 additions & 2 deletions lib/observer/test/crashdump_viewer_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,14 @@ special(File,Procs) ->

{ok,[_Ets=#ets_table{}],[]} = crashdump_viewer:ets_tables(Pid),
io:format(" ets tables ok",[]),
{ok,[_Timer=#timer{}],[]} = crashdump_viewer:timers(Pid),
io:format(" timers ok",[]),

{ok,[#timer{pid=Pid0,name=undefined},
#timer{pid=Pid0,name="aaaaaaaa"}],[]} =
crashdump_viewer:timers(Pid),
{ok,AllTimers,_TimersTW} = crashdump_viewer:timers(all),
#timer{name="noexistproc"} =
lists:keyfind(undefined,#timer.pid,AllTimers),
io:format(" timers ok:",[]),

{ok,Mod1=#loaded_mod{},[]} =
crashdump_viewer:loaded_mod_details(atom_to_list(?helper_mod)),
Expand Down

0 comments on commit dbd2604

Please sign in to comment.