1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2013-2018. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19-module(cdv_proc_cb). 20 21-export([col_to_elem/1, 22 col_spec/0, 23 get_info/1, 24 get_detail_cols/1, 25 get_details/2, 26 detail_pages/0]). 27 28-include_lib("wx/include/wx.hrl"). 29-include("crashdump_viewer.hrl"). 30 31%% Columns 32-define(COL_ID, 0). 33-define(COL_NAME, ?COL_ID+1). 34-define(COL_STATE,?COL_NAME+1). 35-define(COL_REDS, ?COL_STATE+1). 36-define(COL_MEM, ?COL_REDS+1). 37-define(COL_MSG, ?COL_MEM+1). 38 39%% Callbacks for cdv_virtual_list_wx 40col_to_elem(id) -> col_to_elem(?COL_ID); 41col_to_elem(?COL_ID) -> #proc.pid; 42col_to_elem(?COL_NAME) -> #proc.name; 43col_to_elem(?COL_STATE) -> #proc.state; 44col_to_elem(?COL_MEM) -> #proc.memory; 45col_to_elem(?COL_REDS) -> #proc.reds; 46col_to_elem(?COL_MSG) -> #proc.msg_q_len. 47 48col_spec() -> 49 [{"Pid", ?wxLIST_FORMAT_CENTRE, 120}, 50 {"Name or Initial Func", ?wxLIST_FORMAT_LEFT, 250}, 51 {"State", ?wxLIST_FORMAT_LEFT, 100}, 52 {"Reds", ?wxLIST_FORMAT_RIGHT, 80}, 53 {"Memory", ?wxLIST_FORMAT_RIGHT, 80}, 54 {"MsgQ", ?wxLIST_FORMAT_RIGHT, 50}]. 55 56get_info(_) -> 57 {ok,Info,TW} = crashdump_viewer:processes(), 58 {Info,TW}. 59 60get_detail_cols(_) -> 61 {[{process, ?COL_ID}],true}. 62 63%% Callbacks for cdv_detail_wx 64get_details(Id, _) -> 65 case crashdump_viewer:proc_details(Id) of 66 {ok,Info,TW} -> 67 %% The following table is used by observer_html_lib 68 %% for storing expanded terms and it is read by 69 %% cdv_html_wx when a link to an expandable term is clicked. 70 Tab = ets:new(cdv_expand,[set,public]), 71 Proplist0 = 72 crashdump_viewer:to_proplist(record_info(fields,proc),Info), 73 Proplist = [{expand_table,Tab}|Proplist0], 74 Title = io_lib:format("~ts (~s)",[Info#proc.name, Id]), 75 {ok,{Title,Proplist,TW}}; 76 {error,{other_node,NodeId}} -> 77 Info = "The process you are searching for was residing on " 78 "a remote node. No process information is available. " 79 "Show information about the remote node?", 80 Fun = fun() -> cdv_virtual_list_wx:start_detail_win(NodeId, port) end, 81 {yes_no, Info, Fun}; 82 {error,not_found} -> 83 Info = "The process you are searching for could not be found.", 84 {info,Info} 85 end. 86 87detail_pages() -> 88 [{"General Information", fun init_gen_page/2}, 89 {"Messages", fun init_message_page/2}, 90 {"Dictionary", fun init_dict_page/2}, 91 {"Stack Dump", fun init_stack_page/2}, 92 {"ETS tables", fun init_ets_page/2}, 93 {"Timers", fun init_timer_page/2}]. 94 95init_gen_page(Parent, Info) -> 96 Fields = info_fields(), 97 cdv_info_wx:start_link(Parent,{Fields,Info,[]}). 98 99init_message_page(Parent, Info) -> 100 init_memory_page(Parent, Info, msg_q, "MsgQueue"). 101 102init_dict_page(Parent, Info) -> 103 init_memory_page(Parent, Info, dict, "Dictionary"). 104 105init_stack_page(Parent, Info) -> 106 init_memory_page(Parent, Info, stack_dump, "StackDump"). 107 108init_memory_page(Parent, Info0, Tag, Heading) -> 109 Info = proplists:get_value(Tag,Info0), 110 Tab = proplists:get_value(expand_table,Info0), 111 Html = observer_html_lib:expandable_term(Heading,Info,Tab, observer_lib:colors(Parent)), 112 cdv_html_wx:start_link(Parent,{expand,Html,Tab}). 113 114init_ets_page(Parent, Info) -> 115 Pid = proplists:get_value(pid,Info), 116 cdv_virtual_list_wx:start_link(Parent, cdv_ets_cb, Pid). 117 118init_timer_page(Parent, Info) -> 119 Pid = proplists:get_value(pid,Info), 120 cdv_virtual_list_wx:start_link(Parent, cdv_timer_cb, Pid). 121 122%%%----------------------------------------------------------------- 123%%% Internal 124info_fields() -> 125 [{"Overview", 126 [{"Initial Call", init_func}, 127 {dynamic, current_func}, 128 {"Registered Name", name}, 129 {"Status", state}, 130 {"Internal State", int_state}, 131 {"Started", start_time}, 132 {"Parent", {click,parent}}, 133 {"Message Queue Len",msg_q_len}, 134 {"Run queue", run_queue}, 135 {"Reductions", reds}, 136 137 {"Program counter", prog_count}, 138 {"Continuation pointer",cp}, 139 {"Arity",arity}]}, 140 {scroll_boxes, 141 [{"Last Calls",1,{plain,last_calls}}]}, 142 {scroll_boxes, 143 [{"Links",1,{click,links}}, 144 {"Monitors",2,{click,monitors}}, 145 {"Monitored By",2,{click,mon_by}}]}, 146 {"Memory and Garbage Collection", 147 [{"Memory", memory}, 148 {"Stack and Heap", stack_heap}, 149 {"Old Heap", old_heap}, 150 {"Heap Unused", heap_unused}, 151 {"Old Heap Unused", old_heap_unused}, 152 {"Binary vheap", bin_vheap}, 153 {"Old Binary vheap", old_bin_vheap}, 154 {"Binary vheap unused", bin_vheap_unused}, 155 {"Old Binary vheap unused", old_bin_vheap_unused}, 156 {"Number of Heap Fragements", num_heap_frag}, 157 {"Heap Fragment Data",heap_frag_data}, 158 {"New Heap Start", new_heap_start}, 159 {"New Heap Top", new_heap_top}, 160 {"Stack Top", stack_top}, 161 {"Stack End", stack_end}, 162 {"Old Heap Start", old_heap_start}, 163 {"Old Heap Top", old_heap_top}, 164 {"Old Heap End", old_heap_end}]}]. 165