aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2015-05-27 15:42:47 +0200
committerDan Gudmundsson <[email protected]>2015-06-05 12:57:34 +0200
commit534a23c34d38a954610ac11329515a373efa008b (patch)
tree1cb6df58180a2126559db5d363e47fd05d2359f5
parent9b683f4bf98500f76a33f098879ee733790baa1f (diff)
downloadotp-534a23c34d38a954610ac11329515a373efa008b.tar.gz
otp-534a23c34d38a954610ac11329515a373efa008b.tar.bz2
otp-534a23c34d38a954610ac11329515a373efa008b.zip
observer: cdv add more ets information
Info available from erl-18 nodes.
-rw-r--r--lib/observer/src/cdv_bin_cb.erl6
-rw-r--r--lib/observer/src/cdv_detail_wx.erl10
-rw-r--r--lib/observer/src/cdv_dist_cb.erl6
-rw-r--r--lib/observer/src/cdv_ets_cb.erl73
-rw-r--r--lib/observer/src/cdv_fun_cb.erl2
-rw-r--r--lib/observer/src/cdv_html_wx.erl2
-rw-r--r--lib/observer/src/cdv_mod_cb.erl6
-rw-r--r--lib/observer/src/cdv_port_cb.erl8
-rw-r--r--lib/observer/src/cdv_proc_cb.erl8
-rw-r--r--lib/observer/src/cdv_term_cb.erl4
-rw-r--r--lib/observer/src/cdv_timer_cb.erl2
-rw-r--r--lib/observer/src/cdv_virtual_list_wx.erl94
-rw-r--r--lib/observer/src/crashdump_viewer.erl39
-rw-r--r--lib/observer/src/crashdump_viewer.hrl8
-rw-r--r--lib/observer/src/observer_lib.erl2
-rw-r--r--lib/observer/src/observer_procinfo.erl2
16 files changed, 196 insertions, 76 deletions
diff --git a/lib/observer/src/cdv_bin_cb.erl b/lib/observer/src/cdv_bin_cb.erl
index d5fbceff1e..8b427e92b7 100644
--- a/lib/observer/src/cdv_bin_cb.erl
+++ b/lib/observer/src/cdv_bin_cb.erl
@@ -17,14 +17,14 @@
%% %CopyrightEnd%
-module(cdv_bin_cb).
--export([get_details/1,
+-export([get_details/2,
detail_pages/0]).
%% Callbacks for cdv_detail_wx
-get_details({Type, {T,Key}}) ->
+get_details({Type, {T,Key}}, _) ->
[{Key,Term}] = ets:lookup(T,Key),
{ok,{"Expanded Binary", {Type, Term}, []}};
-get_details({cdv, Id}) ->
+get_details({cdv, Id}, _) ->
{ok,Bin} = crashdump_viewer:expand_binary(Id),
{ok,{"Expanded Binary", {cvd, Bin}, []}}.
diff --git a/lib/observer/src/cdv_detail_wx.erl b/lib/observer/src/cdv_detail_wx.erl
index dc93507a36..ec0d877d87 100644
--- a/lib/observer/src/cdv_detail_wx.erl
+++ b/lib/observer/src/cdv_detail_wx.erl
@@ -19,7 +19,7 @@
-behaviour(wx_object).
--export([start_link/3]).
+-export([start_link/4]).
-export([init/1, handle_event/2, handle_cast/2, terminate/2, code_change/3,
handle_call/3, handle_info/2]).
@@ -38,13 +38,13 @@
-define(ID_NOTEBOOK, 604).
%% Detail view
-start_link(Id, ParentFrame, Callback) ->
- wx_object:start_link(?MODULE, [Id, ParentFrame, Callback, self()], []).
+start_link(Id, Data, ParentFrame, Callback) ->
+ wx_object:start_link(?MODULE, [Id, Data, ParentFrame, Callback, self()], []).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-init([Id, ParentFrame, Callback, Parent]) ->
- case Callback:get_details(Id) of
+init([Id, Data, ParentFrame, Callback, Parent]) ->
+ case Callback:get_details(Id, Data) of
{ok,Details} ->
init(Id,ParentFrame,Callback,Parent,Details);
{yes_no, Info, Fun} ->
diff --git a/lib/observer/src/cdv_dist_cb.erl b/lib/observer/src/cdv_dist_cb.erl
index f7e6c9aded..f45fb1f524 100644
--- a/lib/observer/src/cdv_dist_cb.erl
+++ b/lib/observer/src/cdv_dist_cb.erl
@@ -21,7 +21,7 @@
col_spec/0,
get_info/1,
get_detail_cols/1,
- get_details/1,
+ get_details/2,
detail_pages/0,
format/1]).
@@ -55,10 +55,10 @@ get_info(_) ->
{Info,TW}.
get_detail_cols(_) ->
- {[?COL_CH,?COL_CTRL],true}.
+ {[{node, ?COL_CH},{port,?COL_CTRL}],true}.
%% Callbacks for cdv_detail_wx
-get_details(Id) ->
+get_details(Id, _) ->
case crashdump_viewer:node_info(Id) of
{ok,Info,TW} ->
Proplist = crashdump_viewer:to_proplist(record_info(fields,nod),Info),
diff --git a/lib/observer/src/cdv_ets_cb.erl b/lib/observer/src/cdv_ets_cb.erl
index 2a5c170e58..371c7f0b32 100644
--- a/lib/observer/src/cdv_ets_cb.erl
+++ b/lib/observer/src/cdv_ets_cb.erl
@@ -20,7 +20,10 @@
-export([col_to_elem/1,
col_spec/0,
get_info/1,
- get_detail_cols/1]).
+ get_details/2,
+ get_detail_cols/1,
+ detail_pages/0
+ ]).
-include_lib("wx/include/wx.hrl").
-include("crashdump_viewer.hrl").
@@ -41,7 +44,7 @@ col_to_elem(?COL_ID) -> #ets_table.id;
col_to_elem(?COL_NAME) -> #ets_table.name;
col_to_elem(?COL_SLOT) -> #ets_table.slot;
col_to_elem(?COL_OWNER) -> #ets_table.pid;
-col_to_elem(?COL_TYPE) -> #ets_table.type;
+col_to_elem(?COL_TYPE) -> #ets_table.data_type;
col_to_elem(?COL_BUCK) -> #ets_table.buckets;
col_to_elem(?COL_OBJ) -> #ets_table.size;
col_to_elem(?COL_MEM) -> #ets_table.memory.
@@ -50,18 +53,68 @@ col_spec() ->
[{"Id", ?wxLIST_FORMAT_LEFT, 200},
{"Name", ?wxLIST_FORMAT_LEFT, 200},
{"Slot", ?wxLIST_FORMAT_RIGHT, 50},
- {"Owner", ?wxLIST_FORMAT_CENTRE, 90},
- {"Buckets", ?wxLIST_FORMAT_RIGHT, 50},
- {"Objects", ?wxLIST_FORMAT_RIGHT, 50},
- {"Memory", ?wxLIST_FORMAT_RIGHT, 80},
- {"Type", ?wxLIST_FORMAT_LEFT, 50}
+ {"Owner", ?wxLIST_FORMAT_CENTRE, 120},
+ {"Objects", ?wxLIST_FORMAT_RIGHT, 80},
+ {"Memory", ?wxLIST_FORMAT_RIGHT, 80}
+% {"Type", ?wxLIST_FORMAT_LEFT, 50}
].
get_info(Owner) ->
{ok,Info,TW} = crashdump_viewer:ets_tables(Owner),
{Info,TW}.
+%% Callbacks for cdv_detail_wx
+get_details(_Id, not_found) ->
+ Info = "The table you are searching for could not be found.",
+ {info,Info};
+get_details(Id, Data) ->
+ Proplist = crashdump_viewer:to_proplist(record_info(fields,ets_table),Data),
+ {ok,{"Table:" ++ Id,Proplist,""}}.
+
get_detail_cols(all) ->
- {[?COL_OWNER],false};
-get_detail_cols(_) ->
- {[],false}.
+ {[{ets, ?COL_ID}, {process, ?COL_OWNER}],true};
+get_detail_cols(_W) ->
+ {[],true}.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%
+
+detail_pages() ->
+ [{"Table Information", fun init_gen_page/2}].
+
+init_gen_page(Parent, Info0) ->
+ Fields = info_fields(),
+ Details = proplists:get_value(details, Info0),
+ Info = if is_map(Details) -> Info0 ++ maps:to_list(Details);
+ true -> Info0
+ end,
+ cdv_info_wx:start_link(Parent,{Fields,Info,[]}).
+
+%%% Internal
+info_fields() ->
+ [{"Overview",
+ [{"Id", id},
+ {"Name", name},
+ {"Slot", slot},
+ {"Owner", owner},
+ {"Data Structure", data_type}
+ ]},
+ {"Settings",
+ [{"Type", type},
+ {"Protection", protection},
+ {"Compressed", compressed},
+ {"Fixed", fixed},
+ {"Lock write concurrency", write_c},
+ {"Lock read concurrency", read_c}
+ ]},
+ {"Memory Usage",
+ [{"Buckets", buckets},
+ {"Size", size},
+ {"Memory", memory},
+ {"Min Chain Length", chain_min},
+ {"Avg Chain Length", chain_avg},
+ {"Max Chain Length", chain_max},
+ {"Chain Length Std Dev", chain_stddev},
+ {"Chain Length Expected Std Dev", chain_exp_stddev}
+ ]}
+ ].
diff --git a/lib/observer/src/cdv_fun_cb.erl b/lib/observer/src/cdv_fun_cb.erl
index 689ef0e3bb..067377254a 100644
--- a/lib/observer/src/cdv_fun_cb.erl
+++ b/lib/observer/src/cdv_fun_cb.erl
@@ -55,4 +55,4 @@ get_info(_) ->
{Info,TW}.
get_detail_cols(_) ->
- {[?COL_MOD],false}.
+ {[{module, ?COL_MOD}],false}.
diff --git a/lib/observer/src/cdv_html_wx.erl b/lib/observer/src/cdv_html_wx.erl
index b79c647f63..6d19589f5d 100644
--- a/lib/observer/src/cdv_html_wx.erl
+++ b/lib/observer/src/cdv_html_wx.erl
@@ -126,7 +126,7 @@ expand(Id,Callback,#state{expand_wins=Opened0}=State) ->
Opened =
case lists:keyfind(Id,1,Opened0) of
false ->
- EW = cdv_detail_wx:start_link(Id,State#state.panel,Callback),
+ EW = cdv_detail_wx:start_link(Id,[],State#state.panel,Callback),
wx_object:get_pid(EW) ! active,
[{Id,EW}|Opened0];
{_,EW} ->
diff --git a/lib/observer/src/cdv_mod_cb.erl b/lib/observer/src/cdv_mod_cb.erl
index e829ff4fca..8d33f9da9d 100644
--- a/lib/observer/src/cdv_mod_cb.erl
+++ b/lib/observer/src/cdv_mod_cb.erl
@@ -21,7 +21,7 @@
col_spec/0,
get_info/1,
get_detail_cols/1,
- get_details/1,
+ get_details/2,
detail_pages/0,
format/1]).
@@ -49,10 +49,10 @@ get_info(_) ->
{Info,TW}.
get_detail_cols(_) ->
- {[?COL_ID],true}.
+ {[{module, ?COL_ID}],true}.
%% Callbacks for cdv_detail_wx
-get_details(Id) ->
+get_details(Id, _) ->
{ok,Info,TW} = crashdump_viewer:loaded_mod_details(Id),
Proplist = crashdump_viewer:to_proplist(record_info(fields,loaded_mod),Info),
Title = io_lib:format("~s",[Info#loaded_mod.mod]),
diff --git a/lib/observer/src/cdv_port_cb.erl b/lib/observer/src/cdv_port_cb.erl
index 08488d3e34..409431218b 100644
--- a/lib/observer/src/cdv_port_cb.erl
+++ b/lib/observer/src/cdv_port_cb.erl
@@ -21,7 +21,7 @@
col_spec/0,
get_info/1,
get_detail_cols/1,
- get_details/1,
+ get_details/2,
detail_pages/0,
format/1]).
@@ -57,10 +57,10 @@ get_info(_) ->
{Info,TW}.
get_detail_cols(_) ->
- {[?COL_ID,?COL_CONN],true}.
+ {[{port, ?COL_ID},{process, ?COL_CONN}],true}.
%% Callbacks for cdv_detail_wx
-get_details(Id) ->
+get_details(Id, _Data) ->
case crashdump_viewer:port(Id) of
{ok,Info,TW} ->
Proplist =
@@ -70,7 +70,7 @@ get_details(Id) ->
Info = "The port you are searching for was residing on "
"a remote node. No port information is available. "
"Show information about the remote node?",
- Fun = fun() -> cdv_virtual_list_wx:start_detail_win(NodeId) end,
+ Fun = fun() -> cdv_virtual_list_wx:start_detail_win(NodeId, node) end,
{yes_no, Info, Fun};
{error,not_found} ->
Info = "The port you are searching for could not be found.",
diff --git a/lib/observer/src/cdv_proc_cb.erl b/lib/observer/src/cdv_proc_cb.erl
index d1549f79eb..4ab7c2add8 100644
--- a/lib/observer/src/cdv_proc_cb.erl
+++ b/lib/observer/src/cdv_proc_cb.erl
@@ -21,7 +21,7 @@
col_spec/0,
get_info/1,
get_detail_cols/1,
- get_details/1,
+ get_details/2,
detail_pages/0]).
-include_lib("wx/include/wx.hrl").
@@ -57,10 +57,10 @@ get_info(_) ->
{Info,TW}.
get_detail_cols(_) ->
- {[?COL_ID],true}.
+ {[{process, ?COL_ID}],true}.
%% Callbacks for cdv_detail_wx
-get_details(Id) ->
+get_details(Id, _) ->
case crashdump_viewer:proc_details(Id) of
{ok,Info,TW} ->
%% The following table is used by observer_html_lib
@@ -76,7 +76,7 @@ get_details(Id) ->
Info = "The process you are searching for was residing on "
"a remote node. No process information is available. "
"Show information about the remote node?",
- Fun = fun() -> cdv_virtual_list_wx:start_detail_win(NodeId) end,
+ Fun = fun() -> cdv_virtual_list_wx:start_detail_win(NodeId, port) end,
{yes_no, Info, Fun};
{error,not_found} ->
Info = "The process you are searching for could not be found.",
diff --git a/lib/observer/src/cdv_term_cb.erl b/lib/observer/src/cdv_term_cb.erl
index 4451045012..6db6d54514 100644
--- a/lib/observer/src/cdv_term_cb.erl
+++ b/lib/observer/src/cdv_term_cb.erl
@@ -17,11 +17,11 @@
%% %CopyrightEnd%
-module(cdv_term_cb).
--export([get_details/1,
+-export([get_details/2,
detail_pages/0]).
%% Callbacks for cdv_detail_wx
-get_details({Type, {T,Key}}) ->
+get_details({Type, {T,Key}}, _) ->
[{Key,Term}] = ets:lookup(T,Key),
{ok,{"Expanded Term", {Type,[Term, T]}, []}}.
diff --git a/lib/observer/src/cdv_timer_cb.erl b/lib/observer/src/cdv_timer_cb.erl
index d44592cf18..b4564941ea 100644
--- a/lib/observer/src/cdv_timer_cb.erl
+++ b/lib/observer/src/cdv_timer_cb.erl
@@ -49,6 +49,6 @@ get_info(Owner) ->
{Info,TW}.
get_detail_cols(all) ->
- {[?COL_OWNER],false};
+ {[{process, ?COL_OWNER}],false};
get_detail_cols(_) ->
{[],false}.
diff --git a/lib/observer/src/cdv_virtual_list_wx.erl b/lib/observer/src/cdv_virtual_list_wx.erl
index bfe115a42e..561526c0bc 100644
--- a/lib/observer/src/cdv_virtual_list_wx.erl
+++ b/lib/observer/src/cdv_virtual_list_wx.erl
@@ -19,7 +19,8 @@
-behaviour(wx_object).
--export([start_link/2, start_link/3, start_detail_win/1]).
+-export([start_link/2, start_link/3,
+ start_detail_win/1, start_detail_win/2]).
%% wx_object callbacks
-export([init/1, handle_info/2, terminate/2, code_change/3, handle_call/3,
@@ -65,22 +66,28 @@ start_link(ParentWin, Callback, Owner) ->
wx_object:start_link(?MODULE, [ParentWin, Callback, Owner], []).
start_detail_win(Id) ->
- Callback =
- case Id of
- "<"++_ ->
- cdv_proc_cb;
- "#Port"++_ ->
- cdv_port_cb;
- _ ->
- case catch list_to_integer(Id) of
- NodeId when is_integer(NodeId) ->
- cdv_dist_cb;
- _ ->
- cdv_mod_cb
- end
- end,
- start_detail_win(Callback,Id).
-start_detail_win(Callback,Id) ->
+ case Id of
+ "<"++_ ->
+ start_detail_win(Id, process);
+ "#Port"++_ ->
+ start_detail_win(Id, port);
+ _ ->
+ io:format("cdv: unknown identifier: ~p~n",[Id]),
+ ignore
+ end.
+
+start_detail_win(Id, process) ->
+ start_detail_win_2(cdv_proc_cb, Id);
+start_detail_win(Id, port) ->
+ start_detail_win_2(cdv_port_cb, Id);
+start_detail_win(Id, node) ->
+ start_detail_win_2(cdv_dist_cb, Id);
+start_detail_win(Id, module) ->
+ start_detail_win_2(cdv_mod_cb, Id);
+start_detail_win(Id, ets) ->
+ start_detail_win_2(cdv_ets_cb, Id).
+
+start_detail_win_2(Callback,Id) ->
wx_object:cast(Callback,{start_detail_win,Id}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -158,15 +165,14 @@ create_list_box(Panel, Holder, Callback, Owner) ->
do_start_detail_win(undefined, State) ->
State;
do_start_detail_win(Id, #state{panel=Panel,detail_wins=Opened,
- callback=Callback}=State) ->
+ holder=Holder,callback=Callback}=State) ->
NewOpened =
case lists:keyfind(Id, 1, Opened) of
false ->
- case cdv_detail_wx:start_link(Id, Panel, Callback) of
- {error, _} ->
- Opened;
- IW ->
- [{Id, IW} | Opened]
+ Data = call(Holder, {get_data, self(), Id}),
+ case cdv_detail_wx:start_link(Id, Data, Panel, Callback) of
+ {error, _} -> Opened;
+ IW -> [{Id, IW} | Opened]
end;
{_, IW} ->
wxFrame:raise(IW),
@@ -247,8 +253,8 @@ handle_event(#wx{id=MenuId,
event=#wxCommand{type = command_menu_selected}},
#state{menu_items=MenuItems} = State) ->
case lists:keyfind(MenuId,1,MenuItems) of
- {MenuId,Id} ->
- start_detail_win(Id);
+ {MenuId,Type,Id} ->
+ start_detail_win(Id, Type);
false ->
ok
end,
@@ -265,7 +271,7 @@ handle_event(#wx{event=#wxList{type=command_list_item_right_click,
Menu = wxMenu:new(),
MenuItems =
lists:flatmap(
- fun(Col) ->
+ fun({Type, Col}) ->
MenuId = ?ID_DETAILS + Col,
ColText = call(Holder, {get_row, self(), Row, Col}),
case ColText of
@@ -273,14 +279,15 @@ handle_event(#wx{event=#wxList{type=command_list_item_right_click,
_ ->
What =
case catch list_to_integer(ColText) of
- NodeId when is_integer(NodeId) ->
+ NodeId when is_integer(NodeId),
+ Type =:= node ->
"node " ++ ColText;
_ ->
ColText
end,
Text = "Properties for " ++ What,
wxMenu:append(Menu, MenuId, Text),
- [{MenuId,ColText}]
+ [{MenuId,Type,ColText}]
end
end,
MenuCols),
@@ -300,9 +307,14 @@ handle_event(#wx{event=#wxList{type=command_list_col_click, col=Col}},
handle_event(#wx{event=#wxList{type=command_list_item_activated,
itemIndex=Row}},
- #state{holder=Holder} = State) ->
- Id = call(Holder, {get_row, self(), Row, id}),
- start_detail_win(Id),
+ #state{holder=Holder, menu_cols=MenuCols} = State) ->
+ case MenuCols of
+ [{Type, _}|_] ->
+ Id = call(Holder, {get_row, self(), Row, id}),
+ start_detail_win(Id, Type);
+ _ ->
+ ignore
+ end,
{noreply, State};
handle_event(Event, State) ->
@@ -346,7 +358,7 @@ init_table_holder(Parent, Attrs, Callback, InfoList0) ->
attrs=Attrs,
callback=Callback}).
-table_holder(#holder{callback=Callback, attrs=Attrs}=S0) ->
+table_holder(#holder{callback=Callback, attrs=Attrs, info=Info}=S0) ->
receive
_M={get_row, From, Row, Col} ->
%% erlang:display(_M),
@@ -360,6 +372,9 @@ table_holder(#holder{callback=Callback, attrs=Attrs}=S0) ->
%% erlang:display(_M),
State = change_sort(Callback:col_to_elem(Col), S0),
table_holder(State);
+ _M={get_data, From, Id} ->
+ search_id(From, Id, Callback, Info),
+ table_holder(S0);
stop ->
ok;
What ->
@@ -367,6 +382,21 @@ table_holder(#holder{callback=Callback, attrs=Attrs}=S0) ->
table_holder(S0)
end.
+search_id(From, Id, Callback, Info) ->
+ Find = fun(_, RowInfo, _) ->
+ search_id(Callback, RowInfo, Id)
+ end,
+ Res = try array:foldl(Find, not_found, Info)
+ catch Data -> Data end,
+ From ! {self(), Res},
+ ok.
+
+search_id(Callback, RowInfo, Id) ->
+ case observer_lib:to_str(get_cell_data(Callback, id, RowInfo)) of
+ Id -> throw(RowInfo);
+ _Str -> not_found
+ end.
+
change_sort(Col, S0=#holder{parent=Parent, info=Info0, sort=Sort0}) ->
NRows = array:size(Info0),
InfoList0 = array:to_list(Info0),
diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl
index ef14ba46e2..0d7ad47ef4 100644
--- a/lib/observer/src/crashdump_viewer.erl
+++ b/lib/observer/src/crashdump_viewer.erl
@@ -1503,7 +1503,7 @@ get_ets_tables(File,Pid,WS) ->
end,
lookup_and_parse_index(File,{?ets,Pid},ParseFun,"ets").
-get_etsinfo(Fd,EtsTable,WS) ->
+get_etsinfo(Fd,EtsTable = #ets_table{details=Ds},WS) ->
case line_head(Fd) of
"Slot" ->
get_etsinfo(Fd,EtsTable#ets_table{slot=list_to_integer(val(Fd))},WS);
@@ -1513,7 +1513,7 @@ get_etsinfo(Fd,EtsTable,WS) ->
get_etsinfo(Fd,EtsTable#ets_table{name=val(Fd)},WS);
"Ordered set (AVL tree), Elements" ->
skip_rest_of_line(Fd),
- get_etsinfo(Fd,EtsTable#ets_table{type="tree",buckets="-"},WS);
+ get_etsinfo(Fd,EtsTable#ets_table{data_type="tree"},WS);
"Buckets" ->
%% A bug in erl_db_hash.c prints a space after the buckets
%% - need to strip the string to make list_to_integer/1 happy.
@@ -1528,9 +1528,42 @@ get_etsinfo(Fd,EtsTable,WS) ->
-1 -> -1; % probably truncated
_ -> Words * WS
end,
- get_etsinfo(Fd,EtsTable#ets_table{memory=Bytes},WS);
+ get_etsinfo(Fd,EtsTable#ets_table{memory={bytes,Bytes}},WS);
"=" ++ _next_tag ->
EtsTable;
+ "Chain Length Min" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{chain_min=>Val}},WS);
+ "Chain Length Avg" ->
+ Val = try list_to_float(string:strip(val(Fd))) catch _:_ -> "-" end,
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{chain_avg=>Val}},WS);
+ "Chain Length Max" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{chain_max=>Val}},WS);
+ "Chain Length Std Dev" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{chain_stddev=>Val}},WS);
+ "Chain Length Expected Std Dev" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{chain_exp_stddev=>Val}},WS);
+ "Fixed" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{fixed=>Val}},WS);
+ "Type" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{data_type=>Val}},WS);
+ "Protection" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{protection=>Val}},WS);
+ "Compressed" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{compressed=>Val}},WS);
+ "Write Concurrency" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{write_c=>Val}},WS);
+ "Read Concurrency" ->
+ Val = val(Fd),
+ get_etsinfo(Fd,EtsTable#ets_table{details=Ds#{read_c=>Val}},WS);
Other ->
unexpected(Fd,Other,"ETS info"),
EtsTable
diff --git a/lib/observer/src/crashdump_viewer.hrl b/lib/observer/src/crashdump_viewer.hrl
index 47705d0da7..06a81500e3 100644
--- a/lib/observer/src/crashdump_viewer.hrl
+++ b/lib/observer/src/crashdump_viewer.hrl
@@ -103,10 +103,12 @@
slot,
id,
name,
- type="hash",
- buckets,
+ data_type="hash",
+ buckets="-",
size,
- memory}).
+ memory,
+ details= #{}
+ }).
-record(timer,
{pid,
diff --git a/lib/observer/src/observer_lib.erl b/lib/observer/src/observer_lib.erl
index 9592ab5977..c3d48dff35 100644
--- a/lib/observer/src/observer_lib.erl
+++ b/lib/observer/src/observer_lib.erl
@@ -269,6 +269,8 @@ to_str(Pid) when is_pid(Pid) ->
pid_to_list(Pid);
to_str(No) when is_integer(No) ->
integer_to_list(No);
+to_str(Float) when is_float(Float) ->
+ io_lib:format("~.3f", [Float]);
to_str(Term) ->
io_lib:format("~w", [Term]).
diff --git a/lib/observer/src/observer_procinfo.erl b/lib/observer/src/observer_procinfo.erl
index 2a840dc49e..d724cd9e96 100644
--- a/lib/observer/src/observer_procinfo.erl
+++ b/lib/observer/src/observer_procinfo.erl
@@ -150,7 +150,7 @@ handle_event(#wx{event=#wxHtmlLink{linkInfo=#wxHtmlLinkInfo{href=Href}}},
Opened =
case lists:keyfind(Id,1,Opened0) of
false ->
- Win = cdv_detail_wx:start_link(Id,Frame,Callback),
+ Win = cdv_detail_wx:start_link(Id,[],Frame,Callback),
[{Id,Win}|Opened0];
{_,Win} ->
wxFrame:raise(Win),