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 + -
显示快捷键?