aboutsummaryrefslogtreecommitdiffstats
path: root/lib/observer/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/observer/src')
-rw-r--r--lib/observer/src/cdv_dist_wx.erl13
-rw-r--r--lib/observer/src/cdv_html_page.erl6
-rw-r--r--lib/observer/src/cdv_proc_wx.erl2
-rw-r--r--lib/observer/src/crashdump_viewer.erl65
-rw-r--r--lib/observer/src/crashdump_viewer_html.erl1205
-rw-r--r--lib/observer/src/crashdump_viewer_wx.erl7
6 files changed, 46 insertions, 1252 deletions
diff --git a/lib/observer/src/cdv_dist_wx.erl b/lib/observer/src/cdv_dist_wx.erl
index 6e6284a6ba..3910f4fac5 100644
--- a/lib/observer/src/cdv_dist_wx.erl
+++ b/lib/observer/src/cdv_dist_wx.erl
@@ -58,10 +58,15 @@ get_detail_cols(_) ->
%% Callbacks for cdv_detail_win
get_details(Id) ->
- {ok,Info,TW} = crashdump_viewer:node_info(Id),
- Proplist = crashdump_viewer:to_proplist(record_info(fields,nod),Info),
- Title = io_lib:format("~s (~s)",[Info#nod.name,Id]),
- {ok,{Title,Proplist,TW}}.
+ case crashdump_viewer:node_info(Id) of
+ {ok,Info,TW} ->
+ Proplist = crashdump_viewer:to_proplist(record_info(fields,nod),Info),
+ Title = io_lib:format("~s (~s)",[Info#nod.name,Id]),
+ {ok,{Title,Proplist,TW}};
+ {error,not_found} ->
+ Info = "The node you are searching for could not be found.",
+ {info,Info}
+ end.
detail_pages() ->
[{"General Information", fun init_gen_page/2}].
diff --git a/lib/observer/src/cdv_html_page.erl b/lib/observer/src/cdv_html_page.erl
index d77238c6cf..0208d1d67a 100644
--- a/lib/observer/src/cdv_html_page.erl
+++ b/lib/observer/src/cdv_html_page.erl
@@ -89,11 +89,11 @@ handle_event(#wx{event=#wxHtmlLink{type=command_html_link_clicked,
list_to_integer(Pos)}},
expand(Id,cdv_bin_wx,State);
"#OBSBinary?" ++ BinSpec ->
- [{"offset",Off},{"size",Size},{"pos",Pos}] =
+ [{"key1",Preview},{"key2",Size},{"key3",Hash}] =
httpd:parse_query(BinSpec),
- Id = {obs, {Tab, {list_to_integer(Off),
+ Id = {obs, {Tab, {list_to_integer(Preview),
list_to_integer(Size),
- list_to_integer(Pos)}}},
+ list_to_integer(Hash)}}},
expand(Id,cdv_bin_wx,State);
"#Term?" ++ TermKeys ->
[{"key1",Key1},{"key2",Key2},{"key3",Key3}] =
diff --git a/lib/observer/src/cdv_proc_wx.erl b/lib/observer/src/cdv_proc_wx.erl
index 11f83c79a2..6a8fa0b9be 100644
--- a/lib/observer/src/cdv_proc_wx.erl
+++ b/lib/observer/src/cdv_proc_wx.erl
@@ -70,7 +70,7 @@ get_details(Id) ->
Proplist0 =
crashdump_viewer:to_proplist(record_info(fields,proc),Info),
Proplist = [{expand_table,Tab}|Proplist0],
- Title = io_lib:format("~s (~p)",[Info#proc.name, Id]),
+ Title = io_lib:format("~s (~s)",[Info#proc.name, Id]),
{ok,{Title,Proplist,TW}};
{error,{other_node,NodeId}} ->
Info = "The process you are searching for was residing on "
diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl
index ca91f9061a..53e0241711 100644
--- a/lib/observer/src/crashdump_viewer.erl
+++ b/lib/observer/src/crashdump_viewer.erl
@@ -107,7 +107,6 @@
-define(no_distribution,no_distribution).
-define(node,node).
-define(not_connected,not_connected).
--define(num_atoms,num_atoms).
-define(old_instr_data,old_instr_data).
-define(port,port).
-define(proc,proc).
@@ -347,10 +346,8 @@ handle_call({port,Id},_From,State=#state{file=File}) ->
{ok,PortInfo} ->
TW = truncated_warning([{?port,Id}]),
{ok,PortInfo,TW};
- {other_node,Node} ->
- {error,{other_node,Node}};
- not_found ->
- {error,not_found}
+ Other ->
+ {error,Other}
end,
{reply,Reply,State};
handle_call(ports,_From,State=#state{file=File}) ->
@@ -384,9 +381,17 @@ handle_call(dist_info,_From,State=#state{file=File}) ->
Nods=nods(File),
{reply,{ok,Nods,TW},State};
handle_call({node_info,Channel},_From,State=#state{file=File}) ->
- TW = truncated_warning([?visible_node,?hidden_node,?not_connected]),
- Nod=get_node(File,Channel),
- {reply,{ok,Nod,TW},State};
+ Reply =
+ case get_node(File,Channel) of
+ {ok,Nod} ->
+ TW = truncated_warning([?visible_node,
+ ?hidden_node,
+ ?not_connected]),
+ {ok,Nod,TW};
+ {error,Other} ->
+ {error,Other}
+ end,
+ {reply,Reply,State};
handle_call(loaded_mods,_From,State=#state{file=File}) ->
TW = truncated_warning([?mod]),
{_CC,_OC,Mods} = loaded_mods(File),
@@ -400,7 +405,7 @@ handle_call(funs,_From,State=#state{file=File}) ->
Funs = funs(File),
{reply,{ok,Funs,TW},State};
handle_call(atoms,_From,State=#state{file=File,num_atoms=NumAtoms0}) ->
- TW = truncated_warning([?atoms,?num_atoms]),
+ TW = truncated_warning([?atoms]),
NumAtoms = try list_to_integer(NumAtoms0) catch error:badarg -> -1 end,
Atoms = atoms(File,NumAtoms),
{reply,{ok,Atoms,TW},State};
@@ -587,7 +592,7 @@ progress_read(Fd) ->
{R,Bytes} =
case read(Fd) of
{ok,Bin} ->
- {{ok,Bin},size(Bin)};
+ {{ok,Bin},byte_size(Bin)};
Other ->
{Other,0}
end,
@@ -892,11 +897,7 @@ general_info(File) ->
WholeLine -> WholeLine
end,
- GI0 = get_general_info(Fd,#general_info{created=Created}),
- GI = case GI0#general_info.num_atoms of
- undefined -> GI0#general_info{num_atoms=get_num_atoms(Fd)};
- _ -> GI0
- end,
+ GI = get_general_info(Fd,#general_info{created=Created}),
{MemTot,MemMax} =
case lookup_index(?memory) of
@@ -970,35 +971,6 @@ get_general_info(Fd,GenInfo) ->
GenInfo
end.
-get_num_atoms(Fd) ->
- case lookup_index(?hash_table,"atom_tab") of
- [{_,Pos}] ->
- pos_bof(Fd,Pos),
- skip_rest_of_line(Fd), % size
- skip_rest_of_line(Fd), % used
- case line_head(Fd) of
- "objs" ->
- val(Fd);
- _1 ->
- get_num_atoms2()
- end;
- [] ->
- get_num_atoms2()
- end.
-get_num_atoms2() ->
- case lookup_index(?num_atoms) of
- [] ->
- undefined;
- [{NA,_Pos}] ->
- %% If dump is translated this will exist
- case get(truncated) of
- true ->
- [NA," (visible in dump)"]; % might be more
- false ->
- NA
- end
- end.
-
count() ->
{count_index(?proc),count_index(?ets),count_index(?fu),count_index(?timer)}.
@@ -1554,12 +1526,12 @@ get_node(File,Channel) ->
case ets:select(cdv_dump_index_table,Ms) of
[] ->
- not_found;
+ {error,not_found};
[{Type,Pos}] ->
Fd = open(File),
NodeInfo = get_nodeinfo(Fd,Channel,Type,Pos),
close(Fd),
- NodeInfo
+ {ok,NodeInfo}
end.
%%-----------------------------------------------------------------
@@ -2509,7 +2481,6 @@ tag_to_atom("mod") -> ?mod;
tag_to_atom("no_distribution") -> ?no_distribution;
tag_to_atom("node") -> ?node;
tag_to_atom("not_connected") -> ?not_connected;
-tag_to_atom("num_atoms") -> ?num_atoms;
tag_to_atom("old_instr_data") -> ?old_instr_data;
tag_to_atom("port") -> ?port;
tag_to_atom("proc") -> ?proc;
diff --git a/lib/observer/src/crashdump_viewer_html.erl b/lib/observer/src/crashdump_viewer_html.erl
index 2cc28d04be..4b7caaf41e 100644
--- a/lib/observer/src/crashdump_viewer_html.erl
+++ b/lib/observer/src/crashdump_viewer_html.erl
@@ -23,249 +23,14 @@
%% viewer. No logic or states are kept by this module.
%%
--export([welcome/0,
- read_file_frame/0,
- redirect/1,
- start_page/0,
- filename_frame/1,
- menu_frame/0,
- general_info/1,
- pretty_info_page/2,
- plain_page/1,
- info_page/2,
- proc_details/4,
+-export([plain_page/1,
expandable_term/3,
- expanded_binary/1,
- port/3,
- internal_ets_tables/2,
- nods/2,
- loaded_mod_details/2,
- atoms/4,
- atoms_chunk/2,
- memory/2,
- allocated_areas/2,
- allocator_info/2,
- hash_tables/2,
- index_tables/2,
- error/2,
- warning/1,
- chunk_page/5,
- chunk/3]).
+ warning/1]).
-include("crashdump_viewer.hrl").
-include("observer_defs.hrl").
%%%-----------------------------------------------------------------
-%%% Welcome frame
-welcome() ->
- header(body(welcome_body())).
-
-welcome_body() ->
- table(
- "WIDTH=100% HEIGHT=60%",
- [tr("VALIGN=middle",
- td("ALIGN=center",
- font("SIZE=6",
- ["Welcome to the Web Based",br(),
- "Erlang Crash Dump Analyser"]))),
- tr("VALIGN=middle",
- td("ALIGN=center",
- form(["name=load_new ACTION=\"./read_file_frame\""],
- input(["TYPE=submit VALUE=\"Load Crashdump\""]))))]).
-
-%%%-----------------------------------------------------------------
-%%% Present a form to enter file name of erlang crash dump
-read_file_frame() ->
- header("Read File",body(read_file_frame_body())).
-
-
-read_file_frame_body() ->
- %% Using a plain text input field instead of a file input field
- %% (e.g. <INPUT TYPE=file NAME=pathj SIZE=40">) because most
- %% browsers can not forward the full path from this dialog even if
- %% the browser is running on localhost (Ref 'fakepath'-problem)
- Entry = input("TYPE=text NAME=path SIZE=60"),
- Form =
- form(
- "NAME=read_file_form METHOD=post ACTION=\"./read_file\"",
- table(
- "BORDER=0",
- [tr(td("COLSPAN=2","Enter file to analyse")),
- tr(
- [td(Entry),
- td("ALIGN=center",input("TYPE=submit VALUE=Ok"))])])),
- table(
- "WIDTH=100% HEIGHT=60%",
- tr("VALIGN=middle",
- td("ALIGN=center",Form))).
-
-
-%%%-----------------------------------------------------------------
-%%% Display "Please wait..." while crashdump is being read
-redirect(Status) ->
- Head = ["<META HTTP-EQUIV=\"refresh\" CONTENT=\"3; URL=./redirect\">"],
- header("Please wait...",Head,body([Status,br(),"Please wait..."])).
-
-%%%-----------------------------------------------------------------
-%%% Frameset containing "filename", "menu", and "main" frames
-start_page() ->
- header("Crashdump Viewer Start Page",start_page_frameset()).
-
-start_page_frameset() ->
- frameset(
- "ROWS=\"70,*\"",
- [frame(["NAME=\"filename\" SRC=\"./filename_frame\""]),
- frameset(
- "COLS=\"200,*\"",
- [frame(["NAME=\"menu\" ",
- "SRC=\"/cdv_erl/crashdump_viewer/menu_frame\""]),
- frame("NAME=\"main\" SRC=\"./initial_info_frame\"")])]).
-
-
-
-%%%-----------------------------------------------------------------
-%%% Topmost frame presents the filename of the crashdump currently
-%%% viewed
-filename_frame(File) ->
- header("Filename",body(filename_body(File))).
-
-filename_body(File) ->
- p("ALIGN=center",[b("Crashdump currently viewed:"),br(),File]).
-
-
-%%%-----------------------------------------------------------------
-%%% Left frame displays the menu
-menu_frame() ->
- header("Menu", body(menu_body())).
-
-menu_body() ->
- [p(format_items(1,ets:info(cdv_menu_table,size),true)),
- p([br(),
- form(["name=load_new ACTION=\"./read_file_frame\" ",
- "TARGET=app_frame"],
- input("TYPE=submit VALUE=\"Load New Crashdump\""))])].
-
-format_items(I,Max,_ParentState) when I>Max->
- [];
-format_items(I,Max,ParentState) when I=<Max->
- case ets:lookup(cdv_menu_table,I) of
- [] -> [];
- [#menu_item{state=false,children=0}] ->
- format_items(I+1,Max,ParentState);
- [#menu_item{state=false,children=Children}] ->
- format_items(I+Children+1,Max,arentState);
- [Item=#menu_item{state=true,children=0}] when ParentState ->
- This = format_item(Item),
- [This|format_items(I+1,Max,ParentState)];
- [Item=#menu_item{state=true,children=Children}] when ParentState ->
- This = format_item(Item),
- Ch = format_items(I+1,I+Children,true),
- [[This | Ch] | format_items(I+Children+1,Max,ParentState)]
- end.
-
-format_item(Item) ->
- [lists:duplicate(Item#menu_item.depth*5,?space),
- format_picture(Item#menu_item.index,
- Item#menu_item.picture,
- Item#menu_item.children),
- format_title(Item#menu_item.text,Item#menu_item.target),
- br()].
-
-format_picture(_Index,Picture,0) ->
- img(Picture);
-format_picture(Index,Picture,_Children) ->
- href( ["./toggle?index=", integer_to_list(Index)], img(Picture)).
-
-format_title({Link,Text},Target) ->
- href(["TARGET=\"",Target,"\""],Link,Text);
-format_title(Text,_Type) ->
- Text.
-
-%%%-----------------------------------------------------------------
-%%% Display the general information
-general_info(GenInfo) ->
- Heading = "General Information",
- header(Heading,body(general_info_body(Heading,GenInfo))).
-
-general_info_body(Heading,GenInfo) ->
- TruncatedInfo =
- case get(truncated) of
- true ->
- p(font("SIZE=\"+1\" COLOR=\"#FF0000\"",
- b(["WARNING:",br(),
- "The crashdump is truncated",br(),
- "Some information might be missing",br()])));
- false ->
- ""
- end,
-
- [heading(Heading,"general_info"),
- TruncatedInfo,
- table(
- "BORDER=4 CELLPADDING=4",
- [tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Slogan"),
- td(GenInfo#general_info.slogan)]),
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Node name"),
- td(GenInfo#general_info.node_name)]),
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Crashdump created on"),
- td(GenInfo#general_info.created)]),
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","System version"),
- td(GenInfo#general_info.system_vsn)]),
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Compiled"),
- td(GenInfo#general_info.compile_time)]),
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Taints"),
- td(GenInfo#general_info.taints)]),
- case GenInfo#general_info.mem_tot of
- "" -> "";
- MemTot ->
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Memory allocated"),
- td([MemTot," bytes"])])
- end,
- case GenInfo#general_info.mem_max of
- "" -> "";
- MemMax ->
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Memory maximum"),
- td([MemMax," bytes"])])
- end,
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Atoms"),
- td(GenInfo#general_info.num_atoms)]),
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Processes"),
- td(GenInfo#general_info.num_procs)]),
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","ETS tables"),
- td(GenInfo#general_info.num_ets)]),
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Timers"),
- td(GenInfo#general_info.num_timers)]),
- tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Funs"),
- td(GenInfo#general_info.num_fun)])]),
- case GenInfo#general_info.instr_info of
- old_instr_data ->
- [br(),br(),
- font("COLOR=\"#FF0000\"",
- ["Instrumentation information is found at the end of ",br(),
- "the dump. The information has an old format, and ",br(),
- "is not presented in this tool. Please read the ",br(),
- "crashdump manually to see this information."])];
- instr_data ->
- [br(),br(),
- font("COLOR=\"#FF0000\"",
- ["Instrumentation information is found at the end of ",br(),
- "the dump. The information is not presented in this ",br(),
- "tool. Please read the crashdump manually to see",br(),
- "this information."])];
- false ->
- []
- end].
-
-%%%-----------------------------------------------------------------
-%%% Display an error message
-error(Text,Args) ->
- Str = io_lib:format(Text,Args),
- header(body(error_body(Str))).
-
-error_body(Str) ->
- [h1("An error occured:"),Str,"\n"].
-
-%%%-----------------------------------------------------------------
%%% Display the given information as is, no heading
%%% Empty body if no info exists.
warning(Info) ->
@@ -284,213 +49,6 @@ plain_body(Info) ->
[pre(href_proc_port(lists:flatten(Info)))].
%%%-----------------------------------------------------------------
-%%% Display the given information as is
-info_page(Heading,Info) ->
- info_page(Heading,Info,[]).
-info_page(Heading,Info,TW) ->
- header(Heading,body(info_body(Heading,Info,TW))).
-
-info_body(Heading,[],TW) ->
- [h1(Heading),
- warn(TW),
- "No information was found\n"];
-info_body(Heading,Info,TW) ->
- [h1(Heading),
- warn(TW),
- pre(href_proc_port(lists:flatten(Info)))].
-
-%%%-----------------------------------------------------------------
-%%% Pretty print the given information
-pretty_info_page(Heading,Info) ->
- header(Heading,body(pretty_info_body(Heading,Info))).
-
-pretty_info_body(Heading,[]) ->
- [h1(Heading),
- "No information was found\n"];
-pretty_info_body(Heading,Info) ->
- [h1(Heading),
- pre(pretty_format(Info))].
-
-%%%-----------------------------------------------------------------
-%%% Print details for one process
-proc_details(Pid,Proc,TW,SharedHeap) ->
- Script =
-"<SCRIPT type=\"text/javascript\">
- function popup() {
- window.open(\"\",\"expanded\",'resizable=yes,scrollbars=yes')
-}
-</SCRIPT>\n",
-
- Heading = ["Process ", Pid],
- header(Heading,Script,body(proc_details_body(Heading,Proc,TW,SharedHeap))).
-
-proc_details_body(Heading,Proc,TW,SharedHeap) ->
- Pid = Proc#proc.pid,
- Name = if Proc#proc.name==Proc#proc.init_func -> ?space;
- true -> Proc#proc.name
- end,
- [help("processes"),
- warn(TW),
- table(
- "BORDER=4 COLS=4 WIDTH=\"100%\"",
- [tr(
- "BGCOLOR=\"#8899AA\"",
- [td("COLSPAN=4 ALIGN=center",Heading)]),
- tr(
- [td("NOWRAP=true",b("Name")),
- td("COLSPAN=1",Name),
- td("NOWRAP=true",b("Spawned as")),
- td("COLSPAN=1",Proc#proc.init_func)]),
- tr(
- [td("NOWRAP=true",b("State")),
- td("COLSPAN=1",Proc#proc.state),
- td("NOWRAP=true",b(element(1,Proc#proc.current_func))),
- td("COLSPAN=1",element(2,Proc#proc.current_func))]),
- tr(
- [td("NOWRAP=true",b("Started")),
- td("COLSPAN=1",Proc#proc.start_time),
- td("NOWRAP=true",b("Spawned by")),
- td("COLSPAN=1",href_proc_port(Proc#proc.parent))]),
- tr(
- [td("NOWRAP=true",b("Reductions")),
- td("COLSPAN=1",integer_to_list(Proc#proc.reds))] ++
- case Proc#proc.memory of
- undefined -> []; % before R16B01
- Mem ->
- [td("NOWRAP=true",b("Memory (bytes)")),
- td("COLSPAN=1",integer_to_list(Mem))]
- end),
- if SharedHeap ->
- Stack = case Proc#proc.stack_heap of
- -1 -> "unknown";
- S -> integer_to_list(S)
- end,
- tr(
- [td("NOWRAP=true",b("Stack")),
- td("COLSPAN=3",Stack)]);
- true ->
- [tr(
- [td("NOWRAP=true",b("Stack+heap")),
- td(integer_to_list(Proc#proc.stack_heap)),
- td("NOWRAP=true",b("OldHeap")),
- td(Proc#proc.old_heap)]),
- tr(
- [td("NOWRAP=true",b("Heap unused")),
- td(Proc#proc.heap_unused),
- td("NOWRAP=true",b("OldHeap unused")),
- td(Proc#proc.old_heap_unused)]),
- tr(
- [td("NOWRAP=true",b("Number of heap fragments")),
- td(Proc#proc.num_heap_frag),
- td("NOWRAP=true",b("Heap fragment data")),
- td(Proc#proc.heap_frag_data)])]
- end,
- case Proc#proc.new_heap_start of
- ?space -> "";
- _ ->
- %% Garbing
- [tr(
- [td("NOWRAP=true",b("New heap start")),
- td("COLSPAN=1",Proc#proc.new_heap_start),
- td("NOWRAP=true",b("New heap top")),
- td("COLSPAN=1",Proc#proc.new_heap_top)]),
- tr(
- [td("NOWRAP=true",b("Stack top")),
- td("COLSPAN=1",Proc#proc.stack_top),
- td("NOWRAP=true",b("Stack end")),
- td("COLSPAN=1",Proc#proc.stack_end)]),
- tr(
- [td("NOWRAP=true",b("Old heap start")),
- td("COLSPAN=1",Proc#proc.old_heap_start),
- td("NOWRAP=true",b("Old heap top")),
- td("COLSPAN=1",Proc#proc.old_heap_top)]),
- tr(
- [td("NOWRAP=true",b("Old heap end")),
- td("COLSPAN=3",Proc#proc.old_heap_end)])]
- end,
- case Proc#proc.prog_count of
- ?space -> "";
- _ ->
- [tr(
- [td("NOWRAP=true",b("Program counter")),
- td("COLSPAN=3",Proc#proc.prog_count)]),
- tr(
- [td("NOWRAP=true",b("Continuation pointer")),
- td("COLSPAN=3",Proc#proc.cp)]),
- tr(
- [td("NOWRAP=true",b("Arity")),
- td("COLSPAN=3",Proc#proc.arity)])]
- end,
- tr(
- [td("NOWRAP=true",b("Link list")),
- td("COLSPAN=3",href_proc_port(Proc#proc.links))]),
-
- tr(
- [td("NOWRAP=true",b("Msg queue length")),
- td("COLSPAN=3",integer_to_list(Proc#proc.msg_q_len))]),
-
- %% These are displayed only if data exist
- display_or_link_to_expand("MsgQueue",Proc#proc.msg_q,Pid),
- display_or_link_to_expand("Dictionary",Proc#proc.dict,Pid),
- display_or_link_to_expand("LastCalls",Proc#proc.last_calls,Pid),
- display_or_link_to_expand("StackDump",Proc#proc.stack_dump,Pid)]),
-
- p([href(["./ets_tables?pid=",Proc#proc.pid],
- "ETS tables owned by this process"),
- "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",
- href(["./timers?pid=",Proc#proc.pid],
- "Timers owned by this process")])].
-
-display_or_link_to_expand(Heading,Data,Pid) ->
- case Data of
- expand ->
- link_to_read_memory(Heading,Pid);
- truncated ->
- Text = font("COLOR=\"#FF0000\"",
- "The dump is truncated, no data available"),
- tr(
- [td("NOWRAP=true VALIGN=top",b(Heading)),
- td("COLSPAN=3",Text)]);
- ?space ->
- "";
- {size,Truncated,Size,Pos} ->
- %% Too much data, or truncated data -
- %% display a link to expand it
- tr(
- [td("NOWRAP=true",b(Heading)),
- td("COLSPAN=3",
- href("TARGET=\"expanded\" onClick=popup()",
- ["./expand?pos=",integer_to_list(Pos),
- "&size=",integer_to_list(Size),
- "&what=",Heading,
- "&truncated=",atom_to_list(Truncated)],
- ["Expand (",integer_to_list(Size)," bytes)"]))]);
- _ ->
- %% Not too much Data - display it
- tr(
- [td("NOWRAP=true VALIGN=top",b(Heading)),
- td("COLSPAN=3",pre(format(Heading,Data)))])
- end.
-
-link_to_read_memory(Heading,Pid) ->
- tr(
- [td("NOWRAP=true",b(Heading)),
- td("COLSPAN=3",
- href("TARGET=\"expanded\" onClick=popup()",
- ["./expand_memory?pid=",Pid,
- "&what=",Heading],
- ["Expand ", Heading]))]).
-
-format("LastCalls",Data) ->
- Data;
-format("StackDump",Data) ->
- Data;
-format(_Heading,Data) ->
- pretty_format(Data).
-
-
-
-%%%-----------------------------------------------------------------
%%% Expanded memory
expandable_term(Heading,Expanded,Tab) ->
header(Heading,body(expandable_term_body(Heading,Expanded,Tab))).
@@ -585,7 +143,7 @@ proc_state(Tab,{Key0,Value0}, Even) ->
all_or_expand(Tab,Term) ->
Preview = io_lib:format("~P",[Term,8]),
- Check = io_lib:format("~P",[Term,9]),
+ Check = io_lib:format("~P",[Term,100]),
Exp = Preview=/=Check,
all_or_expand(Tab,Term,Preview,Exp).
all_or_expand(_Tab,_Term,Str,false) ->
@@ -619,416 +177,7 @@ color(true) -> io_lib:format("BGCOLOR=\"#~2.16.0B~2.16.0B~2.16.0B\"", tuple_to_l
color(false) -> io_lib:format("BGCOLOR=\"#~2.16.0B~2.16.0B~2.16.0B\"", tuple_to_list(?BG_ODD)).
%%%-----------------------------------------------------------------
-%%% Display an expanded binary, i.e. the whole binary, not just the
-%%% size of it.
-expanded_binary(Bin) ->
- Heading = "Expanded binary",
- header(Heading,body(expanded_binary_body(Heading,Bin))).
-
-expanded_binary_body(Heading,Bin) ->
- [h1(Heading),
- pre(href_proc_port(lists:flatten(Bin))),
- br(),br(),
- href("javascript:history.go(-1)","BACK")].
-
-%%%-----------------------------------------------------------------
-%%% Print info for one port
-port(Heading,Port,TW) ->
- header(Heading,body(port_body(Heading,Port,TW))).
-
-port_body(Heading,Port,TW) ->
- [heading(Heading,"ports"),
- warn(TW),
- table(
- "BORDER=4 CELLPADDING=4",
- [tr([th(Head) || Head <- port_table_head()]), ports_table(Port)])].
-
-%%%-----------------------------------------------------------------
-%%% Print table of internal ETS tables
-internal_ets_tables(InternalEts,TW) ->
- Heading = "Internal ETS tables",
- header(Heading,body(internal_ets_tables_body(Heading,InternalEts,TW))).
-
-internal_ets_tables_body(Heading,[],TW) ->
- [h1(Heading),
- warn(TW),
- "No internal ETS tables were found\n"];
-internal_ets_tables_body(Heading,InternalEts,TW) ->
- [heading(Heading,"internal_ets_tables"),
- warn(TW),
- table(
- "BORDER=4 CELLPADDING=4",
- [tr(
- [th("Description"),
- th("Id"),
- th("Name"),
- th("Type"),
- th("Buckets"),
- th("Objects"),
- th("Memory (bytes)")]) |
- lists:map(fun(InternalEtsTable) ->
- internal_ets_tables_table1(InternalEtsTable)
- end,
- InternalEts)])].
-
-internal_ets_tables_table1({Descr,InternalEtsTable}) ->
- #ets_table{id=Id,name=Name,type=Type,buckets=Buckets,
- size=Size,memory=Memory} = InternalEtsTable,
- tr(
- [td(Descr),
- td(Id),
- td(Name),
- td(Type),
- td("ALIGN=right",Buckets),
- td("ALIGN=right",Size),
- td("ALIGN=right",Memory)]).
-
-%%%-----------------------------------------------------------------
-%%% Print table of nodes in distribution
-nods(Nods,TW) ->
- header("Distribution Information",body(nodes_body(Nods,TW))).
-
-nodes_body(no_distribution,_TW) ->
- [heading("Distribution Information","distribution_info"),
- "Not alive\n"];
-nodes_body({Type,Info,Node},TW) when is_record(Node,nod) ->
- %% Display only one node - used when a pid or port on a remote
- %% node is clicked.
- [heading("Remote Node","distribution_info"),
- warn(TW),
- Info,
- make_nodes_table(Type,[Node])];
-nodes_body({Visible,Hidden,NotConnected},TW) ->
- %% Display all nodes - this is the complete distribution info
- [heading("Distribution Information","distribution_info"),
- warn(TW),
- make_nodes_table("Visible Nodes",Visible),
- make_nodes_table("Hidden Nodes",Hidden),
- make_nodes_table("Not Connected Nodes",NotConnected)].
-
-make_nodes_table(Text,[]) ->
- p(["No \"",Text,"\" were found"]);
-make_nodes_table(Text,Nodes) ->
- p(table(
- "BORDER=4 CELLPADDING=4",
- [nodes_table_heading(Text),
- lists:map(fun(Node) -> nodes_table_row(Node) end, Nodes)])).
-
-nodes_table_heading(Text) ->
- [tr("BGCOLOR=\"#8899AA\"",[th("COLSPAN=6",Text)]),
- tr([th("Name"),
- th("Channel"),
- th("Controller"),
- th("Creation(s)"),
- th("Links/Monitors"),
- th("Extra info")])].
-
-nodes_table_row(Node) ->
- #nod{name=Name,channel=Channel,controller=Controller,creation=Creation,
- remote_links=Links,remote_mon=Mon,remote_mon_by=MonBy,error=Error}=Node,
- tr(
- [td(maybe_refcount(Name)),
- td("ALIGN=right",Channel),
- td(href_proc_port(Controller)),
- td("ALIGN=right",break_lines_creation(Creation)),
- td(format_links_and_monitors(Links,Mon,MonBy)),
- td(format_extra_info(Error))]).
-
-maybe_refcount(Name) ->
- maybe_refcount(Name, []).
-maybe_refcount([$ ,$( | Rest], Acc) ->
- [lists:reverse(Acc),br(),[$(|Rest]];
-maybe_refcount([Char | Rest], Acc) ->
- maybe_refcount(Rest, [Char | Acc]);
-maybe_refcount([],Acc) ->
- lists:reverse(Acc).
-
-break_lines_creation(Creation) ->
- break_lines_creation(Creation,[]).
-break_lines_creation([$ ,$( | Rest1], Acc) ->
- {RefCount,Rest2} = to_end_par(Rest1,[$(,$ ]),
- [lists:reverse(Acc),RefCount,br(),break_lines_creation(Rest2)];
-break_lines_creation([$ | Rest], Acc) ->
- [lists:reverse(Acc),br(),break_lines_creation(Rest)];
-break_lines_creation([Char | Rest], Acc) ->
- break_lines_creation(Rest, [Char | Acc]);
-break_lines_creation([],Acc) ->
- lists:reverse(Acc).
-
-to_end_par([$),$ | Rest], Acc) ->
- {lists:reverse([$) | Acc]),Rest};
-to_end_par([$) | Rest], Acc) ->
- {lists:reverse([$) | Acc]),Rest};
-to_end_par([Char | Rest], Acc) ->
- to_end_par(Rest, [Char | Acc]);
-to_end_par([],Acc) ->
- {lists:reverse(Acc),[]}.
-
-
-format_links_and_monitors(?space,?space,?space) ->
- ?space;
-format_links_and_monitors(Links,Mon,MonBy) ->
- [format_links_and_monitors(Links," is linked to "),
- format_links_and_monitors(Mon," is monitoring "),
- format_links_and_monitors(MonBy," is monitored by ")].
-
-format_links_and_monitors(?space,_Text) ->
- "";
-format_links_and_monitors([{Local,Remote}|Rest],Text) ->
- [[href_proc_port(Local),Text,href_proc_port(Remote),br()] |
- format_links_and_monitors(Rest,Text)];
-format_links_and_monitors([],_Text) ->
- [].
-
-format_extra_info(?space) ->
- ?space;
-format_extra_info(Error) ->
- case Error of
- ?space -> "";
- _ -> font("COLOR=\"#FF0000\"",["ERROR: ",Error,"\n"])
- end.
-
-%%%-----------------------------------------------------------------
-%%% Print detailed information about one module
-loaded_mod_details(ModInfo,TW) ->
- header(ModInfo#loaded_mod.mod,body(loaded_mod_details_body(ModInfo,TW))).
-
-loaded_mod_details_body(ModInfo,TW) ->
- #loaded_mod{mod=Mod,current_size=CS,current_attrib=CA,
- current_comp_info=CCI,old_size=OS,
- old_attrib=OA,old_comp_info=OCI} = ModInfo,
- [help("loaded_modules"),
- warn(TW),
- table(
- "BORDER=4 CELLPADDING=4",
- [tr(th("BGCOLOR=\"#8899AA\" COLSPAN=3",
- ["Module: ",Mod])),
- tr([td(?space),th("Current"),th("Old")]),
- tr([th("ALIGN=left","Size (bytes)"),
- td(CS),
- td(OS)]),
- tr([th("ALIGN=left","Attributes"),
- td(pre(CA)),
- td(pre(OA))]),
- tr([th("ALIGN=left","Compilation info"),
- td(pre(CCI)),
- td(pre(OCI))])])].
-
-
-%%%-----------------------------------------------------------------
-%%% Print atoms
-atoms(SessionId,TW,Num,FirstChunk) ->
- Heading = "Atoms",
- case FirstChunk of
- done ->
- deliver_first(SessionId,[start_html_page(Heading),
- h1(Heading),
- warn(TW),
- "No atoms were found in log",br(),
- "Total number of atoms in node was ", Num,
- br()]);
- _ ->
- deliver_first(SessionId,[start_html_page(Heading),
- heading(Heading,"atoms"),
- warn(TW),
- "Total number of atoms in node was ", Num,
- br(),
- "The last created atom is shown first",
- br(),
- start_pre()]),
- atoms_chunk(SessionId,FirstChunk)
- end.
-
-atoms_chunk(SessionId,done) ->
- deliver(SessionId,[stop_pre(),stop_html_page()]);
-atoms_chunk(SessionId,Atoms) ->
- deliver(SessionId,Atoms).
-
-%%%-----------------------------------------------------------------
-%%% Print memory information
-memory(Memory,TW) ->
- Heading = "Memory Information",
- header(Heading,body(memory_body(Heading,Memory,TW))).
-
-memory_body(Heading,[],TW) ->
- [h1(Heading),
- warn(TW),
- "No memory information was found\n"];
-memory_body(Heading,Memory,TW) ->
- [heading(Heading,"memory"),
- warn(TW),
- table(
- "BORDER=4 CELLPADDING=4",
- [tr("BGCOLOR=\"#8899AA\"",
- [th(?space),
- th("Bytes")]) |
- lists:map(fun(Entry) -> memory_table(Entry) end, Memory)])].
-
-memory_table({Key,Value}) ->
- tr([th("ALIGN=left",Key),td("ALIGN=right",Value)]).
-
-%%%-----------------------------------------------------------------
-%%% Print allocated areas information
-allocated_areas(AllocatedAreas,TW) ->
- Heading = "Information about allocated areas",
- header(Heading,body(allocated_areas_body(Heading,AllocatedAreas,TW))).
-
-allocated_areas_body(Heading,[],TW) ->
- [h1(Heading),
- warn(TW),
- "No information was found about allocated areas\n"];
-allocated_areas_body(Heading,AllocatedAreas,TW) ->
- [heading(Heading,"memory"),
- warn(TW),
- table(
- "BORDER=4 CELLPADDING=4",
- [tr("BGCOLOR=\"#8899AA\"",
- [th(?space),
- th("Allocated (bytes)"),
- th("Used (bytes)")]) |
- lists:map(fun(Entry) -> allocated_areas_table(Entry) end,
- AllocatedAreas)])].
-
-allocated_areas_table({Key,Alloc,Used}) ->
- tr(
- [th("ALIGN=left",Key),
- td("ALIGN=right",Alloc),
- td("ALIGN=right",Used)]).
-
-
-%%%-----------------------------------------------------------------
-%%% Print allocator_info information
-allocator_info(Allocators,TW) ->
- Heading = "Allocator Information",
- header(Heading,body(allocator_info_body(Heading,Allocators,TW))).
-
-allocator_info_body(Heading,[],TW) ->
- [h1(Heading),
- warn(TW),
- "No information was found about allocators\n"];
-allocator_info_body(Heading,Allocators,TW) ->
- [heading(Heading,"memory"),
- warn(TW),
- p(b("Sizes are in bytes")),
- lists:map(fun({Head,Allocator}) ->
- TableHead =
- case Head of
- {SubTitle,Columns} ->
- tr("BGCOLOR=\"#8899AA\"",
- [th("ALIGN=left",
- font("SIZE=+1",SubTitle)) |
- lists:map(
- fun(CH) ->
- th("ALIGN=right",CH)
- end,
- Columns)]);
- SubTitle ->
- tr("BGCOLOR=\"#8899AA\"",
- th("COLSPAN=10 ALIGN=left",
- font("SIZE=+1",SubTitle)))
- end,
- [table(
- "BORDER=4 CELLPADDING=4",
- [TableHead |
- lists:map(
- fun({Key,Values}) ->
- tr([th("ALIGN=left",Key) |
- lists:map(
- fun(Val) ->
- td("ALIGN=right",Val)
- end,Values)])
- end,
- Allocator)]),
- br(),br()]
- end,
- Allocators)].
-
-%%%-----------------------------------------------------------------
-%%% Print informatin about internal tables
-hash_tables(HashTables,TW) ->
- Heading = "Hash Table Information",
- header(Heading,body(hash_tables_body(Heading,HashTables,TW))).
-
-hash_tables_body(Heading,[],TW) ->
- [h1(Heading),
- warn(TW),
- "No hash table information was found\n"];
-hash_tables_body(Heading,HashTables,TW) ->
- [heading(Heading,"internal_tables"),
- warn(TW),
- table(
- "BORDER=4 CELLPADDING=4",
- [tr(
- [th("Name"),
- th("Size"),
- th("Used"),
- th("Objects"),
- th("Depth")]) |
- lists:map(fun(HashTable) -> hash_tables_table(HashTable) end,
- HashTables)])].
-
-hash_tables_table(HashTable) ->
- #hash_table{name=Name,size=Size,used=Used,objs=Objs,depth=Depth}=HashTable,
- tr(
- [td(Name),
- td("ALIGN=right",Size),
- td("ALIGN=right",Used),
- td("ALIGN=right",Objs),
- td("ALIGN=right",Depth)]).
-
-index_tables(IndexTables,TW) ->
- Heading = "Index Table Information",
- header(Heading,body(index_tables_body(Heading,IndexTables,TW))).
-
-index_tables_body(Heading,[],TW) ->
- [h1(Heading),
- warn(TW),
- "No index table information was found\n"];
-index_tables_body(Heading,IndexTables,TW) ->
- [heading(Heading,"internal_tables"),
- warn(TW),
- table(
- "BORDER=4 CELLPADDING=4",
- [tr(
- [th("Name"),
- th("Size"),
- th("Limit"),
- th("Used"),
- th("Rate"),
- th("Entries")]) |
- lists:map(fun(IndexTable) -> index_tables_table(IndexTable) end,
- IndexTables)])].
-
-index_tables_table(IndexTable) ->
- #index_table{name=Name,size=Size,limit=Limit,used=Used,
- rate=Rate,entries=Entries} = IndexTable,
- tr(
- [td(Name),
- td("ALIGN=right",Size),
- td("ALIGN=right",Limit),
- td("ALIGN=right",Used),
- td("ALIGN=right",Rate),
- td("ALIGN=right",Entries)]).
-
-%%%-----------------------------------------------------------------
%%% Internal library
-start_html_page(Title) ->
- [start_html(),
- only_html_header(Title),
- start_html_body()].
-
-stop_html_page() ->
- [stop_html_body(),
- stop_html()].
-
-only_html_header(Title) ->
- only_html_header(Title,"").
-only_html_header(Title,JavaScript) ->
- ["<HEAD>\n",
- "<TITLE>", Title, "</TITLE>\n",
- JavaScript,
- "</HEAD>\n"].
-
start_html() ->
"<HTML>\n".
stop_html() ->
@@ -1052,22 +201,17 @@ html_header(Title,JavaScript,Body) ->
Body,
stop_html()].
+only_html_header(Title,JavaScript) ->
+ ["<HEAD>\n",
+ "<TITLE>", Title, "</TITLE>\n",
+ JavaScript,
+ "</HEAD>\n"].
+
body(Text) ->
[start_html_body(),
Text,
stop_html_body()].
-frameset(Args,Frames) ->
- ["<FRAMESET ",Args,">\n", Frames, "\n</FRAMESET>\n"].
-frame(Args) ->
- ["<FRAME ",Args, ">\n"].
-
-start_visible_table() ->
- start_table("BORDER=\"4\" CELLPADDING=\"4\"").
-start_visible_table(ColTitles) ->
- [start_visible_table(),
- tr([th(ColTitle) || ColTitle <- ColTitles])].
-
start_table(Args) ->
["<TABLE ", Args, ">\n"].
stop_table() ->
@@ -1079,8 +223,6 @@ tr(Text) ->
["<TR>\n", Text, "\n</TR>\n"].
tr(Args,Text) ->
["<TR ", Args, ">\n", Text, "\n</TR>\n"].
-th(Text) ->
- ["<TH>", Text, "</TH>"].
th(Args,Text) ->
["<TH ", Args, ">\n", Text, "\n</TH>\n"].
td(Text) ->
@@ -1088,10 +230,6 @@ td(Text) ->
td(Args,Text) ->
["<TD ", Args, ">", Text, "</TD>"].
-b(Text) ->
- ["<B>",Text,"</B>"].
-em(Text) ->
- ["<EM>",Text,"</EM>\n"].
start_pre() ->
"<PRE>".
stop_pre() ->
@@ -1102,22 +240,10 @@ href(Link,Text) ->
["<A HREF=\"",Link,"\">",Text,"</A>"].
href(Args,Link,Text) ->
["<A HREF=\"",Link,"\" ",Args,">",Text,"</A>"].
-img("") ->
- "";
-img(Picture) ->
- ["<IMG SRC=\"", Picture, "\" BORDER=0>"].
-form(Args,Text) ->
- ["<FORM ",Args,">\n",Text,"\n</FORM>\n"].
-input(Args) ->
- ["<INPUT ", Args, ">\n"].
-h1(Text) ->
- ["<H1>",Text,"</H1>\n"].
font(Args,Text) ->
["<FONT ",Args,">\n",Text,"\n</FONT>\n"].
p(Text) ->
["<P>",Text,"</P>\n"].
-p(Args, Text) ->
- ["<P ", Args, ">",Text,"</P>\n"].
br() ->
"<BR>\n".
@@ -1236,9 +362,9 @@ href_proc_bin(From, T, Acc, LTB) ->
")&gt;&gt;"],
if LTB ->
href("TARGET=\"expanded\"",
- ["#OBSBinary?offset="++Preview++
- "&size="++Size++
- "&pos="++Md5],
+ ["#OBSBinary?key1="++Preview++
+ "&key2="++Size++
+ "&key3="++Md5],
PreviewStr);
true ->
PreviewStr
@@ -1260,310 +386,3 @@ warn([]) ->
[];
warn(Warning) ->
font("COLOR=\"#FF0000\"",p([Warning,br(),br()])).
-
-heading(Heading,HelpMarker) ->
- [font("SIZE=+2",b(Heading)),?space,?space,help(HelpMarker)].
-
-help(HelpMarker) ->
- [href("TARGET=doc",
- ["/crashdump_doc/crashdump_help.html#",HelpMarker],
- "Help"),
- br(),br()].
-
-%%%-----------------------------------------------------------------
-%%% This function pretty formats a string which contains erlang
-%%% terms (e.g. the message queue).
-%%% In all the following, "<" is changed to "&lt;" and ">" is changed to "&gt;"
-pretty_format(In) ->
- case catch scan(In,[],initial,[]) of
- {'EXIT',_Reason} ->
- %% Probably a truncated file, so the erlang term is not complete
- [font("COLOR=\"#FF0000\"","(This term might be truncated)"),
- href_proc_port(lists:flatten(In))];
- {[R],_,Insrt} ->
- InsrtString = lists:flatten(io_lib:format("~p",[R])),
- lists:flatten(replace_insrt(lists:reverse(InsrtString),Insrt,[]))
- end.
-
-%% Finish term
-scan(In,Acc,list,Insrt) when hd(In)==$] ->
- {lists:reverse(Acc),tl(In),Insrt};
-scan(In,Acc,tuple,Insrt) when hd(In)==$} ->
- {list_to_tuple(lists:reverse(Acc)),tl(In),Insrt};
-scan(In,Acc,atom,Insrt) when In==[];hd(In)==$,;hd(In)==$];hd(In)==$} ->
- {list_to_atom(lists:reverse(Acc)),In,Insrt};
-scan(In,Acc,float,Insrt) when In==[];hd(In)==$,;hd(In)==$];hd(In)==$} ->
- {list_to_float(lists:reverse(Acc)),In,Insrt};
-scan(In,Acc,integer,Insrt) when In==[];hd(In)==$,;hd(In)==$];hd(In)==$} ->
- {list_to_integer(lists:reverse(Acc)),In,Insrt};
-scan([$"|In],Acc,string,Insrt) when In==[];hd(In)==$,;hd(In)==$];hd(In)==$} ->
- {lists:reverse(Acc),In,Insrt};
-scan([$>|In],Acc,special,Insrt) when In==[];hd(In)==$,;hd(In)==$];hd(In)==$} ->
- %% pid, ref, port, fun
- {lists:reverse([$;,$t,$g,$&|Acc]),In,Insrt};
-scan([$}|In],Acc,special,Insrt) when In==[];hd(In)==$,;hd(In)==$];hd(In)==$} ->
- %% bignum integer, e.g. #integer(2) = {2452,4324}
- {lists:reverse([$}|Acc]),In,Insrt};
-scan([$,|In],Acc,Cur,Insrt) when Cur/=string,Cur/=special ->
- scan(In,Acc,Cur,Insrt);
-
-%% In the middle of an atom
-scan([$'|In],Acc,Cur,Insrt) when Cur==atom ->
- %% all $' are removed. They are added again by list_to_atom,
- %% so if we don't remove them we will get two of them.
- scan(In,Acc,Cur,Insrt);
-
-%% A $. in the middle of an integer - turn to float
-scan([C|T],Acc,integer,Insrt) when C==$. ->
- scan(T,[C|Acc],float,Insrt);
-
-%% In the middle of an atom, integer, float or string
-scan([$<|T],Acc,Cur,Insrt) when Cur==atom;Cur==string;Cur==special ->
- scan(T,[$;,$t,$l,$&|Acc],Cur,Insrt);
-scan([$>|T],Acc,Cur,Insrt) when Cur==atom;Cur==string ->
- scan(T,[$;,$t,$g,$&|Acc],Cur,Insrt);
-scan([C|T],Acc,Cur,Insrt) when Cur==atom;Cur==integer;Cur==float;Cur==string;Cur==special ->
- scan(T,[C|Acc],Cur,Insrt);
-
-%% Start list
-scan([$[|T],Acc,Cur,Insrt0) ->
- {L,Rest,Insrt} = scan(T,[],list,Insrt0),
- scan(Rest,[L|Acc],Cur,Insrt);
-
-%% Star tuple
-scan([${|T],Acc,Cur,Insrt0) ->
- {Tuple,Rest,Insrt} = scan(T,[],tuple,Insrt0),
- scan(Rest,[Tuple|Acc],Cur,Insrt);
-
-%% Star string
-scan([$"|T],Acc,Cur,Insrt0) ->
- {String,Rest,Insrt} = scan(T,[],string,Insrt0),
- scan(Rest,[String|Acc],Cur,Insrt);
-
-%% Start atom
-scan([$'|T],Acc,Cur,Insrt0) ->
- %% all $' are removed. They are added again by list_to_atom,
- %% so if we don't remove them we will get two of them.
- {Atom,Rest,Insrt} = scan(T,[],atom,Insrt0),
- scan(Rest,[Atom|Acc],Cur,Insrt);
-scan([C|T],Acc,Cur,Insrt0) when C>=$A,C=<$Z;C>=$a,C=<$z;C==$'->
- {Atom,Rest,Insrt} = scan(T,[C],atom,Insrt0),
- scan(Rest,[Atom|Acc],Cur,Insrt);
-
-%% Start integer or float
-scan([C|T],Acc,Cur,Insrt0) when C>=$0,C=<$9;C==$- ->
- {Num,Rest,Insrt} = scan(T,[C],integer,Insrt0), % can later change to float
- scan(Rest,[Num|Acc],Cur,Insrt);
-
-%% Start Pid/Port/Ref/Fun/Binary
-scan([$<|T],Acc,Cur,Insrt0) ->
- {Special,Rest,Insrt} = scan(T,[$;,$t,$l,$&],special,Insrt0),
- scan(Rest,['$insrt'|Acc],Cur,[Special|Insrt]);
-scan([$#|T],Acc,Cur,Insrt0) ->
- {Special,Rest,Insrt} = scan(T,[$#],special,Insrt0),
- scan(Rest,['$insrt'|Acc],Cur,[Special|Insrt]);
-
-
-%% done
-scan([],Acc,initial,Insrt) ->
- {Acc,[],Insrt}.
-
-
-replace_insrt("'trsni$'"++Rest,[H|T],Acc) -> % the list is reversed here!
- Special =
- case H of
- "&lt;&lt;" ++ _Binary ->
- H;
- "&lt;" ++ _Pid ->
- href("TARGET=\"main\"",["./proc_details?pid=",H],H);
- "#Port&lt;" ++ Port ->
- href("TARGET=\"main\"",["./port?port=","Port&lt;"++Port],H);
- "#" ++ _other ->
- H
- end,
- replace_insrt(Rest,T,[Special|Acc]);
-replace_insrt([H|T],Insrt,Acc) ->
- replace_insrt(T,Insrt,[H|Acc]);
-replace_insrt([],[],Acc) ->
- Acc.
-
-%%%-----------------------------------------------------------------
-%%% Create a page with one table by delivering chunk by chunk to
-%%% inets. crashdump_viewer first calls chunk_page/5 once, then
-%%% chunk/3 multiple times until all data is delivered.
-chunk_page(processes,SessionId,TW,{Sorted,SharedHeap,DumpVsn},FirstChunk) ->
- Columns = procs_summary_table_head(Sorted,SharedHeap,DumpVsn),
- chunk_page(SessionId, "Process Information", TW, FirstChunk,
- "processes", Columns, fun procs_summary_table/1);
-chunk_page(ports,SessionId,TW,_,FirstChunk) ->
- chunk_page(SessionId, "Port Information", TW, FirstChunk,
- "ports", port_table_head(), fun ports_table/1);
-chunk_page(ets_tables,SessionId,TW,Heading,FirstChunk) ->
- Columns = ["Owner",
- "Slot",
- "Id",
- "Name",
- "Type",
- "Buckets",
- "Objects",
- "Memory (bytes)"],
- chunk_page(SessionId, Heading, TW, FirstChunk,
- "ets_tables", Columns, fun ets_tables_table/1);
-chunk_page(timers,SessionId,TW,Heading,FirstChunk) ->
- chunk_page(SessionId, Heading, TW, FirstChunk, "timers",
- ["Owner","Message","Time left"], fun timers_table/1);
-chunk_page(loaded_mods,SessionId,TW,{CC,OC},FirstChunk) ->
- TotalsInfo = p([b("Current code: "),CC," bytes",br(),
- b("Old code: "),OC," bytes"]),
- Columns = ["Module","Current size (bytes)","Old size (bytes)"],
- chunk_page(SessionId, "Loaded Modules Information", TW, FirstChunk,
- "loaded_modules", TotalsInfo,Columns, fun loaded_mods_table/1);
-chunk_page(funs,SessionId, TW, _, FirstChunk) ->
- Columns = ["Module",
- "Uniq",
- "Index",
- "Address",
- "Native_address",
- "Refc"],
- chunk_page(SessionId, "Fun Information", TW, FirstChunk,
- "funs", Columns, fun funs_table/1).
-
-chunk_page(SessionId,Heading,TW,FirstChunk,Type,TableColumns,TableFun) ->
- chunk_page(SessionId,Heading,TW,FirstChunk,Type,[],TableColumns,TableFun).
-chunk_page(SessionId,Heading,TW,done,Type,_TotalsInfo,_TableColumns,_TableFun) ->
- no_info_found(SessionId,Heading,TW,Type);
-chunk_page(SessionId,Heading,TW,FirstChunk,Type,TotalsInfo,TableColumns,TableFun) ->
- deliver_first(SessionId,[start_html_page(Heading),
- heading(Heading,Type),
- warn(TW),
- TotalsInfo,
- start_visible_table(TableColumns)]),
- chunk(SessionId,FirstChunk,TableFun),
- TableFun.
-
-no_info_found(SessionId, Heading, TW, Type) ->
- Info = ["No ", Type, " were found\n"],
- deliver_first(SessionId,[start_html_page(Heading),
- h1(Heading),
- warn(TW),
- Info,
- stop_html_page()]).
-
-chunk(SessionId, done, _TableFun) ->
- deliver(SessionId,[stop_table(),stop_html_page()]);
-chunk(SessionId, Items, TableFun) ->
- deliver(SessionId, [lists:map(TableFun, Items),
- stop_table(), %! Will produce an empty table at the end
- start_visible_table()]). % of the page :(
-
-%%%-----------------------------------------------------------------
-%%% Deliver part of a page to inets
-%%% The first part, which includes the HTTP header, must always be
-%%% delivered as a string (i.e. no binaries). The rest of the page is
-%%% better delivered as binaries in order to avoid data copying.
-deliver_first(SessionId,String) ->
- mod_esi:deliver(SessionId,String).
-deliver(SessionId,IoList) ->
- mod_esi:deliver(SessionId,[list_to_binary(IoList)]).
-
-
-%%%-----------------------------------------------------------------
-%%% Page specific stuff for chunk pages
-procs_summary_table_head(Sorted,SharedHeap,DumpVsn) ->
- MemHeading =
- if DumpVsn>=?r16b01_dump_vsn ->
- "Memory (bytes)";
- true ->
- if SharedHeap ->
- "Stack";
- true ->
- "Stack+heap"
- end
- end,
- [procs_summary_table_head1("pid","Pid",Sorted),
- procs_summary_table_head1("name_func","Name/Spawned as",Sorted),
- procs_summary_table_head1("state","State",Sorted),
- procs_summary_table_head1("reds","Reductions",Sorted),
- procs_summary_table_head1("mem",MemHeading,Sorted),
- procs_summary_table_head1("msg_q_len","MsgQ Length",Sorted)].
-
-procs_summary_table_head1(_,Text,no_sort) ->
- Text;
-procs_summary_table_head1(Sorted,Text,Sorted) ->
- %% Mark the sorted column (bigger and italic)
- font("SIZE=\"+1\"",em(href("./sort_procs?sort="++Sorted,Text)));
-procs_summary_table_head1(SortOn,Text,_Sorted) ->
- href("./sort_procs?sort="++SortOn,Text).
-
-procs_summary_table(Proc) ->
- #proc{pid=Pid,name=Name,state=State,
- reds=Reds,stack_heap=Stack,memory=Memory,msg_q_len=MsgQLen}=Proc,
- Mem =
- case Memory of
- undefined -> % assuming pre-R16B01
- case Stack of
- -1 -> "unknown";
- _ -> integer_to_list(Stack)
- end;
- _ ->
- integer_to_list(Memory)
- end,
- tr(
- [td(href(["./proc_details?pid=",Pid],Pid)),
- td(Name),
- td(State),
- td("ALIGN=right",integer_to_list(Reds)),
- td("ALIGN=right",Mem),
- td("ALIGN=right",integer_to_list(MsgQLen))]).
-
-port_table_head() ->
- ["Id","Slot","Connected","Links","Name","Monitors","Controls"].
-
-ports_table(Port) ->
- #port{id=Id,slot=Slot,connected=Connected,links=Links,name=Name,
- monitors=Monitors,controls=Controls}=Port,
- tr(
- [td(Id),
- td("ALIGN=right",Slot),
- td(href_proc_port(Connected)),
- td(href_proc_port(Links)),
- td(Name),
- td(href_proc_port(Monitors)),
- td(Controls)]).
-
-ets_tables_table(EtsTable) ->
- #ets_table{pid=Pid,slot=Slot,id=Id,name=Name,type=Type,
- buckets=Buckets,size=Size,memory=Memory} = EtsTable,
- tr(
- [td(href_proc_port(Pid)),
- td(Slot),
- td(Id),
- td(Name),
- td(Type),
- td("ALIGN=right",Buckets),
- td("ALIGN=right",Size),
- td("ALIGN=right",Memory)]).
-
-timers_table(Timer) ->
- #timer{pid=Pid,msg=Msg,time=Time}=Timer,
- tr(
- [td(href_proc_port(Pid)),
- td(Msg),
- td("ALIGN=right",Time)]).
-
-loaded_mods_table(#loaded_mod{mod=Mod,current_size=CS,old_size=OS}) ->
- tr([td(href(["loaded_mod_details?mod=",http_uri:encode(Mod)],Mod)),
- td("ALIGN=right",CS),
- td("ALIGN=right",OS)]).
-
-funs_table(Fu) ->
- #fu{module=Module,uniq=Uniq,index=Index,address=Address,
- native_address=NativeAddress,refc=Refc}=Fu,
- tr(
- [td(Module),
- td("ALIGN=right",Uniq),
- td("ALIGN=right",Index),
- td(Address),
- td(NativeAddress),
- td("ALIGN=right",Refc)])
-.
diff --git a/lib/observer/src/crashdump_viewer_wx.erl b/lib/observer/src/crashdump_viewer_wx.erl
index 17e43838d6..3464dfafae 100644
--- a/lib/observer/src/crashdump_viewer_wx.erl
+++ b/lib/observer/src/crashdump_viewer_wx.erl
@@ -122,7 +122,6 @@ init(File0) ->
wxNotebook:connect(Notebook, command_notebook_page_changing),
wxFrame:connect(Frame, close_window, [{skip, true}]),
wxMenu:connect(Frame, command_menu_selected),
- wxFrame:show(Frame),
case load_dump(Frame,File0) of
{ok,File} ->
@@ -149,7 +148,7 @@ init(File0) ->
ignore
end.
-setup(#state{frame=Frame, notebook=Notebook, main_panel=Panel}=State) ->
+setup(#state{frame=Frame, notebook=Notebook}=State) ->
%% Setup Menubar & Menus
MenuBar = wxMenuBar:new(),
@@ -190,8 +189,8 @@ setup(#state{frame=Frame, notebook=Notebook, main_panel=Panel}=State) ->
%% Memory Panel
IntPanel = add_page(Notebook, ?INT_STR, cdv_multi_panel, cdv_int_tab_wx),
- %% Force redraw (window needs it)
- wxWindow:refresh(Panel),
+ %% Show the window
+ wxFrame:show(Frame),
GenPid = wx_object:get_pid(GenPanel),
GenPid ! active,