Skip to content

Commit

Permalink
Adding current snippets.
Browse files Browse the repository at this point in the history
  • Loading branch information
archaelus committed Jul 7, 2010
0 parents commit 831a035
Show file tree
Hide file tree
Showing 8 changed files with 359 additions and 0 deletions.
57 changes: 57 additions & 0 deletions dbg/trace_process_messages.erl
@@ -0,0 +1,57 @@
%% @copyright Geoff Cant 2009, 2010
%% @author Geoff Cant <nem@erlang.geek.nz>
%% @version {@vsn}, {@date} {@time}
%% @doc Erlang shell code to trace the messages for one process.
%% @end

dbg:stop_clear().
f(GL).
GL=group_leader().
f(TS).
TS = fun (TimeStamp = {_,_,Mics}) ->
{_,{H, M, Secs}} = calendar:now_to_local_time(TimeStamp),
Micros = Mics div 1000,
Seconds = Secs rem 60 + (Micros / 1000),
[H,M,Seconds];
(OtherTimestamp) ->
io:format("Help, help, got weird ts: ~p~n", [OtherTimestamp]),
[0,0,0]
end,
dbg:tracer(process,
{fun (Msg, State) ->
case Msg of
{trace, Pid, 'receive', TMsg} ->
[H,M,Seconds] = TS(erlang:now()),
io:format(GL, "~n~p:~p:~p ~p < ~p~n",
[H, M, Seconds, Pid, TMsg]);
{trace, Pid, 'send', TMsg, ToPid} ->
[H,M,Seconds] = TS(erlang:now()),
io:format(GL, "~n~p:~p:~p ~p > ~p: ~p~n",
[H, M, Seconds, Pid, ToPid, TMsg]);
{trace_ts, Pid, 'receive', TMsg, Timestamp} ->
[H,M,Seconds] = TS(Timestamp),
io:format(GL, "~n~p:~p:~pt ~p < ~p~n",
[H, M, Seconds, Pid, TMsg]);
{trace_ts, Pid, 'send', TMsg, ToPid, Timestamp} ->
[H,M,Seconds] = TS(Timestamp),
io:format(GL, "~n~p:~p:~pt ~p > ~p: ~p~n",
[H, M, Seconds, Pid, ToPid, TMsg]);
_Else ->
Timestamp = case element(tuple_size(Msg), Msg) of
{Mg,S,MS} when is_integer(Mg),
is_integer(S),
is_integer(MS) ->
{Mg, S, MS};
_Other -> erlang:now()
end,
[H,M,Seconds] = TS(Timestamp),
io:format(GL, "~n~p:~p:~p ~p~n",
[H, M, Seconds, Msg])

end,
State
end,
undefined}).

f(Trace).
Trace = fun(Pid) -> dbg:p(Pid, [m]) end.
66 changes: 66 additions & 0 deletions dbg/trace_to_file.erl
@@ -0,0 +1,66 @@
%% @copyright Geoff Cant 2009, 2010
%% @author Geoff Cant <nem@erlang.geek.nz>
%% @version {@vsn}, {@date} {@time}
%% @doc Erlang shell code to trace process messages to a wrap log.
%% @end

dbg:stop_clear().
f(GL).
GL=group_leader().
f(TS).
TS = fun (TimeStamp = {_,_,Mics}) ->
{_,{H, M, Secs}} = calendar:now_to_local_time(TimeStamp),
Micros = Mics div 1000,
Seconds = Secs rem 60 + (Micros / 1000),
[H,M,Seconds];
(OtherTimestamp) ->
io:format("Help, help, got weird ts: ~p~n", [OtherTimestamp]),
[0,0,0]
end.
f(Log).
{ok, Log} = disk_log:open([{name, dbg_log},
{file, "dbg_trace_log"},
{format, external},
{type, wrap},
{size, {1024*1024, 10}},
{mode, read_write}]).
dbg:tracer(process,
{fun (Msg, State) ->
S = case Msg of
{trace, Pid, 'receive', TMsg} ->
[H,M,Seconds] = TS(erlang:now()),
io_lib:format("~n~p:~p:~p ~p < ~p~n",
[H, M, Seconds, Pid, TMsg]);
{trace, Pid, 'send', TMsg, ToPid} ->
[H,M,Seconds] = TS(erlang:now()),
io_lib:format("~n~p:~p:~p ~p > ~p: ~p~n",
[H, M, Seconds, Pid, ToPid, TMsg]);
{trace_ts, Pid, 'receive', TMsg, Timestamp} ->
[H,M,Seconds] = TS(Timestamp),
io_lib:format("~n~p:~p:~pt ~p < ~p~n",
[H, M, Seconds, Pid, TMsg]);
{trace_ts, Pid, 'send', TMsg, ToPid, Timestamp} ->
[H,M,Seconds] = TS(Timestamp),
io_lib:format("~n~p:~p:~pt ~p > ~p: ~p~n",
[H, M, Seconds, Pid, ToPid, TMsg]);
_Else ->
Timestamp = case element(tuple_size(Msg), Msg) of
{Mg,Se,MS} when is_integer(Mg),
is_integer(Se),
is_integer(MS) ->
{Mg, Se, MS};
_Other -> erlang:now()
end,
[H,M,Seconds] = TS(Timestamp),
io_lib:format("~n~p:~p:~p ~p~n",
[H, M, Seconds, Msg])

end,
disk_log:balog(Log, iolist_to_binary(S)),
io:format(GL, ".", []),
State
end,
undefined}).

f(Trace).
Trace = fun(Pid) -> dbg:p(Pid, [m]) end.
11 changes: 11 additions & 0 deletions dump_source.erl
@@ -0,0 +1,11 @@
%% @copyright Geoff Cant 2009
%% @author Geoff Cant <nem@erlang.geek.nz>
%% @version {@vsn}, {@date} {@time}
%% @doc Reprints the source code of a module compiled with debug_info.
%% @end

PrintSrc = fun (Module) ->
{ok,{_,[{abstract_code,{_,AC}}]}} =
beam_lib:chunks(code:which(Module),[abstract_code]),
io:put_chars(erl_prettypr:format(erl_syntax:form_list(AC)))
end.
31 changes: 31 additions & 0 deletions exec_as_gen.erl
@@ -0,0 +1,31 @@
%% @copyright Geoff Cant 2010
%% @author Geoff Cant <nem@erlang.geek.nz>
%% @doc Erlang shell code to cause a gen* process to evaluate a fun.
%%
%% @license This code was translated from an ancient tome in the
%% Arkham university library (restricted section, 4th vault). As such,
%% use of this code is restricted to only those who see it as the
%% manifestly evil. Using this code under any circumstances other than in
%% dire need while debugging revokes your right to use, view, posess
%% said code.
%% @end

f(EvalAs).
EvalAs = fun (Pid, Fun) when is_function(Fun, 0) ->
Ref = make_ref(),
Caller = self(),
F = fun (nostate, {in, {hack,
_Invocation,
Ref}}, ProcState) ->
Caller ! {hack, <<"Ia! Ia! Cthulhu fhtagn">>, Ref,
catch Fun()},
done
end,
sys:install(Pid, {F,nostate}),
Pid ! {hack, <<"Ph'nglui mglw'nafh "
"Cthulhu R'lyeh wgah'nagl fhtan">>, Ref},
receive
{hack, TerrifyingResponse, Ref, Result} ->
{TerrifyingResponse, Result}
end
end.
45 changes: 45 additions & 0 deletions fun_rpc.erl
@@ -0,0 +1,45 @@
%% @copyright Geoff Cant 2009, 2010
%% @author Geoff Cant <nem@erlang.geek.nz>
%% @version {@vsn}, {@date} {@time}
%% @doc Erlang shell code to use funs with the rpc module.
%% @end

f(Multicall).
Multicall = fun (Fun) when is_function(Fun,0) ->
element(1, rpc:multicall(erlang, apply, [ Fun, [] ]))
end.

f(Ncall).
Ncall = fun (Nodes, Fun) when is_function(Fun,0) ->
element(1, rpc:multicall(Nodes, erlang, apply, [ Fun, [] ]))
end.

f(NodesCalled).
NodesCalled = fun (Name) ->
[N || N <- nodes(known),
lists:member(Name, string:tokens(atom_to_list(N), "@"))]
end.

f(Call).
Call = fun (Node, Fun) when is_function(Fun,0) ->
rpc:call(Node, erlang, apply, [ Fun, [] ])
end.

f(NamedCall).
NamedCall = fun (Name, Fun) ->
Ncall(NodesCalled(Name), Fun)
end.

f(ListDiff).
ListDiff = fun (L1, L2) ->
L1S = sets:from_list(L1),
L2S = sets:from_list(L2),
{sets:to_list(sets:subtract(L2S, L1S)),
sets:to_list(sets:subtract(L1S, L2S))}
end.

f(EvalDiff).
EvalDiff = fun (Node1, Node2, F) ->
ListDiff(Call(Node1, F),
Call(Node2, F))
end.
24 changes: 24 additions & 0 deletions mnesia_schema_symmetry.erl
@@ -0,0 +1,24 @@
%% @copyright Geoff Cant 2009
%% @author Geoff Cant <nem@erlang.geek.nz>
%% @version {@vsn}, {@date} {@time}
%% @doc Alter table copy types to match types on a specific node.
%% @end

f(Rebalance).
Rebalance = fun (IdealNode, OtherNodes) ->
Tables = rpc:call(IdealNode, mnesia, system_info, [tables]),
TableTypes = [{T, rpc:call(IdealNode, mnesia, table_info, [T, storage_type])}
|| T <- Tables],
[{Table, Type, [ case rpc:call(N, mnesia, table_info, [Table, storage_type]) of
Type -> N;
unknown ->
{atomic, ok} = mnesia:add_table_copy(Table, N, Type),
{added, N};
Other ->
{atomic, ok} = mnesia:change_table_copy_type(Table, N, Type),
{fixed, N}
end
|| N <- OtherNodes]}
|| {Table, Type} <- TableTypes]
end.

23 changes: 23 additions & 0 deletions otp/get_status.erl
@@ -0,0 +1,23 @@
%% @copyright Geoff Cant 2009
%% @author Geoff Cant <nem@erlang.geek.nz>
%% @version {@vsn}, {@date} {@time}
%% @doc Erlang shell code get the state of an OTP compliant process as
%% a proplist.
%% @end

f(GetStatus).
GetStatus = fun (Pid) ->
{status,_,
Module,
[[{'$ancestors',Ancestors},
{'$initial_call',MFA}],
_,_,Debug,
[_,
State,
Mod,infinity]]} = sys:get_status(Pid, timer:seconds(1)),
[{state, State},
Module,
{ancestors, Ancestors},
{initial_call, MFA},
{debug_flags, Debug}]
end.
102 changes: 102 additions & 0 deletions pg2.erl
@@ -0,0 +1,102 @@
%% @copyright Geoff Cant 2010
%% @author Geoff Cant <nem@erlang.geek.nz>
%% @version {@vsn}, {@date} {@time}
%% @doc Erlang shell code to fix pg2 tables.
%% @end

f(Pg2Groups).
Pg2Groups = fun () ->
ets:select(pg2_table,
ets:fun2ms(fun ({{group, G}}) -> G end))
end.
f(Pg2GroupMembers).
Pg2GroupMembers = fun (Groups) ->
[{G, lists:usort(ets:select(pg2_table,
ets:fun2ms(fun ({{pid, Pid, Gr}})
when G =:= Gr ->
Pid
end)))}
|| G <- Groups]
end.
f(Pg2Pids).
Pg2Pids = fun () ->
lists:usort(ets:select(pg2_table,
ets:fun2ms(fun ({{ref, R}, Pid}) when is_reference(R) -> Pid end)))
end.
f(Pg2PidGrps).
Pg2PidGrps = fun (Pids) ->
[{P, lists:usort(ets:select(pg2_table,
ets:fun2ms(fun ({{pid, P, Grp}}) -> Grp end)))}
|| P <- Pids]
end.
f(Pg2Refs).
Pg2Refs = fun () ->
lists:usort(ets:select(pg2_table,
ets:fun2ms(fun ({{ref, R}, Pid}) when is_reference(R) ->
{Pid, R}
end)))
end.
f(Correct).
Correct = fun () ->
Groups = Pg2Groups(),
GrpMembers = Pg2GroupMembers(Groups),
Pids = Pg2Pids(),
PidGrps = Pg2PidGrps(Pids),
Refs = Pg2Refs(),

lists:flatten([ [{{group, G}} || G <- Groups],
[{{ref, Ref}, Pid} || {Pid, Ref} <- Refs],
[{{ref, Pid}, Pid, Ref, length(proplists:get_value(Pid, PidGrps))}
|| {Pid, Ref} <- Refs],
[ [{{local_member, Grp, Pid}}
|| Grp <- Grps]
|| {Pid, Grps} <- PidGrps, node() =:= node(Pid)],
[ [[{{member, Grp, Pid}, 1},
{{pid, Pid, Grp}}]
|| Grp <- Grps]
|| {Pid, Grps} <- PidGrps]
])
end.

f(Diff).
Diff = fun () ->
Pg2List = ets:tab2list(pg2_table),
Pg2 = sets:from_list(Pg2List),
RightList = Correct(),
Right = sets:from_list(RightList),
[ case lists:keysearch(element(1, I), 1, Pg2List) of
{value, Wrong} ->
Pos = tuple_size(I),
{fixup, element(1,I), {Pos, element(Pos, I)}, element(Pos, Wrong)};
false ->
{insert, I}
end
|| I <- sets:to_list(sets:subtract(Right, Pg2))
]
end.


f(Diff2).
Diff2 = fun () ->
NewData = Correct(),
Right = sets:from_list(NewData),
Wrong = sets:from_list(ets:tab2list(pg2_table)),
sets:to_list(sets:subtract(Wrong, Right))
end.

f(Fixup).
Fixup = fun () ->
NewData = Correct(),
Right = sets:from_list(NewData),
Wrong = sets:from_list(ets:tab2list(pg2_table)),
Deletable = sets:to_list(sets:subtract(Wrong, Right)),
ets:insert(pg2_table, NewData)
end.

f(ListDiff).
ListDiff = fun (L1, L2) ->
L1S = sets:from_list(L1),
L2S = sets:from_list(L2),
{sets:to_list(sets:subtract(L2, L1)),
sets:to_list(sets:subtract(L1, L2))}
end.

0 comments on commit 831a035

Please sign in to comment.