diff options
Diffstat (limited to 'lib/observer')
-rw-r--r-- | lib/observer/src/cdv_timer_cb.erl | 7 | ||||
-rw-r--r-- | lib/observer/src/cdv_virtual_list_wx.erl | 11 | ||||
-rw-r--r-- | lib/observer/src/crashdump_viewer.erl | 40 | ||||
-rw-r--r-- | lib/observer/src/crashdump_viewer.hrl | 1 | ||||
-rw-r--r-- | lib/observer/src/observer_tv_table.erl | 4 | ||||
-rw-r--r-- | lib/observer/src/observer_wx.erl | 4 | ||||
-rw-r--r-- | lib/observer/test/crashdump_helper.erl | 4 | ||||
-rw-r--r-- | lib/observer/test/crashdump_viewer_SUITE.erl | 10 | ||||
-rw-r--r-- | lib/observer/test/observer_SUITE.erl | 40 |
9 files changed, 94 insertions, 27 deletions
diff --git a/lib/observer/src/cdv_timer_cb.erl b/lib/observer/src/cdv_timer_cb.erl index 9cdbfa05a9..d44592cf18 100644 --- a/lib/observer/src/cdv_timer_cb.erl +++ b/lib/observer/src/cdv_timer_cb.erl @@ -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) -> diff --git a/lib/observer/src/cdv_virtual_list_wx.erl b/lib/observer/src/cdv_virtual_list_wx.erl index c5a7d9a2e5..bfe115a42e 100644 --- a/lib/observer/src/cdv_virtual_list_wx.erl +++ b/lib/observer/src/cdv_virtual_list_wx.erl @@ -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 @@ -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}}, diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl index a08d27d070..99329b94e2 100644 --- a/lib/observer/src/crashdump_viewer.erl +++ b/lib/observer/src/crashdump_viewer.erl @@ -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{}}. %%-------------------------------------------------------------------- @@ -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 @@ -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 diff --git a/lib/observer/src/crashdump_viewer.hrl b/lib/observer/src/crashdump_viewer.hrl index ae288ed573..0e2eba6dee 100644 --- a/lib/observer/src/crashdump_viewer.hrl +++ b/lib/observer/src/crashdump_viewer.hrl @@ -108,6 +108,7 @@ -record(timer, {pid, + name, msg, time}). diff --git a/lib/observer/src/observer_tv_table.erl b/lib/observer/src/observer_tv_table.erl index 59fe5b5670..7757dfea53 100644 --- a/lib/observer/src/observer_tv_table.erl +++ b/lib/observer/src/observer_tv_table.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -409,7 +409,7 @@ handle_info({refresh, Min, Min}, State = #state{grid=Grid}) -> wxListCtrl:refreshItem(Grid, Min), %% Avoid assert in wx below if Max is 0 {noreply, State}; handle_info({refresh, Min, Max}, State = #state{grid=Grid}) -> - wxListCtrl:refreshItems(Grid, Min, Max), + Max > 0 andalso wxListCtrl:refreshItems(Grid, Min, Max), {noreply, State}; handle_info(refresh_interval, State = #state{pid=Pid}) -> diff --git a/lib/observer/src/observer_wx.erl b/lib/observer/src/observer_wx.erl index ced26f7119..03ca1bf9c1 100644 --- a/lib/observer/src/observer_wx.erl +++ b/lib/observer/src/observer_wx.erl @@ -112,7 +112,8 @@ setup(#state{frame = Frame} = State) -> observer_lib:create_menus(DefMenus, MenuBar, default), wxFrame:setMenuBar(Frame, MenuBar), - StatusBar = wxFrame:createStatusBar(Frame, []), + StatusBar = wxStatusBar:new(Frame), + wxFrame:setStatusBar(Frame, StatusBar), wxFrame:setTitle(Frame, atom_to_list(node())), wxStatusBar:setStatusText(StatusBar, atom_to_list(node())), @@ -388,6 +389,7 @@ handle_info(_Info, State) -> terminate(_Reason, #state{frame = Frame}) -> wxFrame:destroy(Frame), + wx:destroy(), ok. code_change(_, _, State) -> diff --git a/lib/observer/test/crashdump_helper.erl b/lib/observer/test/crashdump_helper.erl index 40dbe28d46..0eb4a92c53 100644 --- a/lib/observer/test/crashdump_helper.erl +++ b/lib/observer/test/crashdump_helper.erl @@ -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(), diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl index e9567c82cb..03ab0c20e1 100644 --- a/lib/observer/test/crashdump_viewer_SUITE.erl +++ b/lib/observer/test/crashdump_viewer_SUITE.erl @@ -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)), diff --git a/lib/observer/test/observer_SUITE.erl b/lib/observer/test/observer_SUITE.erl index af07165456..5cf719acb1 100644 --- a/lib/observer/test/observer_SUITE.erl +++ b/lib/observer/test/observer_SUITE.erl @@ -45,7 +45,7 @@ all() -> groups() -> [{gui, [], [basic - %% , process_win, table_win + , process_win, table_win ] }]. @@ -107,6 +107,10 @@ appup_file(Config) when is_list(Config) -> basic(suite) -> []; basic(doc) -> [""]; basic(Config) when is_list(Config) -> + timer:send_after(100, "foobar"), %% Otherwise the timer sever gets added to procs + ProcsBefore = processes(), + NumProcsBefore = length(ProcsBefore), + ok = observer:start(), Notebook = setup_whitebox_testing(), @@ -116,11 +120,11 @@ basic(Config) when is_list(Config) -> 0 = wxNotebook:getSelection(Notebook), timer:sleep(500), Check = fun(N, TestMore) -> - ok = wxNotebook:advanceSelection(Notebook), TestMore andalso test_page(wxNotebook:getPageText(Notebook, N), wxNotebook:getCurrentPage(Notebook)), - timer:sleep(200) + timer:sleep(200), + ok = wxNotebook:advanceSelection(Notebook) end, %% Just verify that we can toogle trough all pages [_|_] = [Check(N, false) || N <- lists:seq(1, Count)], @@ -128,9 +132,22 @@ basic(Config) when is_list(Config) -> Frame = get_top_level_parent(Notebook), {W,H} = wxWindow:getSize(Frame), wxWindow:setSize(Frame, W+10, H+10), - [_|_] = [Check(N, true) || N <- lists:seq(1, Count)], - - ok = observer:stop(). + [_|_] = [Check(N, true) || N <- lists:seq(0, Count-1)], + + ok = observer:stop(), + timer:sleep(2000), %% stop is async + ProcsAfter = processes(), + NumProcsAfter = length(ProcsAfter), + if NumProcsAfter=/=NumProcsBefore -> + ct:log("Before but not after:~n~p~n", + [[{P,process_info(P)} || P <- ProcsBefore -- ProcsAfter]]), + ct:log("After but not before:~n~p~n", + [[{P,process_info(P)} || P <- ProcsAfter -- ProcsBefore]]), + ct:fail("leaking processes"); + true -> + ok + end, + ok. test_page("Load Charts" ++ _, _Window) -> %% Just let it display some info and hopefully it doesn't crash @@ -163,8 +180,11 @@ test_page("Processes" ++ _, _Window) -> timer:sleep(1000), %% Give it time to refresh ok; -test_page("Table" ++ _, _Window) -> +test_page(_Title = "Table" ++ _, _Window) -> Tables = [ets:new(list_to_atom("Test-" ++ [C]), [public]) || C <- lists:seq($A, $Z)], + Table = lists:nth(3, Tables), + ets:insert(Table, [{N,100-N} || N <- lists:seq(1,100)]), + Active = get_active(), Active ! refresh_interval, ChangeSort = fun(N) -> @@ -174,8 +194,6 @@ test_page("Table" ++ _, _Window) -> end, [ChangeSort(N) || N <- lists:seq(1,5) ++ [0]], timer:sleep(1000), - Table = lists:nth(3, Tables), - ets:insert(Table, [{N,100-N} || N <- lists:seq(1,100)]), Focus = #wx{event=#wxList{type=command_list_item_selected, itemIndex=2}}, Active ! Focus, Activate = #wx{event=#wxList{type=command_list_item_activated, itemIndex=2}}, @@ -226,14 +244,12 @@ table_win(Config) when is_list(Config) -> %% Modal can not test edit.. %% TPid = wx_object:get_pid(TObj), %% TPid ! #wx{event=#wxList{type=command_list_item_activated, itemIndex=12}}, - timer:sleep(2000), + timer:sleep(3000), wx_object:get_pid(TObj) ! #wx{event=#wxClose{type=close_window}}, observer:stop(), ok. - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% get_top_level_parent(Window) -> |