📄 instrument.erl
字号:
%% ``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(instrument).-export([holes/1, mem_limits/1, memory_data/0, read_memory_data/1, sort/1, store_memory_data/1, sum_blocks/1, descr/1, type_descr/2, allocator_descr/2, class_descr/2, type_no_range/1, block_header_size/1, store_memory_status/1, read_memory_status/1, memory_status/1]).-define(OLD_INFO_SIZE, 32). %% (sizeof(mem_link) in pre R9C utils.c)-define(IHMARKER(H), element(1, H)).-define(VSN(H), element(2, H)).-define(INFO_SIZE(H), element(3, H)).-define(TYPEMAP(H), element(4, H)).-define(IHDR(H), is_tuple(H), ?IHMARKER(H) =:= instr_hdr).-define(IHDRVSN(H, V), ?IHDR(H), ?VSN(H) =:= V).memory_data() -> case catch erlang:system_info(allocated) of {'EXIT',{Error,_}} -> erlang:fault(Error, []); {'EXIT',Error} -> erlang:fault(Error, []); Res -> Res end.store_memory_data(File) -> case catch erlang:system_info({allocated, File}) of {'EXIT',{Error,_}} -> erlang:fault(Error, [File]); {'EXIT',Error} -> erlang:fault(Error, [File]); Res -> Res end.memory_status(Type) when is_atom(Type) -> case catch erlang:system_info({allocated, status, Type}) of {'EXIT',{Error,_}} -> erlang:fault(Error, [Type]); {'EXIT',Error} -> erlang:fault(Error, [Type]); Res -> Res end;memory_status(Type) -> erlang:fault(badarg, [Type]).store_memory_status(File) when is_list(File) -> case catch erlang:system_info({allocated, status, File}) of {'EXIT',{Error,_}} -> erlang:fault(Error, [File]); {'EXIT',Error} -> erlang:fault(Error, [File]); Res -> Res end;store_memory_status(File) -> erlang:fault(badarg, [File]).read_memory_data(File) when is_list(File) -> case file:consult(File) of {ok, [Hdr|MD]} when ?IHDR(Hdr) -> {Hdr, MD}; {ok, [{T,A,S,undefined}|_] = MD} when is_integer(T), is_integer(A), is_integer(S) -> {{instr_hdr, 1, ?OLD_INFO_SIZE}, MD}; {ok, [{T,A,S,{X,Y,Z}}|_] = MD} when is_integer(T), is_integer(A), is_integer(S), is_integer(X), is_integer(Y), is_integer(Z) -> {{instr_hdr, 1, ?OLD_INFO_SIZE}, MD}; {ok, _} -> {error, eio}; Error -> Error end;read_memory_data(File) -> erlang:fault(badarg, [File]).read_memory_status(File) when is_list(File) -> case file:consult(File) of {ok, [{instr_vsn, _}|Stat]} -> Stat; {ok, _} -> {error, eio}; Error -> Error end;read_memory_status(File) -> erlang:fault(badarg, [File]).holes({Hdr, MD}) when ?IHDR(Hdr) -> check_holes(?INFO_SIZE(Hdr), MD).check_holes(_ISz, []) -> ok;check_holes(ISz, [E | L]) -> check_holes(ISz, E, L).check_holes(_ISz, _E1, []) -> io:format("~n");check_holes(ISz, E1, [E2 | Rest]) -> check_hole(ISz, E1, E2), check_holes(ISz, E2, Rest).check_hole(ISz, {_,P1,S1,_}, {_,P2,_,_}) -> End = P1+S1, Hole = P2 - (End + ISz), if Hole =< 7 -> ok; true -> io:format(" ~p", [Hole]) end.sum_blocks({Hdr, L}) when ?IHDR(Hdr) -> lists:foldl(fun({_,_,S,_}, Sum) -> S+Sum end, 0, L).mem_limits({Hdr, L}) when ?IHDR(Hdr) -> {_, P1, _, _} = hd(L), {_, P2, S2, _} = lists:last(L), {P1, P2+S2}.sort({Hdr, MD}) when ?IHDR(Hdr) -> {Hdr, lists:keysort(2, MD)}.descr({Hdr, MD} = ID) when ?IHDR(Hdr) -> {Hdr, lists:map(fun ({TN, Addr, Sz, {0, N, S}}) -> {type_descr(ID, TN), Addr, Sz, list_to_pid("<0." ++ integer_to_list(N) ++ "." ++ integer_to_list(S) ++ ">")}; ({TN, Addr, Sz, undefined}) -> {type_descr(ID, TN), Addr, Sz, undefined} end, MD)}.block_header_size({Hdr, _}) when ?IHDR(Hdr) -> ?INFO_SIZE(Hdr).type_descr({Hdr, _}, TypeNo) when ?IHDRVSN(Hdr, 2), is_integer(TypeNo) -> case catch element(1, element(TypeNo, ?TYPEMAP(Hdr))) of {'EXIT', _} -> invalid_type; Type -> Type end;type_descr({Hdr, _}, TypeNo) when ?IHDRVSN(Hdr, 1), is_integer(TypeNo) -> type_string(TypeNo).allocator_descr({Hdr, _}, TypeNo) when ?IHDRVSN(Hdr, 2), is_integer(TypeNo) -> case catch element(2, element(TypeNo, ?TYPEMAP(Hdr))) of {'EXIT', _} -> invalid_type; Type -> Type end;allocator_descr({Hdr, _}, TypeNo) when ?IHDRVSN(Hdr, 1), is_integer(TypeNo) -> "unknown".class_descr({Hdr, _}, TypeNo) when ?IHDRVSN(Hdr, 2), is_integer(TypeNo) -> case catch element(3, element(TypeNo, ?TYPEMAP(Hdr))) of {'EXIT', _} -> invalid_type; Type -> Type end;class_descr({Hdr, _}, TypeNo) when ?IHDRVSN(Hdr, 1), is_integer(TypeNo) -> "unknown".type_no_range({Hdr, _}) when ?IHDRVSN(Hdr, 2) -> {1, size(?TYPEMAP(Hdr))};type_no_range({Hdr, _}) when ?IHDRVSN(Hdr, 1) -> {-1, 1000}.type_string(-1) -> "unknown";type_string(1) -> "atom text";type_string(11) -> "atom desc";type_string(2) -> "bignum (big_to_list)";type_string(31) -> "fixalloc";type_string(32) -> "unknown fixalloc block";type_string(33) -> "message buffer";type_string(34) -> "message link";type_string(4) -> "estack";type_string(40) -> "db table vec";type_string(41) -> "db tree select buffer";type_string(43) -> "db hash select buffer";type_string(44) -> "db hash select list";type_string(45) -> "db match prog stack";type_string(46) -> "db match prog heap data";type_string(47) -> "db temp buffer";type_string(48) -> "db error";type_string(49) -> "db error info";type_string(50) -> "db trans tab";type_string(51) -> "db segment";type_string(52) -> "db term";type_string(53) -> "db add_counter";type_string(54) -> "db segment table";type_string(55) -> "db table (fix)";type_string(56) -> "db bindings";type_string(57) -> "db counter";type_string(58) -> "db trace vec";type_string(59) -> "db fixed deletion";type_string(60) -> "binary (external.c)";type_string(61) -> "binary";type_string(62) -> "procbin (fix)";type_string(70) -> "driver alloc (io.c)";type_string(71) -> "binary (io.c)";type_string(72) -> "binary vec (io.c)";type_string(73) -> "binary vec 2 (io.c)";type_string(74) -> "io vec (io.c)";type_string(75) -> "io vec 2 (io.c)";type_string(76) -> "temp io buffer (io.c)";type_string(77) -> "temp io buffer 2 (io.c)";type_string(78) -> "line buffer (io.c)";type_string(8) -> "heap";type_string(801) -> "heap (1)";type_string(802) -> "heap (2)";type_string(803) -> "heap (3)";type_string(804) -> "heap (4)";type_string(805) -> "heap (5)";type_string(821) -> "heap fragment (1)";type_string(822) -> "heap fragment (2)";type_string(830) -> "sequential store buffer (for vectors)";type_string(91) -> "process table";type_string(92) -> "process desc";type_string(110) -> "hash buckets";type_string(111) -> "hash table";type_string(120) -> "index init";type_string(121) -> "index table";type_string(130) -> "temp buffer";type_string(140) -> "timer wheel";type_string(150) -> "distribution cache";type_string(151) -> "dmem";type_string(152) -> "distribution table";type_string(153) -> "distribution table buckets";type_string(154) -> "distribution table entry";type_string(155) -> "node table";type_string(156) -> "node table buckets";type_string(157) -> "node table entry";type_string(160) -> "port table";type_string(161) -> "driver entry";type_string(162) -> "port setup";type_string(163) -> "port wait";type_string(170) -> "module";type_string(171) -> "fundef";type_string(180) -> "file table";type_string(181) -> "driver table";type_string(182) -> "poll struct";type_string(190) -> "inet driver";type_string(200) -> "efile driver";type_string(210) -> "gc root set";type_string(220) -> "breakpoint data";type_string(230) -> "async queue";type_string(231) -> "async (exit)";type_string(232) -> "async (driver)";type_string(240) -> "bits buffer";type_string(241) -> "bits temp buffer";type_string(250) -> "modules (loader)";type_string(251) -> "code (loader)";type_string(252) -> "atom tab (loader)";type_string(253) -> "import tab (loader)";type_string(254) -> "export tab (loader)";type_string(255) -> "lable tab (loader)";type_string(256) -> "gen op (loader)";type_string(257) -> "gen op args (loader)";type_string(258) -> "gen op args 2 (loader)";type_string(259) -> "gen op args 3 (loader)";type_string(260) -> "lambdas (loader)";type_string(261) -> "temp int buffer (loader)";type_string(262) -> "temp heap (loader)";type_string(280) -> "dist ctrl msg buffer";type_string(281) -> "dist_buf";type_string(290) -> "call trace buffer";type_string(300) -> "bif timer rec";type_string(310) -> "argument registers";type_string(320) -> "compressed binary temp buffer";type_string(330) -> "term_to_binary temp buffer";type_string(340) -> "proc dict";type_string(350) -> "trace to port temp buffer";type_string(360) -> "lists subtract temp buffer";type_string(370) -> "link (lh)";type_string(380) -> "port call buffer";type_string(400) -> "definite_alloc block";type_string(_) -> invalid_type.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -