aboutsummaryrefslogtreecommitdiffstats
path: root/lib/debugger/src/i.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/debugger/src/i.erl')
-rw-r--r--lib/debugger/src/i.erl376
1 files changed, 376 insertions, 0 deletions
diff --git a/lib/debugger/src/i.erl b/lib/debugger/src/i.erl
new file mode 100644
index 0000000000..7c2fb22946
--- /dev/null
+++ b/lib/debugger/src/i.erl
@@ -0,0 +1,376 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%% Purpose : User interface to the Erlang debugger/interpreter.
+
+-module(i).
+
+-export([help/0,ia/1,ia/2,ia/3,ia/4,iaa/1,iaa/2,
+ ib/2,ib/3,ib/4,ibd/2,ibe/2,iba/3,ibc/3,ic/0,ii/1,ii/2,
+ il/0,im/0,ini/1,ini/2,inq/1,ip/0,ipb/0,ipb/1,iq/1,
+ ir/0,ir/1,ir/2,ir/3,iv/0,ist/1]).
+
+-import(io, [format/1,format/2]).
+-import(lists, [sort/1,foreach/2]).
+
+iv() ->
+ Vsn = string:substr(filename:basename(code:lib_dir(debugger)), 10),
+ list_to_atom(Vsn).
+
+
+%% -------------------------------------------
+%% Start a new graphical monitor.
+%% A monitor displays status for all processes
+%% running interpreted modules.
+%% -------------------------------------------
+
+im() ->
+ case debugger:start() of
+ {ok, Pid} ->
+ Pid;
+ {error, {already_started, Pid}} ->
+ Pid
+ end.
+
+%% -------------------------------------------
+%% Add Module(s) as being interpreted.
+%% The actual paths will be searched for the
+%% corresponding source file(s) (Module.erl).
+%% Module(s) can be given with absolute path.
+%% -------------------------------------------
+
+ii(Module) ->
+ int:i(Module).
+
+ii(Module,_Options) ->
+ int:i(Module).
+
+%% -------------------------------------------
+%% Don't interpret module(s). The module will be
+%% removed from the set of modules interpreted.
+%% -------------------------------------------
+
+iq(Module) ->
+ int:n(Module).
+
+%% -------------------------------------------
+%% The corresponding functions for distributed
+%% erlang. The loading ... will be performed
+%% at all nodes using the broadcast facility.
+%% -------------------------------------------
+
+ini(Module) ->
+ int:ni(Module).
+
+ini(Module,_Options) ->
+ int:ni(Module).
+
+inq(Module) ->
+ int:nn(Module).
+
+%% -------------------------------------------
+%% Add a new break point at Line in Module.
+%% -------------------------------------------
+
+ib(Module,Line) ->
+ int:break(Module,Line).
+
+%% -------------------------------------------
+%% Break at entrance of specified function.
+%% Breaks is set at the first expression for
+%% all function clauses.
+%% -------------------------------------------
+
+ib(Module,Function,Arity) ->
+ int:break_in(Module,Function,Arity).
+
+%% -------------------------------------------
+%% Break at entrance of specified function.
+%% Breaks is set at the first expression for
+%% all function clauses.
+%% Associate the condition to the break.
+%% -------------------------------------------
+
+ib(Module,Function,Arity,Cond) ->
+ Breaks1 = int:all_breaks(Module),
+ int:break_in(Module,Function,Arity),
+ Breaks2 = int:all_breaks(Module),
+ lists:foreach(fun({Mod,Line}) -> int:test_at_break(Mod,Line,Cond) end,
+ Breaks2--Breaks1).
+
+%% -------------------------------------------
+%% Make an existing break point inactive.
+%% -------------------------------------------
+
+ibd(Mod,Line) ->
+ int:disable_break(Mod,Line).
+
+%% -------------------------------------------
+%% Make an existing break point active.
+%% -------------------------------------------
+
+ibe(Mod,Line) ->
+ int:enable_break(Mod,Line).
+
+%% -------------------------------------------
+%% Set which status a break point shall have
+%% after it has been triggered the next time.
+%% Action is: enable, disable or delete.
+%% -------------------------------------------
+
+iba(Mod,Line,Action) ->
+ int:action_at_break(Mod,Line,Action).
+
+%% -------------------------------------------
+%% Add a conditional function to a break point.
+%% The given function shall have arity 1 and
+%% return either true or false.
+%% The argument of the given function is the
+%% current variable bindings of the process at
+%% the place of the break point, the bindings
+%% can be inspected using int:get_binding/2.
+
+%% Fnk == {Module,Function}
+%% Fnk == {Module,Function,ExtraArgs}
+%% -------------------------------------------
+
+ibc(Mod,Line,Fnk) ->
+ int:test_at_break(Mod,Line,Fnk).
+
+%% -------------------------------------------
+%% Delete break point.
+%% -------------------------------------------
+
+ir(Module,Line) ->
+ int:delete_break(Module,Line).
+
+%% -------------------------------------------
+%% Delete break at entrance of specified function.
+%% -------------------------------------------
+
+ir(Module,Function,Arity) ->
+ int:del_break_in(Module,Function,Arity).
+
+%% -------------------------------------------
+%% Delete all break points in module.
+%% -------------------------------------------
+
+ir(Module) ->
+ int:no_break(Module).
+
+%% -------------------------------------------
+%% Delete all break points (for all modules).
+%% -------------------------------------------
+
+ir() ->
+ int:no_break().
+
+%% -------------------------------------------
+%% Print all interpreted modules.
+%% -------------------------------------------
+
+il() ->
+ Mods = sort(int:interpreted()),
+ ilformat("Module","File"),
+ foreach(fun(Mod) -> ilformat(atom_to_list(Mod), get_file(Mod)) end, Mods).
+
+get_file(Mod) ->
+ case int:file(Mod) of
+ {error,not_loaded} -> % Marked interpreted but not loaded
+ "not loaded";
+ File ->
+ File
+ end.
+
+ilformat(A1, A2) ->
+ format("~-20s ~s\n", [A1,A2]).
+
+%% -------------------------------------------
+%% Print all break points in modules.
+%% -------------------------------------------
+
+ipb() ->
+ Bps = lists:keysort(1,int:all_breaks()),
+ bhformat("Module","Line","Status","Action","Condition"),
+ pb_print(Bps).
+
+ipb(Module) when is_atom(Module) ->
+ ipb1(Module);
+ipb(Module) when is_list(Module) ->
+ ipb1(list_to_atom(Module)).
+
+ipb1(Module) ->
+ Bps = lists:keysort(1,int:all_breaks(Module)),
+ bhformat("Module","Line","Status","Action","Condition"),
+ pb_print(Bps).
+
+pb_print([{{Mod,Line},[Status,Action,_,null|_]}|Bps]) ->
+ bformat(Mod,Line,Status,Action,""),
+ pb_print(Bps);
+pb_print([{{Mod,Line},[Status,Action,_,Cond|_]}|Bps]) ->
+ bformat(Mod,Line,Status,Action,
+ io_lib:format("~w",[Cond])),
+ pb_print(Bps);
+pb_print(_) ->
+ ok.
+
+bhformat(A1, A2, A3, A4, A5) ->
+ format("~-15s ~-9s ~-12s ~-12s ~-21s~n", [A1,A2,A3,A4,A5]).
+
+bformat(A1, A2, A3, A4, A5) ->
+ format("~-15w ~-9w ~-12w ~-12w ~-21s~n", [A1,A2,A3,A4,A5]).
+
+%% -------------------------------------------
+%% Set the stack trace flag.
+%% Flag can be all (true), no_tail or false.
+%% -------------------------------------------
+
+ist(Flag) ->
+ int:stack_trace(Flag),
+ true.
+
+%% -------------------------------------------
+%% Set the automatic attachment flag.
+%% Flags can be init, break and exit.
+%% iaa(Flag) or ia([Flag,Flag,...])
+%% -------------------------------------------
+
+iaa(Flag) ->
+ iaa(Flag,{dbg_ui_trace,start,[]}).
+
+%% -------------------------------------------
+%% Set the automatic attachment flag.
+%% Flags can be init, break and exit.
+%% Use given function to start up an attachment
+%% window.
+%% ia(Flag,Fnk) or ia([Flag,Flag,...],Fnk)
+%% where Fnk == {M,F}
+%% The given Fnk must have arity 3 or 4.
+%% -------------------------------------------
+
+iaa(Flag,Fnk) ->
+ int:auto_attach(Flag,Fnk),
+ true.
+
+%% -------------------------------------------
+%% Attach to process.
+%% -------------------------------------------
+
+ia(Pid) ->
+ ia(Pid,{dbg_ui_trace,start}).
+
+%% -------------------------------------------
+%% Attach to process.
+%% X,Y,Z is combind to a process identity.
+%% -------------------------------------------
+
+ia(X,Y,Z) ->
+ ia(c:pid(X,Y,Z)).
+
+%% -------------------------------------------
+%% Attach to process.
+%% Use Fnk == {M,F} as the attaching interface.
+%% -------------------------------------------
+
+ia(Pid,Fnk) ->
+ case lists:keysearch(Pid, 1, int:snapshot()) of
+ {value, _PidTuple} ->
+ int:attach(Pid,Fnk);
+ false -> no_proc
+ end.
+
+ia(X,Y,Z,Fnk) ->
+ ia(c:pid(X,Y,Z),Fnk).
+
+%% -------------------------------------------
+%% Print status for all interpreted processes.
+%% -------------------------------------------
+
+ip() ->
+ Stats = int:snapshot(),
+ hformat("Pid","Initial Call","Status","Info"),
+ ip(Stats).
+
+ip([{Pid,{M,F,A},Status,{}}|Stats]) ->
+ hformat(io_lib:format("~w",[Pid]),
+ io_lib:format("~p:~p/~p",[M,F,length(A)]),
+ io_lib:format("~w",[Status]),
+ ""),
+ ip(Stats);
+ip([{Pid,{M,F,A},Status,Info}|Stats]) ->
+ hformat(io_lib:format("~w",[Pid]),
+ io_lib:format("~p:~p/~p",[M,F,length(A)]),
+ io_lib:format("~w",[Status]),
+ io_lib:format("~w",[Info])),
+ ip(Stats);
+ip([]) ->
+ ok.
+
+hformat(A1, A2, A3, A4) ->
+ format("~-12s ~-21s ~-9s ~-21s~n", [A1,A2,A3,A4]).
+
+
+%% -------------------------------------------
+%% Delete all terminated processes from the
+%% interpreter.
+%% -------------------------------------------
+
+ic() ->
+ int:clear().
+
+%% -------------------------------------------
+%% Help printout
+%% -------------------------------------------
+
+help() ->
+ format("iv() -- print the current version of the interpreter~n"),
+ format("im() -- pop up a monitor window~n"),
+ format("ii(Mod) -- interpret Mod(s) (or AbsMod(s))~n"),
+ format("ii(Mod,Op) -- interpret Mod(s) (or AbsMod(s))~n"),
+ format(" use Op as options (same as for compile)~n"),
+ format("iq(Mod) -- do not interpret Mod(s)~n"),
+ format("ini(Mod) -- ii/1 at all Erlang nodes~n"),
+ format("ini(Mod,Op) -- ii/2 at all Erlang nodes~n"),
+ format("inq(Mod) -- iq at all Erlang nodes~n"),
+ format("ib(Mod,Line) -- set a break point at Line in Mod~n"),
+ format("ib(M,F,Arity)-- set a break point in M:F/Arity~n"),
+ format("ibd(Mod,Line)-- disable the break point at Line in Mod~n"),
+ format("ibe(Mod,Line)-- enable the break point at Line in Mod~n"),
+ format("iba(M,L,Action)-- set a new action at break~n"),
+ format("ibc(M,L,Action)-- set a new condition for break~n"),
+ format("ir(Mod,Line) -- remove the break point at Line in Mod~n"),
+ format("ir(M,F,Arity)-- remove the break point in M:F/Arity~n"),
+ format("ir(Mod) -- remove all break points in Mod~n"),
+ format("ir() -- remove all existing break points~n"),
+ format("il() -- list all interpreted modules~n"),
+ format("ip() -- print status of all interpreted processes~n"),
+ format("ic() -- remove all terminated interpreted processes~n"),
+ format("ipb() -- list all break points~n"),
+ format("ipb(Mod) -- list all break points in Mod~n"),
+ format("ia(Pid) -- attach to Pid~n"),
+ format("ia(X,Y,Z) -- attach to pid(X,Y,Z)~n"),
+ format("ia(Pid,Fun) -- use own Fun = {M,F} as attach application~n"),
+ format("ia(X,Y,Z,Fun)-- use own Fun = {M,F} as attach application~n"),
+ format("iaa([Flag]) -- set automatic attach to process~n"),
+ format(" Flag is init,break and exit~n"),
+ format("iaa([Fl],Fun)-- use own Fun = {M,F} as attach application~n"),
+ format("ist(Flag) -- set stack trace flag~n"),
+ format(" Flag is all (true),no_tail or false~n"),
+ ok.
+
+