crashdump_translate.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,132 行 · 第 1/3 页

ERL
1,132
字号
    case InputLine of	"Creation: " ++ CreationNl ->	    get_all_creations(Read,Write,(Creation--"\n")++" "++CreationNl);	"\n" ->	    write(Write,Creation);	PartOfLine when Truncated ->	    write(Write,Creation),	    truncated(PartOfLine);	Unexpected ->	    unexpected(Unexpected)    end.translate_links(Read,Write,Tag) ->    {Truncated,InputLine} = 	case line(Read) of	    {eof,InputLine0} -> {true,InputLine0};	    InputLine0 -> {false,InputLine0}	end,    case InputLine of	"------------------------\n" ->	    ok;	"\n" -> 	    ok;	"<" ++ _ = Line -> 	    {Proc1,Rest} = split(Line),	    {Text,Proc2} = 		case Rest of		    "linked to " ++ P -> % R7/R8			{"Remote link: ",P};		    "is linked to " ++ P -> % R9			{"Remote link: ",P};		    "is monitoring " ++ P -> % R9			{"Remote monitoring: ",P};		    "is being monitored by " ++ P -> % R9			{"Remotely monitored by: ",P};		    _ when Truncated ->			truncated(Line)		end,	    {Local,Remote} = 		case Proc1 of		    "<0."++ _ -> {Proc1,Proc2};		    _ -> {Proc2--"\n",[Proc1,"\n"]}		end,	    write(Write,[Text,Local," ",Remote]),	    translate_links(Read,Write,Tag);	Unexpected ->	    unexpected(Unexpected),	    translate_links(Read,Write,Tag)    end.translate_loaded_modules(Read,Write) ->    write(Write,"=loaded_modules\n"),	       case read_to_empty_line_reverse(Read) of	{eof,{Mods,_}} ->	    write(Write,["Current code: unknown\n",			 "Old code: unknown\n"]),	    translate_loaded_modules2(Write,Mods);	{all,{Mods,_}} ->	    translate_loaded_modules_totals(Read,Write,Mods)    end.translate_loaded_modules_totals(Read,Write,Mods) ->    {Truncated,InputLine} = 	case line(Read) of	    {eof,InputLine0} -> {true,InputLine0};	    InputLine0 -> {false,InputLine0}	end,    case InputLine of	"Totals. Current code = " ++ Rest1 ->	    Rest2 = copy_word(Write,Rest1,$ ,"Current code: "),	    case Rest2 of		"Old code = " ++ OldCodeNl ->		    write(Write,["Old code: ", OldCodeNl]),		    translate_loaded_modules2(Write,Mods);		PartOfLine when Truncated ->		    translate_loaded_modules2(Write,Mods),		    truncated(PartOfLine)	    end;	PartOfLine when Truncated ->	    translate_loaded_modules2(Write,Mods),	    truncated(PartOfLine);	Unexpected ->	    translate_loaded_modules2(Write,Mods),	    unexpected(Unexpected)    end.translate_loaded_modules2(Write,[Mod|Mods]) ->    {M,SizeNl} = split(Mod),    write(Write,["=mod:",M,"\n","Current size: ",SizeNl]),    translate_loaded_modules2(Write,Mods);translate_loaded_modules2(_Write,[]) ->    ok.    translate_funs(Read,Write) ->        {Truncated,InputLine} = 	case line(Read) of	    {eof,InputLine0} -> {true,InputLine0};	    InputLine0 -> {false,InputLine0}	end,    case InputLine of	"\n" ->	    ok; % all funs done	"module=" ++ Rest1 ->	    case copy_word(Write,Rest1,$ ,"=fun\nModule: ") of		"uniq=" ++ Rest2 ->		    case copy_word(Write,Rest2,$ ,"Uniq: ") of			"index=" ++ Rest3 ->			    IndexNl = Rest3 -- ":",			    write(Write,["Index: ", IndexNl]),			    translate_fun(Read,Write),			    translate_funs(Read,Write);			PartOfLine when Truncated ->			    truncated(PartOfLine)		    end;		PartOfLine when Truncated ->		    truncated(PartOfLine)	    end;	PartOfLine when Truncated ->	    truncated(PartOfLine);	Unexpected ->	    unexpected(Unexpected),	    translate_funs(Read,Write)    end.translate_fun(Read,Write) ->    {Truncated,InputLine} = 	case line(Read) of	    {eof,InputLine0} -> {true,InputLine0};	    InputLine0 -> {false,InputLine0}	end,    case InputLine of	"\n" ->	    ok; % next fun	"  address=" ++ AddressNl ->	    write(Write,["Address: ", AddressNl]),	    translate_fun(Read,Write);	"  native_address=" ++ NativeAddressNl ->	    write(Write,["Native_address: ",NativeAddressNl]),	    translate_fun(Read,Write);	"  refc=" ++ RefcNl ->	    write(Write,["Refc: ", RefcNl]),	    translate_fun(Read,Write);	PartOfLine when Truncated ->	    truncated(PartOfLine);	Unexpected ->	    unexpected(Unexpected),	    translate_fun(Read,Write)    end.translate_atoms(Read,Write) ->    StartPos = get_pos(Read),    jump_to_empty_line_or_eof(Read),    EndPos = get_pos(Read),    set_pos(Read,EndPos-2),    translate_atoms(Read,Write,StartPos,1),    set_pos(Read,EndPos).translate_atoms(Read,Write,StartPos,N) ->    {Atom,Pos} = read_line_backwards(Read,[]),    write(Write,[Atom,"\n"]),    if Pos<StartPos -> 	    write(Write,["=num_atoms:",integer_to_list(N),"\n"]);       true -> 	    translate_atoms(Read,Write,StartPos,N+1)    end.get_pos(Fd) ->    {ok,Pos0} = file:position(Fd,cur),    case get(chunk) of	undefined ->	    Pos0;	Bin ->	    Pos0 - size(Bin)    end.set_pos(Fd,Pos) ->    erase(chunk),    file:position(Fd,Pos).jump_to_empty_line_or_eof(Fd) ->        case line(Fd) of	"\n" ->	    ok;	{eof,_PartOfLine} ->	    ok;	_Line ->	    jump_to_empty_line_or_eof(Fd)    end.read_line_backwards(Fd,Line) ->    {CurPos,Str} = get_backwards_chunk(Fd),    read_line_backwards(Fd,CurPos,Str,Line).read_line_backwards(_Fd,Pos,[$\n|Str],Line) ->    put(chunk,Str),    put(pos,Pos-1),    {Line,Pos-1};read_line_backwards(Fd,Pos,[$\r|Str],Line) ->    read_line_backwards(Fd,Pos-1,Str,Line);read_line_backwards(Fd,Pos,[Char|Str],Line) ->    read_line_backwards(Fd,Pos-1,Str,[Char|Line]);read_line_backwards(Fd,_Pos,[],Line) ->    read_line_backwards(Fd,Line).    get_backwards_chunk(Fd) ->    case erase(chunk) of	undefined ->	    erase(pos),	    {ok,Pos} = file:position(Fd,cur),	    file:position(Fd,{cur,-?backwards_chunk_size}),	    {ok,Bin} =     file:read(Fd,?backwards_chunk_size),	    file:position(Fd,{cur,-?backwards_chunk_size}),	    {Pos,lists:reverse(binary_to_list(Bin))};	Str ->	    {erase(pos),Str}    end.    %%%-----------------------------------------------------------------%%% Common librarytruncated() ->    io:format("WARNING: Dump is truncated~n",[]),    throw({error,truncated}).truncated(NoText) when NoText=:="\n";NoText=:=""->    truncated();truncated(Text) ->    io:format("WARNING: Dump is truncated. Last text found:~n"	      "~s~n",[Text]),    throw({error,truncated}).unexpected(Text) ->    io:format("WARNING: Found unexpected text in dump:~n~p~n",[Text]).    read_to_empty_line_reverse(Read) ->    read_to_empty_line_reverse(Read,[],0).read_to_empty_line_reverse(Read,Acc,N) ->    case line(Read) of	"\n" ->	    {all,{Acc,N}};	{eof,PartOfLine} ->	    {eof,{[PartOfLine|Acc],N+1}}; % truncated file	Line ->	    read_to_empty_line_reverse(Read,[Line|Acc],N+1)    end.drop_to_empty_line(Read) ->    case line(Read) of	"\n" ->	    ok;	{eof,_PartOfLine} ->	    truncated();	_Line ->	    drop_to_empty_line(Read)    end.get_chunk(Fd) ->    case erase(chunk) of	undefined ->	    read(Fd);	Bin ->	    {ok,Bin}    end.read(Fd) ->    file:read(Fd,?chunk_size).write(Fd,Str) ->    file:write(Fd,list_to_binary(Str)).%% Read chunks from dump. Return one whole line or ?max_line_size%% number of characters.line(Fd) ->    case get_chunk(Fd) of	{ok,Bin} -> line(Fd,Bin,[],0);	eof -> truncated()    end.line(_Fd,Bin,Acc,?max_line_size) ->    put(chunk,Bin),    {part,lists:reverse(Acc)};line(_Fd,<<$\n:8,Bin/binary>>,Acc,_N) ->    put(chunk,Bin),    lists:reverse([$\n|Acc]);line(Fd,<<$\r:8,Bin/binary>>,Acc,N) ->    %% ignore "\r"    line(Fd,Bin,Acc,N);line(Fd,<<Char:8,Bin/binary>>,Acc,N) ->    line(Fd,Bin,[Char|Acc],N+1);line(Fd,<<>>,Acc,N) ->    case read(Fd) of	{ok,Bin} ->	    line(Fd,Bin,Acc,N+1);	eof ->	    {eof,lists:reverse(Acc)}    end.    %% Copy the rest of the started line from dump to translated file.write_rest_of_line(Read,Write) ->    case get_chunk(Read) of	{ok,Bin} -> write_rest_of_line(Read,Write,Bin,[]);	eof -> truncated()    end.write_rest_of_line(_Read,Write,<<$\n:8,Bin/binary>>,Acc) ->    put(chunk,Bin),    write(Write,lists:reverse([$\n|Acc]));write_rest_of_line(Read,Write,<<$\r:8,Bin/binary>>,Acc) ->    %% ignore "\r"    write_rest_of_line(Read,Write,Bin,Acc);write_rest_of_line(Read,Write,<<Char:8,Bin/binary>>,Acc) ->    write_rest_of_line(Read,Write,Bin,[Char|Acc]);write_rest_of_line(Read,Write,<<>>,Acc) ->    case read(Read) of	{ok,Bin} ->	    write(Write,lists:reverse(Acc)),	    write_rest_of_line(Read,Write,Bin,[]);	eof ->	    write(Write,lists:reverse(Acc)),	    truncated()    end.split(Str) -> % default separator is space    split($ ,Str,[]).split(Char,Str) ->    split(Char,Str,[]).split(Char,[Char|Str],Acc) -> % match Char    {lists:reverse(Acc),Str};split(_Char,[$\n|Str],Acc) -> % new line    {lists:reverse(Acc),Str};split(Char,[H|T],Acc) ->    split(Char,T,[H|Acc]);split(_Char,[],Acc) ->    {lists:reverse(Acc),[]}. % truncated linecopy_line(Read,Write) ->    copy_line(Read,Write,[]).copy_line(Read,Write,Heading) ->    case line(Read) of	{eof,PartOfLine} -> 	    write(Write,[Heading,PartOfLine]),	    truncated();	Line ->	    write(Write,[Heading,Line])    end.drop_line(Read) ->    case line(Read) of	{eof,_PartOfLine} ->	    truncated();	_Line ->	    ok    end.copy_word(Write,Line0,SplitChar,Heading) ->    case Line0 of	{eof,PartOfLine} -> 	    {Word,Rest} = split(SplitChar,PartOfLine),	    write(Write,[Heading,Word,"\n"]),	    case Rest of		[] -> truncated();		_ -> Rest	    end;	Line ->	    {Word,Rest} = split(SplitChar,Line),	    write(Write,[Heading,Word,"\n"]),	    Rest    end.	

⌨️ 快捷键说明

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