etp_commands.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 172 行

ERL
172
字号
%% ``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%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%-module(etp_commands).-export([file/1]).file([Fname]) ->    Result = (catch file_1(Fname)),    io:format("% ~p~n", [Result]),    init:stop().file_1(Fname) ->    io:format("% Reading ~p...~n", [Fname]),    {ok,Fd} = file:open(Fname, [read,binary]),    case read_op(Fd, 128) of	"chart" ->            io:format("% Reading heap chart data...~n"),	    chart_scan(Fd);	"overlapped-heaps" ->             io:format("% Reading overlapped-heaps data...~n"),	    overlapped_scan(Fd)    end.read_op(_Fd, 0) ->    [];read_op(Fd, N) ->    case file:read(Fd, 1) of	{ok,<<0>>} -> [];	{ok,<<C>>} -> [C|read_op(Fd, N-1)]    end.overlapped_scan(Fd) ->    overlapped_scan_1(Fd, []).overlapped_scan_1(Fd, R) ->    case file:read(Fd, 4*5) of	eof ->	    io:format("% Analyzing overlaps...~n"),	    overlapped_analyze(lists:sort(R));	{ok,<<Id:32/native,Heap:32/native,Hend:32/native,	     0:32/native,0:32/native>>} 	when Heap < Hend ->	    overlapped_scan_to_0(Fd, [{{Heap,Hend},{Id,heap}}|R], Id, 1);	{ok,<<Id:32/native,Heap:32/native,Hend:32/native,	     OldHeap:32/native,OldHend:32/native>>} 	when Heap < Hend, OldHeap < OldHend->	    overlapped_scan_to_0(Fd, [{{Heap,Hend},{Id,heap}},				      {{OldHeap,OldHend},{Id,old_heap}}|R],				 Id, 1)    end.overlapped_scan_to_0(Fd, R, Id, Cnt) ->    case file:read(Fd, 4*2) of	{ok,<<0:32/native,0:32/native>>} ->	    overlapped_scan_1(Fd, R);	{ok,<<Heap:32/native,Hend:32/native>>}	when Heap < Hend ->	    overlapped_scan_to_0(Fd, 				 [{{Heap,Hend},{Id,{heap_fragment,Cnt}}}|R],				 Id, Cnt+1);	eof ->	    io:format("% Premature end of dump: ~p~n", [Id,Cnt|R])    end.overlapped_analyze([]) ->     io:format("% Oops! was that file empty?~n");overlapped_analyze([{{_,Hend1},_}|[{{Heap2,_},_}|_]=R])   when Hend1 =< Heap2 ->    overlapped_analyze(R);overlapped_analyze([{Addrs1,Tag1}|[{Addrs2,Tag2}|_]=R]) ->    io:format("% ~p overlaps ~p (~p,~p)~n", [Tag1,Tag2,Addrs1,Addrs2]),    overlapped_analyze(R);overlapped_analyze([_]) ->     io:format("% End of overlaps~n").chart_scan(Fd) ->    {ok,<<Heap:32/native,HighWater:32/native,Hend:32/native,	 OldHeap:32/native,OldHend:32/native>>} = file:read(Fd, 4*5),    chart_scan_1(Fd, 		 [{Heap,Heap,heap,0},		  {HighWater,HighWater,high_water,0},		  {Hend,Hend,hend,0},		  {OldHeap,OldHeap,old_heap,0},		  {OldHend,OldHend,old_hend,0}|chart_scan_hdr(Fd)]).chart_scan_hdr(Fd) ->    chart_scan_hdr_2(0, chart_scan_hdr_1(Fd)).chart_scan_hdr_1(Fd) ->    case file:read(Fd, 4*2) of	eof -> [];	{ok,<<0:32/native,0:32/native>>} -> [];	{ok,<<Start:32/native,Size:32/native>>} ->	    [{Start,Size}|chart_scan_hdr_1(Fd)]    end.chart_scan_hdr_2(_N, []) -> [];chart_scan_hdr_2(N, [{Start,End}|T]) when Start =< End ->    [{Start,Start,{heap_frag,N},0},{End,End,{heap_frag_end,N},0}     |chart_scan_hdr_2(N+1, T)].chart_scan_1(Fd, R) ->    case file:read(Fd, 4*4) of	eof ->	    io:format("% Analyzing heap chart...~n"),	    chart_analyze(lists:sort(R));	{ok,	 <<Addr:32/native,Size:32/native,Id:32/native,Depth:32/native>>} ->	    chart_scan_1(Fd, [{Addr,Addr+Size,Id,Depth}|R])    end.%-define(raw_chart_dump, 1).-ifdef(raw_chart_dump).chart_analyze([]) ->    io:format("% End of chart~n");chart_analyze([{S,E,Id,D}|R]) ->    io:format("% ~.16x-~.16x: ~w[~w]~n", 	      [S,"0x",E,"0x",Id,D]),    chart_analyze(R).-else.chart_analyze([]) ->     io:format("% ***Oops, was chart empty?***~n");chart_analyze([{S,_,Id,D}=X|R]) ->    io:format("% ~.16x: ~w[~w", [S,"0x",Id,D]),    chart_analyze_1(R, X).chart_analyze_1([{S,E,Id,D}=X|R], {S,E,Id,_}) ->    io:format(",~w", [D]),    chart_analyze_1(R, X);chart_analyze_1([{S,E,Id,D}=X|R], {S,E,_,_}) ->    io:format("],~w[~w", [Id,D]),    chart_analyze_1(R, X);chart_analyze_1(R, X) ->    io:format("]~n"),    chart_analyze_2(R, X).chart_analyze_2([], {_,E,_,_}) ->    io:format("% ~.16x: End of chart~n", [E,"0x"]);chart_analyze_2([{S,_,_,_}|_]=R, {_,E,_,_}) ->    if E == S ->	    chart_analyze(R);       E < S ->	    io:format("% ~.16x:~n", [E,"0x"]),	    chart_analyze(R);       true ->	    io:format("% ~.16x: ***Overlap***~n", [E,"0x"]),	    chart_analyze(R)    end.-endif.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?