1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1998-2017. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20%% Purpose : User interface to the Erlang debugger/interpreter. 21 22-module(i). 23 24-export([help/0,ia/1,ia/2,ia/3,ia/4,iaa/1,iaa/2, 25 ib/2,ib/3,ib/4,ibd/2,ibe/2,iba/3,ibc/3,ic/0,ii/1,ii/2, 26 il/0,im/0,ini/1,ini/2,inq/1,ip/0,ipb/0,ipb/1,iq/1, 27 ir/0,ir/1,ir/2,ir/3,iv/0,ist/1]). 28 29-import(io, [format/1,format/2]). 30-import(lists, [sort/1,foreach/2]). 31 32iv() -> 33 Vsn = string:slice(filename:basename(code:lib_dir(debugger)), 9), 34 list_to_atom(Vsn). 35 36%% ------------------------------------------- 37%% Start a new graphical monitor. 38%% A monitor displays status for all processes 39%% running interpreted modules. 40%% ------------------------------------------- 41 42im() -> 43 case debugger:start() of 44 {ok, Pid} -> 45 Pid; 46 {error, {already_started, Pid}} -> 47 Pid 48 end. 49 50%% ------------------------------------------- 51%% Add Module(s) as being interpreted. 52%% The actual paths will be searched for the 53%% corresponding source file(s) (Module.erl). 54%% Module(s) can be given with absolute path. 55%% ------------------------------------------- 56 57ii(Module) -> 58 int:i(Module). 59 60ii(Module,_Options) -> 61 int:i(Module). 62 63%% ------------------------------------------- 64%% Don't interpret module(s). The module will be 65%% removed from the set of modules interpreted. 66%% ------------------------------------------- 67 68iq(Module) -> 69 int:n(Module). 70 71%% ------------------------------------------- 72%% The corresponding functions for distributed 73%% erlang. The loading ... will be performed 74%% at all nodes using the broadcast facility. 75%% ------------------------------------------- 76 77ini(Module) -> 78 int:ni(Module). 79 80ini(Module,_Options) -> 81 int:ni(Module). 82 83inq(Module) -> 84 int:nn(Module). 85 86%% ------------------------------------------- 87%% Add a new break point at Line in Module. 88%% ------------------------------------------- 89 90ib(Module,Line) -> 91 int:break(Module,Line). 92 93%% ------------------------------------------- 94%% Break at entrance of specified function. 95%% Breaks is set at the first expression for 96%% all function clauses. 97%% ------------------------------------------- 98 99ib(Module,Function,Arity) -> 100 int:break_in(Module,Function,Arity). 101 102%% ------------------------------------------- 103%% Break at entrance of specified function. 104%% Breaks is set at the first expression for 105%% all function clauses. 106%% Associate the condition to the break. 107%% ------------------------------------------- 108 109ib(Module,Function,Arity,Cond) -> 110 Breaks1 = int:all_breaks(Module), 111 ok = int:break_in(Module,Function,Arity), 112 Breaks2 = int:all_breaks(Module), 113 lists:foreach(fun({Mod,Line}) -> int:test_at_break(Mod,Line,Cond) end, 114 Breaks2--Breaks1). 115 116%% ------------------------------------------- 117%% Make an existing break point inactive. 118%% ------------------------------------------- 119 120ibd(Mod,Line) -> 121 int:disable_break(Mod,Line). 122 123%% ------------------------------------------- 124%% Make an existing break point active. 125%% ------------------------------------------- 126 127ibe(Mod,Line) -> 128 int:enable_break(Mod,Line). 129 130%% ------------------------------------------- 131%% Set which status a break point shall have 132%% after it has been triggered the next time. 133%% Action is: enable, disable or delete. 134%% ------------------------------------------- 135 136iba(Mod,Line,Action) -> 137 int:action_at_break(Mod,Line,Action). 138 139%% ------------------------------------------- 140%% Add a conditional function to a break point. 141%% The given function shall have arity 1 and 142%% return either true or false. 143%% The argument of the given function is the 144%% current variable bindings of the process at 145%% the place of the break point, the bindings 146%% can be inspected using int:get_binding/2. 147 148%% Fnk == {Module,Function} 149%% Fnk == {Module,Function,ExtraArgs} 150%% ------------------------------------------- 151 152ibc(Mod,Line,Fnk) -> 153 int:test_at_break(Mod,Line,Fnk). 154 155%% ------------------------------------------- 156%% Delete break point. 157%% ------------------------------------------- 158 159ir(Module,Line) -> 160 int:delete_break(Module,Line). 161 162%% ------------------------------------------- 163%% Delete break at entrance of specified function. 164%% ------------------------------------------- 165 166ir(Module,Function,Arity) -> 167 int:del_break_in(Module,Function,Arity). 168 169%% ------------------------------------------- 170%% Delete all break points in module. 171%% ------------------------------------------- 172 173ir(Module) -> 174 int:no_break(Module). 175 176%% ------------------------------------------- 177%% Delete all break points (for all modules). 178%% ------------------------------------------- 179 180ir() -> 181 int:no_break(). 182 183%% ------------------------------------------- 184%% Print all interpreted modules. 185%% ------------------------------------------- 186 187il() -> 188 Mods = sort(int:interpreted()), 189 ilformat("Module","File"), 190 foreach(fun(Mod) -> ilformat(atom_to_list(Mod), get_file(Mod)) end, Mods). 191 192get_file(Mod) -> 193 case int:file(Mod) of 194 {error,not_loaded} -> % Marked interpreted but not loaded 195 "not loaded"; 196 File -> 197 File 198 end. 199 200ilformat(A1, A2) -> 201 format("~-20s ~ts\n", [A1,A2]). 202 203%% ------------------------------------------- 204%% Print all break points in modules. 205%% ------------------------------------------- 206 207ipb() -> 208 Bps = lists:keysort(1,int:all_breaks()), 209 bhformat("Module","Line","Status","Action","Condition"), 210 pb_print(Bps). 211 212ipb(Module) when is_atom(Module) -> 213 ipb1(Module); 214ipb(Module) when is_list(Module) -> 215 ipb1(list_to_atom(Module)). 216 217ipb1(Module) -> 218 Bps = lists:keysort(1,int:all_breaks(Module)), 219 bhformat("Module","Line","Status","Action","Condition"), 220 pb_print(Bps). 221 222pb_print([{{Mod,Line},[Status,Action,_,null|_]}|Bps]) -> 223 bformat(Mod,Line,Status,Action,""), 224 pb_print(Bps); 225pb_print([{{Mod,Line},[Status,Action,_,Cond|_]}|Bps]) -> 226 bformat(Mod,Line,Status,Action, 227 io_lib:format("~w",[Cond])), 228 pb_print(Bps); 229pb_print(_) -> 230 ok. 231 232bhformat(A1, A2, A3, A4, A5) -> 233 format("~-15s ~-9s ~-12s ~-12s ~-21s~n", [A1,A2,A3,A4,A5]). 234 235bformat(A1, A2, A3, A4, A5) -> 236 format("~-15w ~-9w ~-12w ~-12w ~-21s~n", [A1,A2,A3,A4,A5]). 237 238%% ------------------------------------------- 239%% Set the stack trace flag. 240%% Flag can be all (true), no_tail or false. 241%% ------------------------------------------- 242 243ist(Flag) -> 244 int:stack_trace(Flag), 245 true. 246 247%% ------------------------------------------- 248%% Set the automatic attachment flag. 249%% Flags can be init, break and exit. 250%% iaa(Flag) or ia([Flag,Flag,...]) 251%% ------------------------------------------- 252 253iaa(Flag) -> 254 iaa(Flag,{dbg_wx_trace,start,[]}). 255 256%% ------------------------------------------- 257%% Set the automatic attachment flag. 258%% Flags can be init, break and exit. 259%% Use given function to start up an attachment 260%% window. 261%% ia(Flag,Fnk) or ia([Flag,Flag,...],Fnk) 262%% where Fnk == {M,F} 263%% The given Fnk must have arity 3 or 4. 264%% ------------------------------------------- 265 266iaa(Flag,Fnk) -> 267 int:auto_attach(Flag,Fnk), 268 true. 269 270%% ------------------------------------------- 271%% Attach to process. 272%% ------------------------------------------- 273 274ia(Pid) -> 275 ia(Pid,{dbg_wx_trace,start}). 276 277%% ------------------------------------------- 278%% Attach to process. 279%% X,Y,Z is combind to a process identity. 280%% ------------------------------------------- 281 282ia(X,Y,Z) -> 283 ia(c:pid(X,Y,Z)). 284 285%% ------------------------------------------- 286%% Attach to process. 287%% Use Fnk == {M,F} as the attaching interface. 288%% ------------------------------------------- 289 290ia(Pid,Fnk) -> 291 case lists:keymember(Pid, 1, int:snapshot()) of 292 false -> no_proc; 293 true -> int:attach(Pid,Fnk) 294 end. 295 296ia(X,Y,Z,Fnk) -> 297 ia(c:pid(X,Y,Z),Fnk). 298 299%% ------------------------------------------- 300%% Print status for all interpreted processes. 301%% ------------------------------------------- 302 303ip() -> 304 Stats = int:snapshot(), 305 hformat("Pid","Initial Call","Status","Info"), 306 ip(Stats). 307 308ip([{Pid,{M,F,A},Status,{}}|Stats]) -> 309 hformat(io_lib:format("~w",[Pid]), 310 io_lib:format("~w:~tw/~w",[M,F,length(A)]), 311 io_lib:format("~w",[Status]), 312 ""), 313 ip(Stats); 314ip([{Pid,{M,F,A},Status,Info}|Stats]) -> 315 hformat(io_lib:format("~w",[Pid]), 316 io_lib:format("~w:~tw/~w",[M,F,length(A)]), 317 io_lib:format("~w",[Status]), 318 io_lib:format("~w",[Info])), 319 ip(Stats); 320ip([]) -> 321 ok. 322 323hformat(A1, A2, A3, A4) -> 324 format("~-12s ~-21ts ~-9s ~-21s~n", [A1,A2,A3,A4]). 325 326 327%% ------------------------------------------- 328%% Delete all terminated processes from the 329%% interpreter. 330%% ------------------------------------------- 331 332ic() -> 333 int:clear(). 334 335%% ------------------------------------------- 336%% Help printout 337%% ------------------------------------------- 338 339help() -> 340 format("iv() -- print the current version of the interpreter~n"), 341 format("im() -- pop up a monitor window~n"), 342 format("ii(Mod) -- interpret Mod(s) (or AbsMod(s))~n"), 343 format("ii(Mod,Op) -- interpret Mod(s) (or AbsMod(s))~n"), 344 format(" use Op as options (same as for compile)~n"), 345 format("iq(Mod) -- do not interpret Mod(s)~n"), 346 format("ini(Mod) -- ii/1 at all Erlang nodes~n"), 347 format("ini(Mod,Op) -- ii/2 at all Erlang nodes~n"), 348 format("inq(Mod) -- iq at all Erlang nodes~n"), 349 format("ib(Mod,Line) -- set a break point at Line in Mod~n"), 350 format("ib(M,F,Arity)-- set a break point in M:F/Arity~n"), 351 format("ibd(Mod,Line)-- disable the break point at Line in Mod~n"), 352 format("ibe(Mod,Line)-- enable the break point at Line in Mod~n"), 353 format("iba(M,L,Action)-- set a new action at break~n"), 354 format("ibc(M,L,Action)-- set a new condition for break~n"), 355 format("ir(Mod,Line) -- remove the break point at Line in Mod~n"), 356 format("ir(M,F,Arity)-- remove the break point in M:F/Arity~n"), 357 format("ir(Mod) -- remove all break points in Mod~n"), 358 format("ir() -- remove all existing break points~n"), 359 format("il() -- list all interpreted modules~n"), 360 format("ip() -- print status of all interpreted processes~n"), 361 format("ic() -- remove all terminated interpreted processes~n"), 362 format("ipb() -- list all break points~n"), 363 format("ipb(Mod) -- list all break points in Mod~n"), 364 format("ia(Pid) -- attach to Pid~n"), 365 format("ia(X,Y,Z) -- attach to pid(X,Y,Z)~n"), 366 format("ia(Pid,Fun) -- use own Fun = {M,F} as attach application~n"), 367 format("ia(X,Y,Z,Fun)-- use own Fun = {M,F} as attach application~n"), 368 format("iaa([Flag]) -- set automatic attach to process~n"), 369 format(" Flag is init,break and exit~n"), 370 format("iaa([Fl],Fun)-- use own Fun = {M,F} as attach application~n"), 371 format("ist(Flag) -- set stack trace flag~n"), 372 format(" Flag is all (true),no_tail or false~n"), 373 ok. 374 375 376