Skip to content

Instantly share code, notes, and snippets.

@jrwest
Created May 6, 2013 22:05
Show Gist options
  • Save jrwest/2999f8f217f1cbceca83 to your computer and use it in GitHub Desktop.
Save jrwest/2999f8f217f1cbceca83 to your computer and use it in GitHub Desktop.
-module(ktrace_fold).
-compile([export_all]).
-record(state, {
stack = [],
out_fd = undefined,
in_fd = undefined
}).
go(InPath, OutPath) when is_list(InPath) ->
{ok, InFd} = file:open(InPath, [read]),
{ok, OutFd} = file:open(OutPath, [append]),
go(#state{out_fd=OutFd,in_fd=InFd}).
go(State=#state{in_fd=InFd}) ->
case io:get_line(InFd, "") of
eof ->
file:close(InFd),
io:format("DONE~n"),
State;
{error, Desc} ->
io:format("error reading next line from file: ~p", [Desc]),
file:close(InFd),
State;
Line ->
go(do_line(State, Line))
end.
do_line(State,
[$*,$*,$* | _Line]) ->
io:format("start of trace~n"),
State;
do_line(State, Line) ->
{match, [Time,SpaceDepth,Mod,Fun,Arity]} =
re:run(Line, ["^\s*([0-9]+)?\s+\\|(\s+){(.+),(.+),(.+)}\s?$"], [{capture, all_but_first}]),
do_line(State,Line,Time,SpaceDepth,Mod,Fun,Arity).
do_line(State = #state{stack=CurrentStack=[{CurDepth,_}]},
_Line,{-1, 0},{_, Depth},_,_,_) when CurDepth >= Depth ->
PoppedStack = lists:dropwhile(drop_stack_fun(Depth), CurrentStack),
State#state{stack=PoppedStack};
do_line(State,_Line,{-1, 0},{_, _Depth},_,_,_) ->
State;
do_line(State = #state{stack=CurrentStack}, %=#state{out_fd=OutFd},
Line,
{TimeStart,TimeLen},
{_, Depth},
{ModStart,ModLen},
{FunStart,FunLen},
{ArityStart,ArityLen}) ->
TimeStr = string:substr(Line, TimeStart+1, TimeLen),
ModStr = string:substr(Line, ModStart+1, ModLen),
FunStr = string:substr(Line, FunStart+1, FunLen),
ArityStr = string:substr(Line,ArityStart+1, ArityLen),
case CurrentStack of
[] ->
CurrentDepth = undefined;
[{CD,_} | _] ->
CurrentDepth = CD
end,
FnStr = io_lib:format("~s-~s-~s", [ModStr, FunStr, ArityStr]),
case CurrentDepth >= Depth of
true when CurrentDepth =/= undefined->
PoppedStack = lists:dropwhile(drop_stack_fun(Depth), CurrentStack),
StackStr = stack_str(PoppedStack, FnStr),
io:format(State#state.out_fd, "~s ~s~n", [StackStr, TimeStr]),
State#state{stack=[{Depth,FnStr} | PoppedStack]};
_ ->
StackStr = stack_str(CurrentStack, FnStr),
io:format(State#state.out_fd,"~s ~s~n", [StackStr, TimeStr]),
State#state{stack=[{Depth,FnStr} | State#state.stack]}
end.
drop_stack_fun(MaxDepth) ->
fun({Depth, _}) when Depth >= MaxDepth -> true;
(_) -> false
end.
stack_str(Stack, FnStr) ->
stack_str(lists:reverse(Stack), FnStr, "").
stack_str([], FnStr, Acc) ->
Acc ++ FnStr;
stack_str([{_,Bot} | Rest], FnStr, Acc) ->
stack_str(Rest, FnStr, Acc ++ Bot ++ ";").
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment