summaryrefslogtreecommitdiff
path: root/src/couch/src/couch_debug.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/couch/src/couch_debug.erl')
-rw-r--r--src/couch/src/couch_debug.erl161
1 files changed, 97 insertions, 64 deletions
diff --git a/src/couch/src/couch_debug.erl b/src/couch/src/couch_debug.erl
index 290d095bf..a2f4cdc87 100644
--- a/src/couch/src/couch_debug.erl
+++ b/src/couch/src/couch_debug.erl
@@ -49,6 +49,7 @@ help() ->
].
-spec help(Function :: atom()) -> ok.
+%% erlfmt-ignore
help(opened_files) ->
io:format("
opened_files()
@@ -205,9 +206,11 @@ help(Unknown) ->
[{port(), CouchFilePid :: pid(), Fd :: pid() | tuple(), FilePath :: string()}].
opened_files() ->
- Info = [couch_file_port_info(Port)
- || Port <- erlang:ports(),
- {name, "efile"} =:= erlang:port_info(Port, name)],
+ Info = [
+ couch_file_port_info(Port)
+ || Port <- erlang:ports(),
+ {name, "efile"} =:= erlang:port_info(Port, name)
+ ],
[I || I <- Info, is_tuple(I)].
couch_file_port_info(Port) ->
@@ -223,17 +226,22 @@ couch_file_port_info(Port) ->
[{port(), CouchFilePid :: pid(), Fd :: pid() | tuple(), FilePath :: string()}].
opened_files_by_regexp(FileRegExp) ->
{ok, RegExp} = re:compile(FileRegExp),
- lists:filter(fun({_Port, _Pid, _Fd, Path}) ->
- re:run(Path, RegExp) =/= nomatch
- end, couch_debug:opened_files()).
+ lists:filter(
+ fun({_Port, _Pid, _Fd, Path}) ->
+ re:run(Path, RegExp) =/= nomatch
+ end,
+ couch_debug:opened_files()
+ ).
-spec opened_files_contains(FileNameFragment :: iodata()) ->
[{port(), CouchFilePid :: pid(), Fd :: pid() | tuple(), FilePath :: string()}].
opened_files_contains(FileNameFragment) ->
- lists:filter(fun({_Port, _Pid, _Fd, Path}) ->
- string:str(Path, FileNameFragment) > 0
- end, couch_debug:opened_files()).
-
+ lists:filter(
+ fun({_Port, _Pid, _Fd, Path}) ->
+ string:str(Path, FileNameFragment) > 0
+ end,
+ couch_debug:opened_files()
+ ).
process_name(Pid) when is_pid(Pid) ->
Info = process_info(Pid, [registered_name, dictionary, initial_call]),
@@ -260,7 +268,8 @@ link_tree(RootPid, Info) ->
link_tree(RootPid, Info, Fun) ->
{_, Result} = link_tree(
- RootPid, [links | Info], gb_trees:empty(), 0, [RootPid], Fun),
+ RootPid, [links | Info], gb_trees:empty(), 0, [RootPid], Fun
+ ),
Result.
link_tree(RootPid, Info, Visited0, Pos, [Pid | Rest], Fun) ->
@@ -272,21 +281,23 @@ link_tree(RootPid, Info, Visited0, Pos, [Pid | Rest], Fun) ->
Visited1 = gb_trees:insert(Pid, Props, Visited0),
{links, Children} = lists:keyfind(links, 1, Props),
{Visited2, NewTree} = link_tree(
- RootPid, Info, Visited1, Pos + 1, Children, Fun),
+ RootPid, Info, Visited1, Pos + 1, Children, Fun
+ ),
{Visited3, Result} = link_tree(
- RootPid, Info, Visited2, Pos, Rest, Fun),
- {Visited3, [{Pos, {Pid, Fun(Pid, Props), NewTree}}] ++ Result};
+ RootPid, Info, Visited2, Pos, Rest, Fun
+ ),
+ {Visited3, [{Pos, {Pid, Fun(Pid, Props), NewTree}}] ++ Result};
none ->
Props = info(Pid, Info),
Visited1 = gb_trees:insert(Pid, Props, Visited0),
{Visited2, Result} = link_tree(
- RootPid, Info, Visited1, Pos, Rest, Fun),
+ RootPid, Info, Visited1, Pos, Rest, Fun
+ ),
{Visited2, [{Pos, {Pid, Fun(Pid, Props), []}}] ++ Result}
end;
link_tree(_RootPid, _Info, Visited, _Pos, [], _Fun) ->
{Visited, []}.
-
info(Pid, Info) when is_pid(Pid) ->
ValidProps = [
backtrace,
@@ -340,12 +351,16 @@ info(Port, Info) when is_port(Port) ->
port_info(Port, lists:usort(Validated)).
port_info(Port, Items) ->
- lists:foldl(fun(Item, Acc) ->
- case (catch erlang:port_info(Port, Item)) of
- {Item, _Value} = Info -> [Info | Acc];
- _Else -> Acc
- end
- end, [], Items).
+ lists:foldl(
+ fun(Item, Acc) ->
+ case (catch erlang:port_info(Port, Item)) of
+ {Item, _Value} = Info -> [Info | Acc];
+ _Else -> Acc
+ end
+ end,
+ [],
+ Items
+ ).
mapfold_tree([], Acc, _Fun) ->
{[], Acc};
@@ -380,8 +395,10 @@ print_linked_processes(Name) when is_atom(Name) ->
print_linked_processes(Pid) when is_pid(Pid) ->
Info = [reductions, message_queue_len, memory],
TableSpec = [
- {50, left, name}, {12, centre, reductions},
- {19, centre, message_queue_len}, {10, centre, memory}
+ {50, left, name},
+ {12, centre, reductions},
+ {19, centre, message_queue_len},
+ {10, centre, memory}
],
Tree = linked_processes_info(Pid, Info),
print_tree(Tree, TableSpec).
@@ -390,9 +407,12 @@ id("couch_file:init" ++ _, Pid, _Props) ->
case couch_file:process_info(Pid) of
{{file_descriptor, prim_file, {Port, Fd}}, FilePath} ->
term2str([
- term2str(Fd), ":",
- term2str(Port), ":",
- shorten_path(FilePath)]);
+ term2str(Fd),
+ ":",
+ term2str(Port),
+ ":",
+ shorten_path(FilePath)
+ ]);
undefined ->
""
end;
@@ -402,8 +422,11 @@ id(_IdStr, _Pid, _Props) ->
print_couch_index_server_processes() ->
Info = [reductions, message_queue_len, memory],
TableSpec = [
- {50, left, name}, {12, centre, reductions},
- {19, centre, message_queue_len}, {14, centre, memory}, {id}
+ {50, left, name},
+ {12, centre, reductions},
+ {19, centre, message_queue_len},
+ {14, centre, memory},
+ {id}
],
Tree = link_tree(whereis(couch_index_server), Info, fun(P, Props) ->
@@ -476,31 +499,40 @@ random_processes(Pids, 0) ->
random_processes(Acc, Depth) ->
Caller = self(),
Ref = make_ref(),
- Pid = case oneof([spawn_link, open_port]) of
- spawn_monitor ->
- {P, _} = spawn_monitor(fun() ->
- Caller ! {Ref, random_processes(Depth - 1)},
- receive looper -> ok end
- end),
- P;
- spawn ->
- spawn(fun() ->
- Caller ! {Ref, random_processes(Depth - 1)},
- receive looper -> ok end
- end);
- spawn_link ->
- spawn_link(fun() ->
- Caller ! {Ref, random_processes(Depth - 1)},
- receive looper -> ok end
- end);
- open_port ->
- spawn_link(fun() ->
- Port = erlang:open_port({spawn, "sleep 10"}, []),
- true = erlang:link(Port),
- Caller ! {Ref, random_processes(Depth - 1)},
- receive looper -> ok end
- end)
- end,
+ Pid =
+ case oneof([spawn_link, open_port]) of
+ spawn_monitor ->
+ {P, _} = spawn_monitor(fun() ->
+ Caller ! {Ref, random_processes(Depth - 1)},
+ receive
+ looper -> ok
+ end
+ end),
+ P;
+ spawn ->
+ spawn(fun() ->
+ Caller ! {Ref, random_processes(Depth - 1)},
+ receive
+ looper -> ok
+ end
+ end);
+ spawn_link ->
+ spawn_link(fun() ->
+ Caller ! {Ref, random_processes(Depth - 1)},
+ receive
+ looper -> ok
+ end
+ end);
+ open_port ->
+ spawn_link(fun() ->
+ Port = erlang:open_port({spawn, "sleep 10"}, []),
+ true = erlang:link(Port),
+ Caller ! {Ref, random_processes(Depth - 1)},
+ receive
+ looper -> ok
+ end
+ end)
+ end,
receive
{Ref, Pids} -> random_processes([Pid | Pids] ++ Acc, Depth - 1)
end.
@@ -508,7 +540,6 @@ random_processes(Acc, Depth) ->
oneof(Options) ->
lists:nth(couch_rand:uniform(length(Options)), Options).
-
tree() ->
[InitialPid | _] = Processes = random_processes(5),
{InitialPid, Processes, link_tree(InitialPid)}.
@@ -524,7 +555,8 @@ link_tree_test_() ->
"link_tree tests",
{
foreach,
- fun setup/0, fun teardown/1,
+ fun setup/0,
+ fun teardown/1,
[
fun should_have_same_shape/1,
fun should_include_extra_info/1
@@ -534,16 +566,16 @@ link_tree_test_() ->
should_have_same_shape({InitialPid, _Processes, Tree}) ->
?_test(begin
- InfoTree = linked_processes_info(InitialPid, []),
- ?assert(is_equal(InfoTree, Tree)),
- ok
+ InfoTree = linked_processes_info(InitialPid, []),
+ ?assert(is_equal(InfoTree, Tree)),
+ ok
end).
should_include_extra_info({InitialPid, _Processes, _Tree}) ->
Info = [reductions, message_queue_len, memory],
?_test(begin
- InfoTree = linked_processes_info(InitialPid, Info),
- map_tree(InfoTree, fun(Key, {_Id, Props}, _Pos) ->
+ InfoTree = linked_processes_info(InitialPid, Info),
+ map_tree(InfoTree, fun(Key, {_Id, Props}, _Pos) ->
case Key of
Pid when is_pid(Pid) ->
?assert(lists:keymember(reductions, 1, Props)),
@@ -553,11 +585,12 @@ should_include_extra_info({InitialPid, _Processes, _Tree}) ->
ok
end,
Props
- end),
- ok
+ end),
+ ok
end).
-is_equal([], []) -> true;
+is_equal([], []) ->
+ true;
is_equal([{Pos, {Pid, _, A}} | RestA], [{Pos, {Pid, _, B}} | RestB]) ->
case is_equal(RestA, RestB) of
false -> false;