diff options
Diffstat (limited to 'lib/pman/src')
| -rw-r--r-- | lib/pman/src/Makefile | 112 | ||||
| -rw-r--r-- | lib/pman/src/assert.hrl | 81 | ||||
| -rw-r--r-- | lib/pman/src/pman.app.src | 40 | ||||
| -rw-r--r-- | lib/pman/src/pman.appup.src | 19 | ||||
| -rw-r--r-- | lib/pman/src/pman.erl | 132 | ||||
| -rw-r--r-- | lib/pman/src/pman_buf.erl | 117 | ||||
| -rw-r--r-- | lib/pman/src/pman_buf.hrl | 29 | ||||
| -rw-r--r-- | lib/pman/src/pman_buf_buffer.erl | 102 | ||||
| -rw-r--r-- | lib/pman/src/pman_buf_converter.erl | 190 | ||||
| -rw-r--r-- | lib/pman/src/pman_buf_printer.erl | 91 | ||||
| -rw-r--r-- | lib/pman/src/pman_buf_utils.erl | 106 | ||||
| -rw-r--r-- | lib/pman/src/pman_main.erl | 789 | ||||
| -rw-r--r-- | lib/pman/src/pman_module_info.erl | 133 | ||||
| -rw-r--r-- | lib/pman/src/pman_options.erl | 395 | ||||
| -rw-r--r-- | lib/pman/src/pman_options.hrl | 34 | ||||
| -rw-r--r-- | lib/pman/src/pman_process.erl | 317 | ||||
| -rw-r--r-- | lib/pman/src/pman_relay.erl | 127 | ||||
| -rw-r--r-- | lib/pman/src/pman_relay_server.erl | 57 | ||||
| -rw-r--r-- | lib/pman/src/pman_shell.erl | 827 | ||||
| -rw-r--r-- | lib/pman/src/pman_tool.erl | 146 | ||||
| -rw-r--r-- | lib/pman/src/pman_win.erl | 677 | ||||
| -rw-r--r-- | lib/pman/src/pman_win.hrl | 39 | 
22 files changed, 0 insertions, 4560 deletions
| diff --git a/lib/pman/src/Makefile b/lib/pman/src/Makefile deleted file mode 100644 index eb0413bdbc..0000000000 --- a/lib/pman/src/Makefile +++ /dev/null @@ -1,112 +0,0 @@ -# -# %CopyrightBegin% -#  -# Copyright Ericsson AB 1996-2012. 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% -# -include $(ERL_TOP)/make/target.mk -include $(ERL_TOP)/make/$(TARGET)/otp.mk - -# ---------------------------------------------------- -# Application version -# ---------------------------------------------------- -include ../vsn.mk -VSN=$(PMAN_VSN) - -# ---------------------------------------------------- -# Release directory specification -# ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/lib/pman-$(VSN) - -# ---------------------------------------------------- -# Common Macros -# ---------------------------------------------------- - -MODULES= \ -	pman \ -	pman_main \ -	pman_shell \ -	pman_relay \ -	pman_relay_server \ -	pman_module_info \ -	pman_win \ -	pman_buf \ -	pman_buf_utils \ -	pman_buf_buffer \ -	pman_buf_converter \ -	pman_buf_printer \ -	pman_options \ -	pman_process \ -	pman_tool - -HRL_FILES= \ -	assert.hrl \ -	pman_buf.hrl \ -	pman_options.hrl \ -	pman_win.hrl - -ERL_FILES= $(MODULES:%=%.erl) - -TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET) - -APP_FILE = pman.app -APP_SRC = $(APP_FILE).src -APP_TARGET = $(EBIN)/$(APP_FILE) - -APPUP_FILE = pman.appup -APPUP_SRC = $(APPUP_FILE).src -APPUP_TARGET = $(EBIN)/$(APPUP_FILE) - -# ---------------------------------------------------- -# FLAGS -# ---------------------------------------------------- -ERL_COMPILE_FLAGS += +warn_obsolete_guard - -# ---------------------------------------------------- -# Targets -# ---------------------------------------------------- - -debug opt: $(TARGET_FILES)  - -clean: -	rm -f $(TARGET_FILES)  -	rm -f errs core *~ - -$(APP_TARGET): $(APP_SRC) ../vsn.mk -	$(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@ - -$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk -	$(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@ - -docs: - -# ---------------------------------------------------- -# Special Targets -# ---------------------------------------------------- - - -# ---------------------------------------------------- -# Release Target -# ----------------------------------------------------  -include $(ERL_TOP)/make/otp_release_targets.mk - -release_spec: opt -	$(INSTALL_DIR) "$(RELSYSDIR)/src" -	$(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(TOOLBOX_FILES) "$(RELSYSDIR)/src" -	$(INSTALL_DIR) "$(RELSYSDIR)/ebin" -	$(INSTALL_DATA) $(TARGET_FILES) $(TARGET_TOOLBOX_FILES) "$(RELSYSDIR)/ebin" - -release_docs_spec: - diff --git a/lib/pman/src/assert.hrl b/lib/pman/src/assert.hrl deleted file mode 100644 index ea3b68cd7c..0000000000 --- a/lib/pman/src/assert.hrl +++ /dev/null @@ -1,81 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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 : Assert macro - - -%% ?ASSERT/2 - will simply return true if the first argument evaluates to true -%%    otherwise it will exit and output (via the error logger) the -%%    second string -%% -%% Arguments: -%%   Flag	Expression that should evalueate to true or false -%%   String	String to return as a part of the exit reason as well -%%   		be to be sent to the error logger. -%% -%% Returns: -%%   true	If the Flag expression evaluates to true -%%    -%% Exits: -%%   {'EXIT', {assertion_failed, String}} -%%  		If the Flag expression evaluates to something other than -%%		true. -%% -%% Usage notes: -%%   Please note that the Flag argument must be a valid expression that  -%%   evaluates to true. -%% -%%   Also, avoid any side effects in the Flag, as everything performed -%%   within the scope of the ?ASSERT macro will not be present when -%%   the code is not compiled with the debug_on flag. -%% -%%   Side effects include the binding of a variable, sending of a -%%   message, etc. -%% - --ifdef(debug_on). --define(ASSERT(Flag, String), -	case Flag of -	    true -> -		true; -	   _ -> -		S2 = -		    lists:flatten( -		      io_lib:format( -			"=ASSERT====~nPid:~p, Module:~p, Line:~p~nTermination because assertion failed:~n~p", -			[self(),?MODULE, ?LINE,String])), -		error_logger:error_report(S2), -		exit({assertion_failed, String}) -	end -       ). - --define(ALWAYS_ASSERT(String), -	S2 = lists:flatten( -	       io_lib:format( -		 "=ASSERT====~nPid:~p, Module:~p, Line:~p~nTermination because of unconditional assert:~n~p", -		 [self(),?MODULE, ?LINE, String])), -	error_logger:error_report(S2), -	exit({always_assert, String}) -	). --else. --define(ASSERT(_Flag,_String), true). --define(ALWAYS_ASSERT(_String), true). --endif. - -				       - diff --git a/lib/pman/src/pman.app.src b/lib/pman/src/pman.app.src deleted file mode 100644 index cc32a17296..0000000000 --- a/lib/pman/src/pman.app.src +++ /dev/null @@ -1,40 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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% -%% -{application, pman, - [{description, "pman The Process Manager"}, -  {vsn, "%VSN%"}, -  {modules, [ -	     pman, -	     pman_buf, -	     pman_buf_buffer, -	     pman_buf_converter, -	     pman_buf_printer, -	     pman_buf_utils, -	     pman_main, -	     pman_module_info, -	     pman_options, -	     pman_process, -	     pman_relay, -	     pman_relay_server, -	     pman_shell, -	     pman_tool, -	     pman_win -	    ]}, -  {registered, []}, -  {applications, [kernel, stdlib]}]}. diff --git a/lib/pman/src/pman.appup.src b/lib/pman/src/pman.appup.src deleted file mode 100644 index 7a435e9b22..0000000000 --- a/lib/pman/src/pman.appup.src +++ /dev/null @@ -1,19 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 2001-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% -%% -{"%VSN%",[],[]}. diff --git a/lib/pman/src/pman.erl b/lib/pman/src/pman.erl deleted file mode 100644 index c8ea34b6b7..0000000000 --- a/lib/pman/src/pman.erl +++ /dev/null @@ -1,132 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1996-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 : Exported API to the Pman graphical tool -%%---------------------------------------------------------------------- - --module(pman). - - -%% --------------------------------------------------------------- -%% The user interface exports  -%% --------------------------------------------------------------- --export([start/0, -	 start_notimeout/0, -	 start/1, -	 start_notimeout/1, -	 proc/1, -	 proc/3]). - -%% --------------------------------------------------------------- - -%% Timeout for the startup function. -%% If no  {initialization_complete, Pid} message has been received -%% from the spawned init-function within ?STARTUP_TIMEOUT ms -%% the start-function will call exit(Reason). --define(STARTUP_TIMEOUT, 20000). - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% start/0 - -start() -> -    start([], ?STARTUP_TIMEOUT).		%Start w/o excluded modules - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% start_notimeout/0 - -start_notimeout() -> -    start([],infinity).				%Start w/o excluded modules - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% start/1 - -start(LIModuleExcluded) -> -    start(LIModuleExcluded, ?STARTUP_TIMEOUT). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% start_notimeout/1 - -start_notimeout(LIModuleExcluded) -> -    start(LIModuleExcluded, infinity). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% start/2 - Spawns the main Pman process, that will supervise -%%    all processes except those running code from the modules -%%    specified in LIModuleExcluded -%% - -start(LIModuleExcluded, Timeout) -> - -    OSModuleExcluded = ordsets:from_list(LIModuleExcluded), - -    PidInit = spawn(pman_main, init, [self(), OSModuleExcluded]), - -    %% Wait for a initialization completion message from -    %% the spawned process before returning its Pid. -    %%  - -    receive -	{initialization_complete, PidInit} -> -	    PidInit - -    %% (Conditional) Failure to start within the time limit will -    %% result in termination - -    after -	Timeout -> -	    exit(PidInit, kill), -	    exit({startup_timeout, ?MODULE}) -    end. - - - -%% --------------------------------------------------------------- -%% If we want to trace just one process, we can call proc, giving it -%% either the Pid, or the registered name, (Global or local). -%% -%% (???) -%% Note that this function must not be used internally to create a -%% trace window, since it is assumed that it is started from any -%% process (esp. the shell) it will not have any supervisor process -%% that shall be notified about it's exit/death. -%% -%% Returns: Trace loop Pid|udefined - -%% --------------------------------------------------------------- - - -proc(undefined) -> -    exit(undefined); - -proc({shell,P}) when is_pid(P) -> -    pman_shell:start({{shell,P},self()}); - -proc(P) when is_atom(P) -> -    proc(whereis(P)); - -proc({global, N}) -> -    proc(global:whereis_name(N)); - -proc(P) when is_pid(P) -> -    pman_shell:start({P,self()}). - -proc(X,Y,Z) -> -    proc(c:pid(X,Y,Z)). - diff --git a/lib/pman/src/pman_buf.erl b/lib/pman/src/pman_buf.erl deleted file mode 100644 index d56ce184fa..0000000000 --- a/lib/pman/src/pman_buf.erl +++ /dev/null @@ -1,117 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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 : This module is the exported interface to the buffering mechanism -%%%           used in PMAN to prevent the trace output to congest -%%%           the system. -%%% -%%%           This module depends on the modules (direct or indirectly): -%%%               pman_buf.hrl -%%%               pman_buf_utils.erl -%%%               pman_buf_buffer.erl -%%%               pman_buf_converter.erl -%%%               pman_buf_printer.erl -%%% -%%%---------------------------------------------------------------------- - --module(pman_buf). - -%%-compile(export_all). --export([start/2,clear/3]). - - --include("pman_buf.hrl"). - - -%% The buffering mechanism consists of three processes that  -%% work in a chain to prevent the process monitor from congesting -%% output mechanism. -%%  -%% Messages are buffered in the CONVERTER process before they are sent to -%% to the BUFFER process where they are formatted before they are finally -%% sent to either a file or the PRINTER process. The printer process -%% outputs the messages in the graphical user interface. -%% -%% -%% -%%     	   -->   CONVERTER  -->   BUFFER    --> PRINTER --> gui -%%                                 | -%%                                 | -%%                                 | -%%                                 V -%% -%%                                file -%% - - - - - -%% ---------------------------------------------------------------- -%% The amount of data produced by a trace message may be large, and -%% cause the run time system to run out of memory. To avoid this, -%% the task of storing, cutting buffers, formating data and printing -%% it is performed by three processes: The buffer, the converter and  -%% the printer. -%% -%% The converter accepts the raw data, a list -%% of {trace,Msg} tuples. Having max priority, it assures that the -%% amount of raw data stored never excedes ?BUFF_SIZE messages. -%% (With the exception of the last batch received, which assures that -%% the last trace message printed is never a buffer cut message.) -%% Whenever there is space available in the buffer process, (The -%% Buffer process stores max. ?BUFF_SIZE converted messages), -%% the buffer asks for more unconverted messages, and ?PRINT_LEN messages  -%% are sent. They are converted by the buffer, and added to the list -%% of messages to be sent.  - -%% The printer process requests formatted messages from the buffer, -%% and in chuncs of ?MAX_OUTPUT sends them to the buffer. If traces -%% are to be dumped on file, due to the max priority, such is handled -%% in the converter, and buffers are not cut. -%% - - -%% --------------------------------------------------------------- -%% Initializes the buffering mechanism, which consist of three -%% processes, each involved with a phase of the formattation and -%% output of data to the process windows. - -start(Editor, FileName) -> -    Buffer_Pid = spawn_link(pman_buf_buffer,init,[Editor]), -    Converter_Pid = -	spawn_link(pman_buf_converter,init,[Buffer_Pid, FileName]), -    Buffer_Pid!{converter_pid, Converter_Pid}, -    #buffer{converter=Converter_Pid,buffer=Buffer_Pid}. - - - -%% --------------------------------------------------------------- -%% Kills the converter and the clears the buffer with formated data -%% starting a new converter. - -clear(Buff,String, FileName) -> -    exit(Buff#buffer.converter,win_killed), -    Converter_Pid=spawn_link(pman_buf_converter,init,[Buff#buffer.buffer, -						      FileName]), -    Buff#buffer.buffer!{clear,String,Converter_Pid }, -    Buff#buffer{converter = Converter_Pid}. - - - diff --git a/lib/pman/src/pman_buf.hrl b/lib/pman/src/pman_buf.hrl deleted file mode 100644 index 3f25dcc5f0..0000000000 --- a/lib/pman/src/pman_buf.hrl +++ /dev/null @@ -1,29 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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% -%% - -%%-compile(export_all). -%%-export([Function/Arity, ...]). - --define(BUFF_SIZE,1000). --define(EDITOR_MAX,10000). --define(PRINT_LEN,50). --define(MAX_OUTPUT,5000). - - --record(buffer,{buffer,converter}). diff --git a/lib/pman/src/pman_buf_buffer.erl b/lib/pman/src/pman_buf_buffer.erl deleted file mode 100644 index ad92eb1f3e..0000000000 --- a/lib/pman/src/pman_buf_buffer.erl +++ /dev/null @@ -1,102 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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 : The purpouse of the buffer process is to take -%%%           care of the data that is received by the converter -%%%           process and pass it on to the printer process in chunks -%%%	      that can be handled. -%%% -%%%           This module is a part of the buffering system, and -%%%           should not be used except through the API defined -%%%           in the pman_buf module. -%%% -%%%---------------------------------------------------------------------- - --module(pman_buf_buffer). - -%%-compile(export_all). --export([init/1]). - --include("pman_buf.hrl"). - - - -%% -%% Initialization function for the buffer process. -%% To be started with spawn from the calling process. -%% - -init(Editor) -> -    Printer_pid = spawn_link(pman_buf_printer,init,[Editor,self()]), -    receive -	{converter_pid,Pid} -> -	    Pid!{buffer,accept}, -	    buffer_loop([],0,0,Printer_pid,Pid) -    end. - - - -%% -%% Receive loop for the buffer process. -%% - -buffer_loop(Buffer,Size,Acc,Printer,Converter) -> -    receive -	{save_buffer,Name} -> -	    Printer!{save_buffer,Name}, -	    buffer_loop(Buffer,Size,Acc,Printer,Converter); -	{raw,Raw,Length} ->   %%output to editor -	    New_Size = Size + Length, -	    if New_Size < ?BUFF_SIZE -> -		    Converter!{buffer,accept}; -	       true -> ok -	    end, -	    Print = lists:map(fun(X) -> pman_buf_utils:textformat(X) end, Raw), -	    New_Buff = lists:append(Buffer,Print), -	    buffer_loop(New_Buff,New_Size,Acc,Printer,Converter); -	{clear,Text,N_Converter} -> -	    Converter!{buffer,accept}, -	    Printer!clear, -	    buffer_loop([Text],1,1,Printer,N_Converter); -	{printer,send} when Buffer /= [] -> -	     if -		 Acc  > ?EDITOR_MAX -> -		     Printer!clear, -		     Printer !{buffer,"Cleared Buffer due to Size\n\n"}, -		     buffer_loop(Buffer,Size,1,Printer,Converter); -		 true -> -		     {Length,Rest,Print} = pman_buf_utils:split(Buffer, -								?PRINT_LEN, -								0, -								[]), -		     Printer ! {buffer,Print}, -		     New_Size = Size - Length, -		     if New_Size < ?BUFF_SIZE -> -			     Converter!{buffer,accept}; -			true -> ok -		     end, -		     buffer_loop(Rest,New_Size,Acc+Length,Printer,Converter) -	     end; -	{converter,file} -> -	    Converter!{buffer,Buffer}, -	    self()!{raw,[to_file],1}, -	    buffer_loop([],0,Acc,Printer,Converter) -    end. - - diff --git a/lib/pman/src/pman_buf_converter.erl b/lib/pman/src/pman_buf_converter.erl deleted file mode 100644 index c8b3fe37aa..0000000000 --- a/lib/pman/src/pman_buf_converter.erl +++ /dev/null @@ -1,190 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-2012. 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 : The purpouse of the converter process is to take -%%           care of the raw data that is received by the tracing -%%           process (a pman_shell process) and pass it on to -%%           the buffer process in chunks that can be handled. -%% -%%           This module is a part of the buffering system, and -%%           should not be used except through the API defined -%%           in the pman_buf module. -%% -%%---------------------------------------------------------------------- - --module(pman_buf_converter). --compile([{nowarn_deprecated_function,{gs,start,0}}]). - -%%-compile(export_all). --export([init/2]). - --include("pman_buf.hrl"). - - -%% --------------------------------------------------------------- -%% Starts the process which received the raw data from the debugger,  -%% cuts and forwards it to the buffer in smaller chunks. High priority -%% to avoid large message queues waiting to be processed. - -init(Buffer_Pid, FileName) -> -    process_flag(priority, max), -    converter_loop(Buffer_Pid,[],0,true,[], FileName). -     -converter_loop(Buffer_Pid,Raw,Size,State,Last, FileName) -> -    receive -	{file,Shell} -> -	    case init_file(lists:append(Raw,Last), -			   FileName, -			   Shell, -			   Buffer_Pid) of -		true  -> converter_loop(Buffer_Pid, -					[to_buffer], -					1, -					State, -					[], -					FileName); -		false -> converter_loop(Buffer_Pid, -					Raw, -					Size, -					State, -					Last, -					FileName) -	    end; -	{raw,Trace} -> -	    {New_Raw,New_Size,New_State,New_Last} = -		converter_data(Trace, Buffer_Pid, Raw, Size, State, Last), -	    converter_loop(Buffer_Pid, -			   New_Raw, -			   New_Size, -			   New_State, -			   New_Last, -			   FileName); -        {buffer,accept} when Raw /= [] -> -	    {Length,Rest,Print} = pman_buf_utils:split(Raw,?PRINT_LEN,0,[]), -	    Buffer_Pid!{raw,Print,Length}, -	    converter_loop(Buffer_Pid,Rest,Size-Length,false,Last,FileName); -	{buffer,accept} when Last /= [] -> -	    {New_Raw,New_Size,New_State,New_Last} = -		converter_data(Last,Buffer_Pid,Raw,Size,true,[]), -	    converter_loop(Buffer_Pid, -			   New_Raw, -			   New_Size, -			   New_State, -			   New_Last, -			   FileName); -	{buffer,accept} -> -	    converter_loop(Buffer_Pid,Raw,Size,true,Last, FileName);   -	{clear,Str} -> -	    Buffer_Pid!{clear,Str}, -	    converter_loop(Buffer_Pid,[],0,State,Last,FileName) -    end. - -converter_data(Trace,Buffer_Pid,Raw,Size,State,Last) -> -    if -	?BUFF_SIZE - Size > 0 -> -	    {Len,Rest,New_Trace} = pman_buf_utils:split(Trace, -							?BUFF_SIZE-Size, -							0,[]), -	    {New_Raw,New_Last} = -		case Rest of -		    [] -> -			{lists:append(Raw,New_Trace),Last}; -		    [_|_] -> -			case Last of -			    [] -> -				{lists:append(Raw,New_Trace),Rest}; -			    _ ->{lists:concat([Raw,New_Trace,[cut_buffer]]), -				 Rest} -			end -		end, -	    case State of true -> -		    {Length,Cut_Raw,Print} = pman_buf_utils:split(New_Raw, -								  ?PRINT_LEN, -								  0,[]), -		    Buffer_Pid!{raw,Print,Length}, -		    {Cut_Raw,Size-Length,false,New_Last}; -		_ -> -		    {New_Raw,Size+Len,false,New_Last} -	    end; -	true -> -	    {Raw,Size,State,Trace} -    end. - - -%% --------------------------------------------------------------- -%% Initializes the environment for saving the trace to file. The  -%% actual saving is taken care of by the buffer process. - -init_file(Raw,FileName, Name,Buffer_Pid) -> -     case open_file(FileName, Name) of -	 {false,T} -> -	     pman_win:msg_win(T), -	     false; -	 {File,T} -> -	     Buffer_Pid!{converter,file}, -	     pman_win:dialog_window(gs:start(),T), -	     save_loop_init(File,Raw) -     end. - -open_file(FileName, _Shell) -> -%%    L = "pman_trace." ++ Shell, -    case file:open(FileName, [read,write]) of -	{error, _} ->  -	    Str = "ERROR: Could not create_file\n" ++ FileName, -	    {false,Str}; -	{ok,File} -> -	    file:position(File, {eof, 0}), -	    Str1 = " Appending trace log to file\n" ++ FileName, -	    {File,Str1} -    end. - - -save_loop_init(Fd,Raw) -> -    {Date, Time} = calendar:local_time(), -    {Year, Month, Day} = Date, -    {Hour, Minute, Second} = Time, -    io:format(Fd,"%%% ~n",[]), -    io:format(Fd,"%%% Trace output~n",[]), -    io:format(Fd,"%%% Started at ~4p-~2p-~2p ~2p:~2p:~2p~n", -	      [Year, Month, Day, -	       Hour, Minute, Second -	      ]), -    io:format(Fd,"%%% ~n~n",[]), - -    Print = lists:map(fun(X) -> pman_buf_utils:textformat(X) end, Raw), -    receive -	{buffer,Text} when is_list(Text) -> -	    io:format(Fd,Text,[]), -	    io:format(Fd,Print,[]), -	    save_loop(Fd) -    end. - -save_loop(Fd) -> -    receive -	{raw,Raw} -> -	    Print = lists:map(fun(X) -> pman_buf_utils:textformat(X) end, Raw), -	    io:format(Fd,Print,[]), -	    save_loop(Fd); -	buffer -> true -    end. - - - - - diff --git a/lib/pman/src/pman_buf_printer.erl b/lib/pman/src/pman_buf_printer.erl deleted file mode 100644 index 3284c57559..0000000000 --- a/lib/pman/src/pman_buf_printer.erl +++ /dev/null @@ -1,91 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-2012. 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% -%% - --module(pman_buf_printer). --compile([{nowarn_deprecated_function,{gs,config,2}}, -          {nowarn_deprecated_function,{gs,start,0}}]). - -%%-compile(export_all). --export([init/2]). - - --include("pman_buf.hrl"). - -%% --------------------------------------------------------------- -%% Starts the part of the buffer which regulates the flow of data to -%% be printed in the pid editors - - -init(Editor,Buffer_pid) -> -    Buffer_pid!{printer,send}, -    printer_loop(Editor,Buffer_pid). -     -printer_loop(Editor,Buffer_pid)-> -    receive -	{save_buffer,Name} -> -	    gs:config(Editor,{save,Name}), -	    TT = "Buffer saved in file\n" ++ Name, -	    pman_win:dialog_window(gs:start(),TT), -	    printer_loop(Editor,Buffer_pid); -	{buffer,Trace} -> -	    case lists:flatlength(Trace) of -		Len when Len > ?MAX_OUTPUT -> -		    printer_long(lists:flatten(Trace),Editor), -		    Buffer_pid!{printer,send}, -		    printer_loop(Editor,Buffer_pid); -		_ -> -		    		    Buffer_pid!{printer,send}, -		    print_trace(Editor,Trace), -		    printer_loop(Editor,Buffer_pid) -	    end; -	clear -> -	    pman_win:configeditor(Editor, [{enable, true}]), -	    pman_win:configeditor(Editor,clear), -	    pman_win:configeditor(Editor, [{enable, false}]), -	    printer_loop(Editor,Buffer_pid); -	_Other -> -	    printer_loop(Editor,Buffer_pid) -    end. - -printer_long([],_) -> ok; -printer_long(Trace,Editor) -> -    receive -	clear -> -	    pman_win:configeditor(Editor, [{enable, true}]), -	    pman_win:configeditor(Editor,clear), -	    pman_win:configeditor(Editor, [{enable, false}]) -    after 0 -> -	    {_Length,Rest,Print} = pman_buf_utils:split(Trace, -							?MAX_OUTPUT, -							0, -							[]), -	    print_trace(Editor,Print), -	    printer_long(Rest,Editor) -    end. - - - -%% --------------------------------------------------------------- -%% Function which print trace messages on the window  -%% --------------------------------------------------------------- - -print_trace(Editor,Elements) -> -    pman_win:configeditor(Editor, [{enable, true}]), -    pman_win:configeditor(Editor, [{insert, {'end',Elements}}]), -    pman_win:configeditor(Editor, [{enable, false}]).	 diff --git a/lib/pman/src/pman_buf_utils.erl b/lib/pman/src/pman_buf_utils.erl deleted file mode 100644 index af3982665e..0000000000 --- a/lib/pman/src/pman_buf_utils.erl +++ /dev/null @@ -1,106 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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% -%% - --module(pman_buf_utils). - -%%-compile(export_all). --export([textformat/1, split/4]). - - -%% --------------------------------------------------------------- -%% Funtion which format the trace message -%% --------------------------------------------------------------- - -textformat(died) -> -    "\n\nProcess died\n"; -textformat({died, Pid}) -> -    io_lib:format("~w Process died.~n",[Pid]); -textformat({shell_died, Old, New}) -> -    io_lib:format("~w Shell Process died. Restarted as ~w~n~n",[Old,New]); - - -textformat(to_buffer) -> -    "\nAppending trace log to Buffer\n\n"; -textformat(to_file) -> -    "\nAppending trace log to File\n\n"; -textformat(cut_buffer) -> -    "\nCUT BUFFER\n\n"; -textformat({trace, From, 'receive', Msg}) -> -    io_lib:format("~w: rec   ~s~n", [From, -				       tuple_space(Msg)]); -textformat({trace, From, send, Msg, To}) -> -    io_lib:format("~w:  !    To: ~w Msg: ~s~n", [From, -						   To, -						   tuple_space(Msg)]); -textformat({trace, From, call, Func}) -> -    io_lib:format("~w: call  ~s~n",[From, ffunc(Func)]); -textformat({trace, From, spawn, Data}) -> -    io_lib:format("~w: spawn ~p~n", [From, Data]); -textformat({trace, From, link, Data}) -> -    io_lib:format("~w: link  ~p~n", [From,  Data]); -textformat({trace, From, unlink, Data}) -> -    io_lib:format("~w: U-lnk ~p~n", [From,  Data]); - -textformat({trace, From, Op, Data}) -> -    io_lib:format("~w: ~w   ~p~n", [From, Op, Data]); - -textformat({print, Format, Args}) -> -    io_lib:format(Format, Args); -textformat(Other) -> -    io_lib:format("~p~n",[Other]). -     - - - - -ffunc({M,F, Argl}) -> -    io_lib:format("~w:~w(~s)", [M, F, fargs(Argl)]); -ffunc(X) -> tuple_space(X). -fargs([]) -> []; -fargs([A]) -> tuple_space(A);  %% last arg -fargs([A|Args]) -> [tuple_space(A),", "|fargs(Args)]. - - -tuple_space(X) when is_tuple(X) -> print(size(X), X, "}"); -tuple_space(X)                  -> io_lib:format("~p",[X]). - -print(0  , _X, Buff) -> ["{"|Buff]; -print(1  , X, Buff) ->  -    Str =  tuple_space(element(1, X)), -    ["{",Str|Buff]; -print(Num, X, Buff) -> -    Str =  tuple_space(element(Num, X)), -    print(Num-1, X, [", ",Str|Buff]). - - - -%% ---------------------------------------------------------------- -%% splits the list at element Size, returns Size, and the 2 lists -%% If the list is not long enough, it returns {size(List),[],List} - - -split([],_,Length,Buff) -> -    {Length,[],lists:reverse(Buff)}; -split(Rest,0,Length,Buff) -> -    {Length,Rest,lists:reverse(Buff)}; -split([L|List],Size,Length,Buff) -> -    split(List,Size-1,Length+1,[L|Buff]). - - - diff --git a/lib/pman/src/pman_main.erl b/lib/pman/src/pman_main.erl deleted file mode 100644 index 2f51284293..0000000000 --- a/lib/pman/src/pman_main.erl +++ /dev/null @@ -1,789 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-2012. 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% -%% --module(pman_main). --compile([{nowarn_deprecated_function,{gs,config,2}}, -          {nowarn_deprecated_function,{gs,read,2}}]). - -%% Main process and window - --export([init/2]). - --record(state, {win,		     % GS top window -		frame,	             % GS top frame -		grid,		     % GS process info grid - -		size,                % int() No. of displayed procs -		w,                   % int() Window width -		h,                   % int() Window height - -		hide_system=false,   % bool() Auto-hide system procs -		hide_new=false,      % bool() Auto-hide new processes - -		hide_modules,        % ordset() Excluded modules - -		hide_all=[],         % [{node(), bool()}] Hide all -		hide_pids=[],        % [{node(), Ordset}] Processes -				     %  explicitly to hide, per node -		show_pids=[],        % [{node(), Ordset}] Processes -				     %  explicitly to show, per node - -		shown_pids=[],       % [{node(), Ordset}] Processes -		                     %  actually shown, per node - -		node,		     % node() Current node -		nodes=[],            % [node()] All known nodes - -		focus=1,	     % int() Grid line with focus -		focus_pid=undefined, % pid() | undefined Proc in focus - -		noshell,	     % bool() Noshell mode on - -		options}).           % term() Trace options settings - - --include("pman_win.hrl"). - --define(REFRESH_TIME,5000). - --define(REQUIRES_FOCUS,		     % List of menus that should -	['Trace Process',	     % be disabled if no process -	 'Kill',		     % is in focus -	 'Hide Selected Process', -	 'Module']). - -%%--Process init and loop----------------------------------------------- - -init(PidCaller, OSModuleExcluded) -> -    process_flag(trap_exit, true), - -    %% Monitor all nodes in a distributed system -    case is_alive() of - -	%% We have a distributed system -	true -> net_kernel:monitor_nodes(true); - -	%% No distribution -	false -> ignore -    end, -    Nodes = [node()|nodes()], - -    %% Create the main window -    %% For some extremely strange reason, the frame must be resized -    %% or the grid won't be visible... -    GridSize = length(processes()) + 61, -    {Window, Grid, Frame, Visible, W, H}  = -	pman_win:pman_window(GridSize, OSModuleExcluded, Nodes), -    gse:resize(Frame, ?WIN_WIDTH, ?WIN_HEIGHT-?MENU_HEIGHT), - -    Noshell = case pman_shell:find_shell() of -		  noshell -> true; -		  _ -> false -	      end, - -    State1 = #state{win=Window, frame=Frame, grid=Grid, -		    size=Visible, -		    w=W, h=H, -		    hide_modules=OSModuleExcluded, -		    node=node(), -		    noshell=Noshell}, - -    State2 = lists:foldl(fun(Node, State) -> add_node(Node, State) end, -			 State1, -			 Nodes), - -    State3 = refresh(State2), - -    %% Notify caller that the process appears -    %% to have been started. -    PidCaller ! {initialization_complete, self()}, - -    %% Initiate a 'catch all' trace pattern so call tracing works -    erlang:trace_pattern({'_', '_', '_'}, true, [local]), - -    %% Read default options file -    Options = restore_options(State3), - -    loop(State3#state{options=Options}). - -add_node(Node, State) -> -    pman_win:add_menu(node, [Node], "Show"), -    State#state{hide_all=nl_update(Node, false, State#state.hide_all), -		hide_pids=nl_update(Node, [], State#state.hide_pids), -		show_pids=nl_update(Node, [], State#state.show_pids), -		shown_pids=nl_update(Node, [], State#state.shown_pids), -		nodes=[Node|State#state.nodes]}. - -%% Restore saved options from default file -restore_options(State)-> -    File = options_file(), -    case pman_options:read_from_file(File) of -	{ok, Options} -> -	    Options; -	{error, ReasonStr, DefOptions} -> -	    Parent = State#state.win, -	    Msg = io_lib:format( -		    "Problems reading default option file~n~s:~n~s", -		    [File, ReasonStr]), -	    tool_utils:notify(Parent, Msg), -	    DefOptions -    end. - -options_file() -> -    {ok, [[Home]]} = init:get_argument(home), -    filename:join([Home, ".erlang_tools", "pman.opts"]). - -loop(State) -> -    receive -	{nodeup, Node} -> -	    case nl_exists(Node, State#state.hide_all) of -		true -> -		    pman_win:add_menu(node, [Node], "Show"), -		    loop(State#state{nodes=[Node|State#state.nodes]}); -		false -> -		    loop(add_node(Node, State)) -	    end; - -	{nodedown, Node} -> -	    pman_win:remove_menu([Node]), - -	    Msg = io_lib:format("Node~n~p~ndown.", [Node]), -	    spawn_link(tool_utils, notify, [State#state.win, Msg]), - -	    %% We remove Node from the list of nodes but not from -	    %% the other lists of State, in case Node reappears later -	    Nodes = lists:delete(Node, State#state.nodes), -	    State2 = State#state{nodes=Nodes}, - -	    %% If it was the shown node that went down, -	    %% change overview to this node -	    if -		Node==State#state.node -> -		    State3 = execute_cmd({node,node()}, State2, [], []), -		    loop(State3); -		true -> -		    loop(State2) -	    end; - -	%% Ignore EXIT signals from help processes -	{'EXIT', _Pid, _Reason} -> -	    loop(State); - -	%% GS events -	{gs, _Obj, _Event, _Data, _Args} = Cmd -> -	    case gs_cmd(Cmd, State) of -		stop -> -		    exit(topquit); -		State2 -> -		    loop(State2) -	    end - -    after ?REFRESH_TIME -> -	    State2 = refresh(State), -	    loop(State2) -    end. - -%% gs_cmd(Event, State) -> stop | State' -gs_cmd(Event, State) -> -    case Event of - -	%% --- Window manager commands --- - -	%% Window is moved or resized -        {gs, _, configure, _Data, Args} -> -	    configure(Args, State); - -	%% Window closed, stop Pman -        {gs, _, destroy, _, _} -> -	    stop; - -	%% --- Dynamic commands --- - -	%% Click in any object where the GS Data field is a 2-tuple -	{gs, _, click, Data, Args} when is_tuple(Data), size(Data)==2 -> -	    execute_cmd(Data, State, [], Args); - -	%% Single click in the grid sets focus to selected process -	{gs, _, click, {pidfunc,_,_}, [_,Row|_]} when is_integer(Row) -> -	    focus(Row, State); - -	%% Double click in the grid starts tracing of selected process -	{gs, _, doubleclick, {pidfunc,_,_}, [_Col,Row| _]} when is_integer(Row) -> -	    execute_cmd('Trace Process', State, [], []); - -	%% Click in named GS objects -        {gs, Cmd, click, Data, Args} when is_atom(Cmd); -					  is_atom(element(1, Cmd)) -> -	    execute_cmd(Cmd, State, Data, Args); - -        %% --- Keyboard accelerator commands --- - -	%% Move focus up and down -	{gs, _, keypress, [], ['Up',_,0,0]} -> -	    execute_cmd(focus_previous, State, [], []); -	{gs, _, keypress, [], ['Down',_,0,0]} -> -	    execute_cmd(focus_next, State, [], []); - -	%% Other keyboard shortcuts -	{gs, _, keypress, [], ['Return',_,0,0]} -> -	    execute_cmd('Trace Process', State, [], []); -        {gs, _, keypress, [], [Key,_,0,1]} -> -	    execute_cmd(shortcut(Key), State, [], []); - -	%% Ignore all other GS events -     	_Other -> -	    State -    end. - -%% Keyboard shortcuts - -%% File menu -shortcut(o) -> 'Default Options'; -shortcut(e) -> 'Exit'; -shortcut(z) -> 'Exit'; - -%% View menu -shortcut(i) -> 'Hide All'; -shortcut(u) -> 'Hide Modules'; -shortcut(d) -> 'Hide Selected Process'; -shortcut(m) -> 'Module'; -shortcut(r) -> 'Refresh'; - -%% Trace menu -shortcut(k) -> 'Kill'; -shortcut(t) -> 'Trace Process'; -shortcut(s) -> 'Trace Shell'; - -%% Help menu -shortcut(h) -> 'Help'; - -%% Keyboard command only -shortcut(l) -> 'All Links'; - -%% Process grid traversal -shortcut(p) -> focus_previous; -shortcut(n) -> focus_next; -shortcut(_) -> dummy. - -%% configure([W,H,X,Y|_], State) -> State' -%% Window has been moved or resized -configure([W,H|_], State) -> -    if -	W==State#state.w, H==State#state.h -> -	    ignore; - -	true -> -	    gse:resize(State#state.frame, W, H-?MENU_HEIGHT), - -	    Grid = State#state.grid, -	    case abs(W - gs:read(Grid,width) - 6) of -		0 -> -		    ok;   %% Avoid refreshing width if possible -		_Anything -> -		    Cols = pman_win:calc_columnwidths(W-6), -		    gs:config(Grid, Cols) -	    end, -	    pman_win:configwin(Grid, W, H) -    end, -    State. - -%% focus(Row, State) -> State' -%%   Row = int()  Grid row -%% User has selected a row in the grid. -%% Row==1 means header row. -focus(Row, State) -> - -    Pid = case get_pid_in_focus(Row, State#state.grid) of -	      {true, {pidfunc,Pid0,_}} -> -		  pman_win:change_colour(State#state.grid, -					 State#state.focus, Row), -		  enable_pid_actions(), -		  Pid0; -	      false -> -		  disable_pid_actions(), -		  undefined -	  end, - -    State#state{focus=Row, focus_pid=Pid}. - -%% get_pid_in_focus(Row, Grid) -> {true, Data} | false -%%   Data = {pidfunc, Pid, Func} -%%     Func = {Mod,Name,Arity} | term() -%% Return the data associated with the process in focus if there is one, -get_pid_in_focus(1, _Grid) -> -    false; -get_pid_in_focus(Row, Grid) -> -    case gs:read(Grid, {obj_at_row,Row}) of -	undefined -> false; -	GridLine -> -	    Data = gs:read(GridLine, data), -	    {true, Data} -    end. - -%% execute_cmd(Cmd, State, Data, Args) -> stop | State' - -%% Checkbutton "Hide System Processes" -execute_cmd('Hide System', State, _Data, Args) -> -    [_Text, _Group, Bool|_Rest] = Args, -    State2 = State#state{hide_system=Bool}, -    refresh(State2); - -%% Checkbutton "Auto-Hide New" -execute_cmd('Auto Hide New', State, _Data, Args ) -> -    [_Text, _Group, Bool|_Rest] = Args, -    refresh(State#state{hide_new=Bool}); - -%% File->Options... -execute_cmd('Default Options', State, _Data, _Args) -> -    OldOptions = State#state.options, -    NewOptions = pman_options:dialog(State#state.win, -				     "Default Trace Options", -				     OldOptions), -    case NewOptions of -	{error, _Reason} -> -	    State; -	Options -> -	    State#state{options=Options} -    end; - -%% File->Save Options -%% Save the set default options to the user's option file -execute_cmd('Save Options', State, _Data, _Args)-> -    Options = State#state.options, -    File = options_file(), -    Parent = State#state.win, - -    case pman_options:save_to_file(Options, File) of -	ok -> -	    tool_utils:notify(Parent, "Options saved to\n" ++ File); -	{error, ReasonStr} -> -	    Msg = io_lib:format("Could not save options to~n~s:~n~s", -				[File, ReasonStr]), -	    tool_utils:notify(Parent, Msg) -    end, -    State; - -%% File->Exit -%% Exit the application -execute_cmd('Exit', _State, _Data, _Args) -> -    stop; - -%% View->Hide All Processes -execute_cmd('Hide All', State, _Data, _Args) -> -    Node = State#state.node, -    HideAll = nl_update(Node, true, State#state.hide_all), -    ShowPids = nl_del_all(State#state.node, State#state.show_pids), -    State2 = State#state{hide_all=HideAll, show_pids=ShowPids}, -    refresh(State2, true); - -%% View->Hide modules... -%% Opens a dialog where the user can select from a list of  -%% the loaded modules. -%% The selected module is added to the list of hidden modules. -execute_cmd('Hide Modules', State, _Data, _Args) -> - -    %% Get all loaded modules that are not already hidden -    AllModules = lists:map(fun({Module, _File}) -> Module end, -			   code:all_loaded()), -    ModulesSet = ordsets:subtract(ordsets:from_list(AllModules), -				  State#state.hide_modules), - -    %% Let the user select which of the loaded modules to exclude from -    %% the process overview -    Title = "Module selection", -    case pman_tool:select(State#state.win, Title, ModulesSet) of -	Modules when is_list(Modules) -> -	    HideModules = ordsets:union(State#state.hide_modules, -					ordsets:from_list(Modules)), -	    refresh(State#state{hide_modules=HideModules}); -	cancelled -> State -    end; - -%% View->Hide Selected Process -%% The process in focus should explicitly be hidden -execute_cmd('Hide Selected Process', State, _Data, _Args) -> -    case State#state.focus_pid of -	undefined -> State; -	Pid -> -	    Node = State#state.node, -	    HidePids = nl_add(Node, Pid, State#state.hide_pids), -	    ShowPids = nl_del(Node, Pid, State#state.show_pids), -	    refresh(State#state{hide_pids=HidePids, show_pids=ShowPids}) -    end; - -%% View->Module Info... -%% Open window with module information. -execute_cmd('Module', State, _Data, _Args) -> -    case get_pid_in_focus(State#state.focus, State#state.grid) of -	{true, {pidfunc, _Pid, {Module,_Name,_Arity}}} -> -	    pman_module_info:start(Module); -	_ -> % false | {true, {pidfunc, Pid, Other}} -	    ignore -    end, -    State; - -%% View->Refresh -%% Refresh the main window.  -%% (Called automatically every ?REFRESH_TIME millisecond) -execute_cmd('Refresh', State, _Data, _Args) -> -    refresh(State); - -%% View->Show All Processes -%% Makes all processes visible except system processes and new -%% processes, if those buttons are checked. -%% Note: Also un-hides all hidden modules! -execute_cmd('Show All', State, _Data, _Args) -> -    Node = State#state.node, -    HideAll = nl_update(Node, false, State#state.hide_all), -    HidePids = nl_del_all(State#state.node, State#state.hide_pids), -    ShowPids = nl_del_all(State#state.node, State#state.show_pids), -    State2 = State#state{hide_modules=ordsets:new(), hide_all=HideAll, -			 hide_pids=HidePids, show_pids=ShowPids}, -    refresh(State2, true); - -%% View->Show Processes... -%% Open a list of all hidden processes, if the user selects one this -%% process should explicitly be shown -execute_cmd('Show Selected', State, _Data, _Args) -> -    Node = State#state.node, - -    All = pman_process:r_processes(Node), -    Hidden = case nl_lookup(Node, State#state.hide_all) of -		 true -> -		     All; -		 false -> -		     Shown = nl_lookup(Node, State#state.shown_pids), -		     ordsets:subtract(All, Shown) -	     end, - -    %% Selection window -    Title = "Select Processes to Show", -    Tuples = -	lists:map(fun(Pid) -> -			  {M,F,A} = pman_process:function_info(Pid), -			  Str = case pman_process:get_name(Pid) of -				    " " -> -					io_lib:format("~p:~p/~p", -						      [M, F, A]); -				    Name -> -					io_lib:format("[~p] ~p:~p/~p", -						      [Name, M, F, A]) -				end, -			  {Pid, Str} -		  end, -		  Hidden), -    case pman_tool:select(State#state.win, Title, Tuples) of -	Pids when is_list(Pids) -> -	    HidePids = nl_del(Node, Pids, State#state.hide_pids), -	    ShowPids = nl_add(Node, Pids, State#state.show_pids), -	    refresh(State#state{hide_pids=HidePids,show_pids=ShowPids}); -	cancelled -> State -    end; - -%% Trace->Kill -execute_cmd('Kill', State, _Data, _Args) -> -    case State#state.focus_pid of -	Pid when is_pid(Pid) -> -	    exit(Pid, kill); -	undefined -> -	    ignore -    end, -    State; - -%% Trace->Selected Process -execute_cmd('Trace Process', State, _Data, _Args) -> -    case State#state.focus_pid of -	Pid when is_pid(Pid) -> -	    pman_shell:start({Pid,self()}, State#state.options); -	undefined -> -	    ignore -    end, -    State; - -%% Trace->Shell Process -execute_cmd('Trace Shell', State, _Data, _Args) -> -    case pman_shell:find_shell() of -	noshell -> -	    State; -	Shell ->  -	    pman_shell:start({{shell,Shell},self()}, -			     State#state.options), -	    State#state{noshell=false} -    end; - -%% Nodes->Show <Node> -%% Change shown node -execute_cmd({node,Node}, State, _Data, _Args) -> -    gse:config(State#state.win, -	       [{title,lists:concat(["Pman: Overview on ", Node])}]), -    gse:disable(Node), -    catch gse:enable(State#state.node), % Menu may not exist any more -    refresh(State#state{node=Node}, true); - -%% Help->Help -execute_cmd('Help', State, _Data, _Args)  -> -    Win = State#state.win, -    HelpFile = -	filename:join([code:lib_dir(pman),"doc","html","index.html"]), -    tool_utils:open_help(Win, HelpFile), -    State; - -%% Keyboard shortcut Ctrl-l -execute_cmd('All Links', State, _Data, _Args) -> -    case State#state.focus_pid of -	Pid when is_pid(Pid) -> -	    case process_info(Pid, links) of -		{links, Pids} -> -		    pman_shell:start_list(Pids, self(), -					  State#state.options); -		undefined -> -		    ignore -	    end; -	undefined -> ignore -    end, -    State; - -%% Keyboard shortcuts for process grid traversal -execute_cmd(focus_previous, State, _Data, _Args) -> -    focus(previous_row(State), State); -execute_cmd(focus_next, State, _Data, _Args) -> -    focus(next_row(State), State); - -%% Keyboard combinations that are not shortcuts -execute_cmd(dummy, State, _Data, _Args) -> -    State. - -%% Convenience functions for disabling/enabling menu items that require -%% that a process is selected. -disable_pid_actions() -> -    lists:foreach(fun(X) -> gse:disable(X) end, ?REQUIRES_FOCUS). - -enable_pid_actions()  -> -    lists:foreach(fun(X) -> gse:enable(X) end, ?REQUIRES_FOCUS). - -%% refresh(State) -> State' -%% refresh(State, ForceP) -> State' -%% Refreshes the main window. -refresh(State) -> -    refresh(State, false). -refresh(#state{node=Node} = State, ForceP) -> - -    %% Update shown processes - -    %% First, get an ordset of all processes running at the current node -    All = pman_process:r_processes(Node), - -    Shown = nl_lookup(Node, State#state.shown_pids), -    ExpShown = nl_lookup(Node, State#state.show_pids), - -    {Show, State2} = -	case nl_lookup(Node, State#state.hide_all) of - -	    %% If the user has selected "Hide All Processes", only -	    %% explicitly selected processes which still exist should -	    %% be shown -	    true -> -		{ordsets:intersection(ExpShown, All), State}; - -	    false -> -		%% Compute which processes should be hidden according -		%% to the flags/menu items selected -		Hidden = hidden_pids(All, State), - -		NotHidden = ordsets:subtract(All, Hidden), - -		Show0 = case State#state.hide_new of -			    %% If the user has selected "Auto-Hide New", -			    %% then only those processes in NotHidden -			    %% which are already shown, should be shown, -			    %% together with explicitly selected -			    %% processes which still exist -			    true -> -				ordsets:union( -				  ordsets:intersection(NotHidden,Shown), -				  ordsets:intersection(ExpShown, All)); - -			    %% Otherwise, show all processes in -			    %% NotHidden, together with explicitly -			    %% selected processes which still exist -			    false -> -				ordsets:union( -				  NotHidden, -				  ordsets:intersection(ExpShown, All)) -			end, - -		ShownPids = nl_update(Node, Show0, -				      State#state.shown_pids), -		{Show0, State#state{shown_pids=ShownPids}} -	end, - -    NoOfHidden = length(All) - length(Show), - -    if -	Show==Shown, not ForceP -> -	    pman_win:update(NoOfHidden), -	    State; - -	true -> -	    ShowInfo = display_info(Show), -	    pman_win:update(State#state.grid, ShowInfo, NoOfHidden), -	     -	    %% Set the focus appropriately -	    State3 = case State2#state.focus_pid of -			 undefined -> -			     disable_pid_actions(), -			     State2; -			 Pid -> -			     Row = get_row(Pid, Show), -			     focus(Row, State2) -		     end, - -	    trace_shell_possible(State3), - -	    Size = length(Show), -	    case Size of -		1 -> gse:disable('Hide All'); -		_ -> gse:enable('Hide All') -	    end, - -	    State3#state{size=Size} -    end. - -%% hidden_pids(All, State) -> Hidden -hidden_pids(All, State) -> - -    %% Processes hidden because they are system processes -    HideSys = case State#state.hide_system of -		  true -> -		      lists:filter( -			fun(Pid) -> -				pman_process:is_system_process(Pid) -			end, -			All); -		  false -> -		      [] -	      end, -	     -    %% Process hidden because they are executing code in a hidden module -    Mods = State#state.hide_modules, -    HideMod = -	lists:filter(fun(Pid) -> -			     pman_process:is_hidden_by_module(Pid, Mods) -		     end, -		     All), - -    %% Explicitly hidden processes -    HideExp = nl_lookup(State#state.node, State#state.hide_pids), - -    %% All hidden processes -    ordsets:union([HideSys, HideMod, HideExp]). - -display_info(Pids) -> -    lists:map(fun(Pid) -> -		      Func = pman_process:function_info(Pid), -		      Name = pman_process:get_name(Pid), -		      Msgs = pman_process:msg(Pid), -		      Reds = pman_process:reds(Pid), -		      Size = pman_process:psize(Pid), -		      {Pid, Func, Name, Msgs, Reds, Size} -	      end, -	      Pids). - -get_row(Pid, List) -> -    get_row(Pid, List, length(List)+1). - -get_row(Pid, [Pid | _], Row) -> -    Row; -get_row(Pid, [_ | T], Row) -> -    get_row(Pid, T, Row-1); -get_row(_Pid, [], _Row) -> -    1. - -next_row(#state{size=Size, focus=Row}) -> -    check_row(Row+1, Size). - -previous_row(#state{size=Size, focus=Row}) -> -    check_row(Row-1, Size). - -check_row(1, Size) -> -    Size+1; -check_row(Row, Size) when Row==Size+2 -> -    2; -check_row(Row, _Size) -> -    Row. - -%% Check if node is running in noshell mode and if so disable the -%% 'Trace Shell' menu option. -trace_shell_possible(#state{noshell=true}) -> -    gse:disable('Trace Shell'); -trace_shell_possible(_) -> -    ok. - -%% -- Functions for manipulating {Node, Data} lists -- - -%% nl_add(Node, Elem|Elems, NList) -> NList' -nl_add(Node, Elems, [{Node, Ordset} | T]) when is_list(Elems) -> -    [{Node, ordsets:union(Elems, Ordset)} | T]; -nl_add(Node, Elem, [{Node, Ordset} | T]) -> -    [{Node, ordsets:add_element(Elem, Ordset)} | T]; -nl_add(Node, Elem, [H | T]) -> -    [H | nl_add(Node, Elem, T)]; -nl_add(Node, Elems, []) when is_list(Elems) -> -    [{Node, Elems}]; -nl_add(Node, Elem, []) -> -    [{Node, ordsets:add_element(Elem, ordsets:new())}]. - -%% nl_del(Node, Elem|Elems, NList) -> NList' -nl_del(Node, Elems, [{Node, Ordset} | T]) when is_list(Elems) -> -    [{Node, ordsets:subtract(Ordset, Elems)} | T]; -nl_del(Node, Elem, [{Node, Ordset} | T]) -> -    [{Node, ordsets:del_element(Elem, Ordset)} | T]; -nl_del(Node, Elem, [H | T]) -> -    [H | nl_del(Node, Elem, T)]; -nl_del(_Node, _Elem, []) -> -    []. - -%% nl_del_all(Node, NList) -> NList' -nl_del_all(Node, [{Node, _Ordset} | T]) -> -    [{Node, ordsets:new()} | T]; -nl_del_all(Node, [H | T]) -> -    [H | nl_del_all(Node, T)]; -nl_del_all(_Node, []) -> -    []. - -%% nl_update(Node, Val, NList) -> NList' -nl_update(Node, Val, [{Node, _OldVal} | T]) -> -    [{Node, Val} | T]; -nl_update(Node, Val, [H | T]) -> -    [H | nl_update(Node, Val, T)]; -nl_update(Node, Val, []) -> -    [{Node, Val}]. - -%% nl_lookup(Node, NList) -> Val -nl_lookup(Node, NList) -> -    {value, {_Node,Val}} = lists:keysearch(Node, 1, NList), -    Val. - -%% nl_exists(Node, NList) -> bool() -nl_exists(Node, NList) -> -    case lists:keysearch(Node, 1, NList) of -	{value, _Val} -> -	    true; -	false -> -	    false -    end. diff --git a/lib/pman/src/pman_module_info.erl b/lib/pman/src/pman_module_info.erl deleted file mode 100644 index 944fd4a462..0000000000 --- a/lib/pman/src/pman_module_info.erl +++ /dev/null @@ -1,133 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-2012. 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% -%% --module(pman_module_info). --compile([{nowarn_deprecated_function,{gs,config,2}}, -          {nowarn_deprecated_function,{gs,start,1}}]). - -%% Window with module information (View->Module Info...) - -%% External exports --export([start/1]). - -%% Record for keeping the loop state for the  -%% module info process. --record(state, {topwin,      % GS identifier for top window -		editor,      % GS identifier for editor -		module,      % Name of the viewed module -		parent}).    % Pid of the parent - -start(Module) -> -    Self = self(), -    spawn_link(fun() -> init(Module, Self) end). - -init(Module, Parent) -> -    process_flag(trap_exit, true), - -    GS = gs:start([{kernel,true}]), -    Font = pman_win:font(GS), - -    WinTitle = lists:flatten(io_lib:format("Pman - Module Info: ~p", -					   [Module])), -    WinOptions = [{title,WinTitle}, {width,550}, {height, 400}, -		  {configure,true}, {keypress,true}, {destroy,true}], -    TopWindow = gse:window(GS, WinOptions), - -    %% File menu -    MenuBar = gse:menubar(TopWindow, []), -    MBFile = gse:menubutton(MenuBar, [{label,{text," File "}}, -				      {font,Font}, {underline, 1}]), -    MenuFile = gse:menu(MBFile, []), - -    gse:named_menuitem('Save buffer', MenuFile, -		       [{label,{text,"Save buffer..."}}, -			{font,Font}, {underline,0}]), -    gse:named_menuitem('Close', MenuFile, -		       [{label,{text,"Close"}}, -			{font,Font}, {underline,0}]), - -    %% Output part of window -    Editor = gse:editor(TopWindow, -			[{font,Font}, -			 {x,3}, {y,40}, {width,546}, {height,348}]), -    gse:config(Editor, [{keypress,true}, -			{insert,{'end',pman_win:module_data(Module)}}]), -    gse:config(Editor, [{enable,false}, -			{vscroll,right}, {hscroll,bottom}, -			{wrap,none}]), -    gse:map(TopWindow), - -    State = #state{topwin=TopWindow, editor=Editor, module=Module, -		   parent=Parent}, -    loop(State). - -loop(State) -> - -    receive -	%% Die if the parent dies -	{'EXIT', Pid, _Reason} when Pid==State#state.parent -> -	    gse:destroy(State#state.topwin); - -	%% Ignore other exit signals (from file dialog window) -	{'EXIT', _Pid, _Reason} -> -	    loop(State); - -	%% Window closed -	{gs, _TopWindow, destroy, [], []} -> -	    ok; - -	%% Window resized or moved -        {gs, _TopWindow, configure ,_Data, [W,H,_X,_Y|_]} -> -	    gs:config(State#state.editor, [{width,W-3}, {height,H-40}]), -	    loop(State); - -	%% Close - destroy window and exit process -	{gs, 'Close', click, _Data, _Args} -> -	    gse:destroy(State#state.topwin), -	    ok; - -	%% Save Buffer - make filename and save buffer to file -	{gs, 'Save buffer', click, _Data, _Args} -> -	    save_buffer(State), -	    loop(State); - -	%% Keyboard accelerator commands -	{gs, _, keypress, [], [c,_,0,1]} -> % 'Close' -	    gse:destroy(State#state.topwin), -	    ok; -	{gs, _, keypress, [], [s,_,0,1]} -> % 'Save buffer' -	    save_buffer(State), -	    loop(State); -	{gs, _, keypress, _Data, _Args} -> -	    loop(State) -    end. - -save_buffer(State) -> -    DefaultFile = atom_to_list(State#state.module) ++ ".module_info", -    Result = tool_utils:file_dialog([{type,save}, {file,DefaultFile}]), -    case Result of -	%% User selected a file, now save the result -	{ok, File, _Dir} ->	     -	    gs:config(State#state.editor, {save,File}), -	    Msg = "Module information saved in file\n" ++ File, -	    tool_utils:notify(State#state.topwin, Msg); - -	%% File dialog was cancelled in some way. -	{error, _Reason} -> -	    ignore -    end. diff --git a/lib/pman/src/pman_options.erl b/lib/pman/src/pman_options.erl deleted file mode 100644 index 0765458fdc..0000000000 --- a/lib/pman/src/pman_options.erl +++ /dev/null @@ -1,395 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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% -%% --module(pman_options). - -%% Window with trace options settings (File->Options...) - --export([dialog/3, -	 read_from_file/1, save_to_file/2]). - --include("pman_options.hrl"). - --define(WIN_WIDTH,  350). --define(WIN_HEIGHT, 350). - --define(TOP_WINDOW, xx_pman_option_window_xx). --define(TOP_FRAME,  xx_pman_top_frame_xx). - --record(state, {resize_frame,   % GS identifier for the main frame -		parent}).       % Pid of parent - -%%--dialog/3------------------------------------------------------------ -%% Create a window, or return a value indicating that is is already -%% created. - -dialog(ParentWin, Title, Options) -> -    Self = self(), -    Pid = spawn(fun() -> dialog(Self, ParentWin, Title, Options) end), -    receive -	{Pid, Value} -> -	    Value % Options2 | {error,destroyed} | {error,cancelled} -    end. - -dialog(Parent, ParentWin, Title, Options) -> - -    %% Check if the dialog has already been created, in that  -    %% case, we can reuse it. Otherwise a new dialog is created. -    case gse:name_occupied(?TOP_WINDOW) of -	false -> make_window(ParentWin, Title); -	true -> ok -    end, - -    %% Window has now been created or may be re-used -    update_window_from_options(Options), - -    gse:resize(?TOP_FRAME, ?WIN_WIDTH, ?WIN_HEIGHT), -    gse:map(?TOP_WINDOW), - -    loop(#state{resize_frame=?TOP_FRAME, parent=Parent}). - -loop(State) -> -    receive -	{gs, _Id, destroy, _Data, _Arg} ->  -	    State#state.parent ! {self(), {error,destroyed}}; - -	{gs, ?TOP_WINDOW, configure, _Data, [W, H |_]} -> -	    gse:config(State#state.resize_frame, -		       [{width,W},{height,H}]), % repack -	    loop(State); - -	{gs, ok_button, click, _Data, _Arg} -> -	    Options = get_options_from_window(), -	    gse:unmap(?TOP_WINDOW), -	    State#state.parent ! {self(), Options}; - -	{gs, cancel_button, click, _Data, _Arg} -> -	    gse:unmap(?TOP_WINDOW), -	    State#state.parent ! {self(), {error,cancelled}}; - -	{gs, trace_spawn, click, _Data, [_Text,_,Value]} -> -	    group_radio(Value, trace_spawn_all, [trace_spawn_all, -						 trace_spawn_first]), -	    loop(State); - -	{gs, trace_link, click, _Data, [_Text,_,Value]} -> -	    group_radio(Value, trace_link_all, [trace_link_all, -						trace_link_first]), -	    loop(State); - -	{gs, trace_in_window, click, _Data, _Arg} -> -	    lists:foreach(fun(X) -> gse:disable(X) end, -			  [trace_file, trace_file_browse]), -	    loop(State); - -	{gs, trace_to_file, click, _Data, [_Text,_,_Value]} -> -	    lists:foreach(fun(X) -> gse:enable(X) end, -			  [trace_file, trace_file_browse]), -	    loop(State); - -	{gs, trace_file_browse, click, _Data, _Arg} -> -	    Result = tool_utils:file_dialog([{type,save}, -					     {file, "Untitled.log"}]), -	    case Result of -		{error, _Reason} -> -		    loop(State); -		{ok, Name,_State} -> -		    gse:config(trace_file, [{text, Name}]), -		    loop(State) -	    end -    end. - --define(LBLOPTS, [{justify,left}, {align,w}]). --define(BTNOPTS, [{justify,left}, {align,w}]). - -make_window(ParentWin, Title) -> - -    Font = pman_win:font(), - -    gse:named_window(?TOP_WINDOW, ParentWin, [{title,Title}, -					      {configure,true}, -					      {width, ?WIN_WIDTH}, -					      {height, ?WIN_HEIGHT}]), - -    gse:named_frame(?TOP_FRAME, ?TOP_WINDOW, -		    [{bw,3}, -		     {packer_x,[{stretch,1,175}, {stretch,1,175}]}, -		     {packer_y,[{stretch,3},{stretch,2},{stretch,1}]}]), - -    F11 = gse:frame(?TOP_FRAME, [{bw,3}, -				 {pack_xy,{1,1}}, -				 {packer_x,[{stretch,1}, -					    {stretch,20}, -					    {stretch,2}]}, -				 {packer_y,[{stretch,2}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}]}]), - -    gse:label(F11,[{pack_xy,{2,1}}, -		   {label,{text,"Trace output options:"}}, -		   {font,Font} | ?LBLOPTS]), - -    gse:named_checkbutton(trace_send, F11, -			  [{pack_xy,{2,2}}, -			   {label,{text,"Trace send"}}, -			   {font,Font} | ?BTNOPTS]), -    gse:named_checkbutton(trace_receive, F11, -			  [{pack_xy,{2,3}}, -			   {label,{text, "Trace receive"}}, -			   {font,Font} | ?BTNOPTS]), -    gse:named_checkbutton(trace_functions,F11, -			  [{pack_xy,{2,4}}, -			   {label,{text, "Trace functions"}}, -			   {font,Font} | ?BTNOPTS]), -    gse:named_checkbutton(trace_events,F11, -			  [{pack_xy,{2,5}}, -			   {label,{text, "Trace events"}}, -			   {font,Font} | ?BTNOPTS]), - -    F21 = gse:frame(?TOP_FRAME, [{bw,3}, -				 {pack_xy,{2,1}}, -				 {packer_x,[{stretch,1}, -					    {stretch,2}, -					    {stretch,2}, -					    {stretch,20}, -					    {stretch,1}]}, -				 {packer_y,[{stretch,2}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}]}]), - -    gse:label(F21, [{pack_xy,{{2,4},1}}, -		    {label,{text,"Inheritance options:"}}, -		    {font,Font} | ?LBLOPTS]), - -    gse:named_checkbutton(trace_spawn, F21, -			  [{pack_xy,{{2,4},2}}, -			   {data,trace_send}, -			   {label,{text,"Inherit on spawn"}}, -			   {font,Font} | ?BTNOPTS]), -    gse:named_radiobutton(trace_spawn_all, F21, -			  [{pack_xy,{{3,4},3}}, -			   {group,spawn}, -			   {data,trace_receive}, -			   {label,{text, "All spawns"}}, -			   {font,Font} | ?BTNOPTS]), -    gse:named_radiobutton(trace_spawn_first, F21, -			  [{pack_xy,{{3,4},4}}, -			   {group,spawn}, -			   {data,trace_receive}, -			   {label,{text,"First spawn only"}}, -			   {font,Font} | ?BTNOPTS]), -    gse:named_checkbutton(trace_link, F21, -			  [{pack_xy,{{2,4},6}}, -			   {data,trace_send}, -			   {label,{text,"Inherit on link"}}, -			   {font,Font} | ?BTNOPTS]), -    gse:named_radiobutton(trace_link_all, F21, -			  [{pack_xy,{{3,4},7}}, -			   {group,link}, -			   {data,trace_receive}, -			   {label,{text,"All links"}}, -			   {font,Font} | ?BTNOPTS]), - -    gse:named_radiobutton(trace_link_first, F21, -			  [{pack_xy,{{3,4},8}}, -			   {group,link}, -			   {data,trace_receive}, -			   {label,{text,"First link only"}}, -			   {font,Font} | ?BTNOPTS]), - -    F12 = gse:frame(?TOP_FRAME, [{bw,3}, -				 {pack_xy,{{1,2},2}}, -				 {packer_x,[{stretch,1}, -					    {stretch,5},  % Label -					    {stretch,1}, -					    {stretch,10}, % Field -					    {stretch,1}, -					    {stretch,5},  % Button -					    {stretch,1}]}, -				 {packer_y,[{stretch,2}, -					    {stretch,1}, -					    {stretch,1}, -					    {stretch,1}]}]), -     -    gse:label(F12, [{pack_xy,{{2,6},1}}, -		    {label,{text,"Trace output options:"}}, -		    {font,Font} | ?LBLOPTS]), -    gse:named_radiobutton(trace_in_window, F12, -			  [{pack_xy,{{2,6},2}}, -			   {group, trace_dest}, -			   {label,{text,"In window"}}, -			   {font,Font} | ?BTNOPTS]), -    gse:named_radiobutton(trace_to_file, F12, -			  [{pack_xy,{2,3}}, -			   {group, trace_dest}, -			   {label,{text,"To file"}}, -			   {font,Font} | ?BTNOPTS]), -    gse:named_entry(trace_file, F12, [{pack_xy,{4,3}}, {font,Font}]), -    gse:named_button(trace_file_browse, F12, -		     [{pack_xy,{6,3}}, -		      {label,{text," Browse..."}}, -		      {font,Font} | ?BTNOPTS]), - -    F13 = gse:frame(?TOP_FRAME, [{bw,3}, -				 {pack_xy,{{1,2},3}}, -				 {packer_x,[{stretch, 1}, -					    {fixed, 60}, -					    {stretch, 1}, -					    {fixed, 60}, -					    {stretch, 1}]}, -				 {packer_y,[{stretch,1}, -					    {fixed, 30}, -					    {stretch,1}]}]), -     -    gse:named_button(ok_button, F13, [{pack_xy,{2,2}}, -				      {label,{text,"OK"}}, -				      {font,Font}]), -    gse:named_button(cancel_button, F13, [{pack_xy,{4,2}}, -					  {label,{text,"Cancel"}}, -					  {font,Font}]). - -update_window_from_options(Options) -> - -    %% Trace output -    gse:config(trace_send, [{select,Options#trace_options.send}]), -    gse:config(trace_receive, -	       [{select,Options#trace_options.treceive}]), -    gse:config(trace_functions, -	       [{select,Options#trace_options.functions}]), -    gse:config(trace_events, [{select,Options#trace_options.events}]), - -    %% Trace inheritance -    case (Options#trace_options.inherit_on_all_spawn or -	  Options#trace_options.inherit_on_1st_spawn) of -	true -> -	    gse:select(trace_spawn), -	    gse:config(trace_spawn_all, -		       [{select,Options#trace_options.inherit_on_all_spawn}]), -	    gse:config(trace_spawn_first, -		       [{select,Options#trace_options.inherit_on_1st_spawn}]); -	false -> -	    lists:foreach(fun(X) -> gse:disable(X) end, -			  [trace_spawn_all,trace_spawn_first]) -    end, - -    case (Options#trace_options.inherit_on_all_link or -	  Options#trace_options.inherit_on_1st_link) of -	true -> gse:select(trace_link), -		gse:config(trace_link_all, -			   [{select,Options#trace_options.inherit_on_all_link}]), -		gse:config(trace_link_first, -			   [{select, Options#trace_options.inherit_on_1st_link}]); -	false -> -	    lists:foreach(fun(X) -> gse:disable(X) end, -			  [trace_link_all,trace_link_first]) -    end, - -    %% Trace ouput destinations -    gse:config(trace_in_window, -	       [{select,(not Options#trace_options.to_file)}]), - -    gse:config(trace_to_file, [{select,Options#trace_options.to_file}]), -    gse:config(trace_file, [{text,Options#trace_options.file}]), -    case Options#trace_options.to_file of -	true -> -	    ok; -	false -> -	    lists:foreach(fun(X) -> gse:disable(X) end, -			  [trace_file, trace_file_browse]) -    end. - -get_options_from_window() -> -    #trace_options{send = gse:read(trace_send,select), -		   treceive = gse:read(trace_receive,select), -		   functions = gse:read(trace_functions,select), -		   events = gse:read(trace_events,select), -		   inherit_on_1st_spawn = gse:read(trace_spawn_first,select), -		   inherit_on_all_spawn = gse:read(trace_spawn_all,select), -		   inherit_on_1st_link = gse:read(trace_link_first,select), -		   inherit_on_all_link = gse:read(trace_link_all,select), -		   to_file = gse:read(trace_to_file,select), -		   file = gse:read(trace_file,text)}. - -group_radio(Value, Default, GroupList) -> -    case Value of -	true -> -	    gse:select(Default), -	    lists:foreach(fun(X) -> gse:enable(X) end, GroupList); -	false -> -	    lists:foreach(fun(X) -> gse:deselect(X) end, GroupList), -	    lists:foreach(fun(X) -> gse:disable(X) end, GroupList) -    end. - -%%--read_from_file/(File)----------------------------------------------- -%% Returns the options saved in File. -%% If no options can be found, then the default options are -%% returned. - -read_from_file(File) -> -    case file:consult(File) of -	{ok, [Term]} -> -	    if -		is_record(Term, trace_options) -> -		    {ok, Term}; -		true -> -		    {error, "unexpected contents", #trace_options{}} -	    end; -	{ok, _Terms} -> -	    {error, "unexpected contents", #trace_options{}}; -	{error, Tuple} when is_tuple(Tuple) -> % {Line,Mod,Term} -	    {error, "erroneous contents", #trace_options{}}; -	{error, _Posix} -> -	    %% The most probable reason is that the file does not -	    %% exist, this is not an error so we simply return -	    %% the default trace options instead -	    {ok, #trace_options{}} -    end. - -%%--save_to_file(Options, File)----------------------------------------- - -save_to_file(Options, File) -> -    case file:open(File, [write]) of -	{ok, Fd} -> -	    {{Year,Month,Day},{H,M,S}} = calendar:local_time(), -	    io:format(Fd, "%%%~n", []), -	    io:format(Fd, "%%% File: ~s~n", [File]), -	    io:format(Fd, "%%% Date: ~w-~2..0w-~2..0w, ~2..0w:~2..0w:~2..0w~n", -		      [Year,Month,Day,H,M,S]), -	    io:format(Fd, "%%%~n", []), -	    io:format(Fd, "%%% This file was created by Pman. ~n", []), -	    io:format(Fd, "%%%~n", []), -	    io:format(Fd, "%%% DO NOT EDIT! ~n", []), -	    io:format(Fd, "%%%~n", []), -	    io:format(Fd, "%%%~n", []), -	    io:format(Fd, "~p.~n", [Options]), -	    file:close(Fd), -	    ok; -	{error, Posix} -> -	    {error, file:format_error(Posix)} -    end. diff --git a/lib/pman/src/pman_options.hrl b/lib/pman/src/pman_options.hrl deleted file mode 100644 index 047b9866c3..0000000000 --- a/lib/pman/src/pman_options.hrl +++ /dev/null @@ -1,34 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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% -%% - -%% -%% An options-record contains the return data from the option dialog. -%%  - --record(trace_options, {send=true,		     -		 treceive=true, -		 functions=true, -		 events=true, -		 to_file=false, -		 file="", -		 inherit_on_1st_spawn=false, -		 inherit_on_all_spawn=true, -		 inherit_on_1st_link=false, -		 inherit_on_all_link=true}). - diff --git a/lib/pman/src/pman_process.erl b/lib/pman/src/pman_process.erl deleted file mode 100644 index 276407a0f1..0000000000 --- a/lib/pman/src/pman_process.erl +++ /dev/null @@ -1,317 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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 : A front-end to the erlang:process_info() functions, that -%%           can handle processes on different nodes in a transparent -%%           way.  -%%	     Also some convenience functions for process info, as well -%%	     as some application specific functions for process  -%%           classification. -%%---------------------------------------------------------------------- - --module(pman_process). - --export([pinfo/1, pinfo/2, -	 r_processes/1, -	 function_info/1, -	 get_name/1, msg/1, reds/1, psize/1, -	 is_running/1, -	 is_pid_or_shell/1, -	 get_pid/1, -	 is_system_process/1, -	 is_hidden_by_module/2 -	]). - -%% List of registered name that will make a prodcess a "SYSTEM"-process  --define(SYSTEM_REG_NAMES, -	[ -	 %% kernel -	 application_controller, -	 erl_reply, -	 auth, -	 boot_server, -	 code_server, -	 disk_log_server, -	 disk_log_sup, -	 erl_prim_loader, -	 error_logger, -	 file_server_2, -	 fixtable_server, -	 global_group, -	 global_name_server, -	 heart, -	 inet_gethost_native, -	 inet_gethost_native_sup, -	 init, -	 kernel_config, -	 kernel_safe_sup, -	 kernel_sup, -	 net_kernel, -	 net_sup, -	 rex, -	 user, -	 os_server, -	 ddll_server, -	 erl_epmd, -	 inet_db, -	 pg2, - -	 %% stdlib -	 timer_server, -	 rsh_starter, -	 take_over_monitor, -	 pool_master, -	 dets, - -	 %% sasl -	 sasl_safe_sup, sasl_sup, alarm_handler, overload, -	 release_handler, - -	 %% gs -	 gs_frontend -	]). -	  -%% List of module:function/arity calls that will make the caller a  -%% "SYSTEM"-process. -%%  --define(SYSTEM_INIT_CALLS, -	[{application_master,init,4}, -	 {application_master,start_it,4}, -	 {inet_tcp_dist,accept_loop,2}, -	 {net_kernel,ticker,2}, -	 {supervisor_bridge,user_sup,1}, -	 {user_drv,server,2}, -	 {group,server,3}, -	 {kernel_config,init,1}, -	 {inet_tcp_dist,do_accept,6}, -	 {inet_tcp_dist,do_setup,6}, -	 {pman_main,init,2}, -	 {pman_buf_printer,init,2}, -	 {pman_buf_converter,init,2}, -	 {pman_buf_buffer,init,1}, -	 {gstk,init,1}, -	 {gstk_port_handler,init,2}, -	 {gstk,worker_init,1} -	]). - -%% List of module:function/arity calls that will make the executing -%% process a "SYSTEM"-process. --define(SYSTEM_RUNNING_CALLS, -	[{file_io_server,server_loop,1}, -	 {global,loop_the_locker,1}, -	 {global,collect_deletions,2}, -	 {global,loop_the_registrar,0}, -	 {gs_frontend,request,2}, -	 {shell,get_command1,5}, -	 {shell,eval_loop,3}, -	 {io,wait_io_mon_reply,2}, -	 {pman_module_info,loop,1}, -	 {pman_options,dialog,3}, -	 {pman_options,loop,1}, -	 {pman_relay_server,loop,1}, -	 {pman_shell,monitor_loop,1}, -	 {pman_shell,safe_loop,2} -	]). - -%% pinfo(Pid) -> [{Item, Info}] | undefined -%% pinfo(Pid, Item) -> Info | undefined -%% A version of process_info/1 that handles pid on remote nodes as well. -pinfo({_, Pid}) -> % Handle internal process format -    pinfo(Pid); -pinfo(Pid) when node(Pid)==node() -> -    process_info(Pid); -pinfo(Pid) -> -    case rpc:call(node(Pid), erlang, process_info, [Pid]) of -	{badrpc, _} -> undefined; -	Res -> Res -    end. - -pinfo({_, Pid}, Item) -> % Handle internal process format -    pinfo(Pid, Item); -pinfo(Pid, Item) when node(Pid)==node() -> -    case process_info(Pid, Item) of -	{Item, Info} -> Info; -	"" -> ""; % Item == registered_name -	undefined -> undefined -    end; -pinfo(Pid, Item) -> -    case rpc:call(node(Pid), erlang, process_info, [Pid, Item]) of -	{badrpc, _} -> undefined; -	{Item, Info} -> Info; -	"" -> ""; % Item == registered_name -	undefined -> undefined -    end. - -%% function_info(Pid) -> {M, F, A} -%% Returns the initial function for the specified process.  -function_info(Pid) -> -    case pinfo(Pid, current_function) of -	{Module, Function, Arity} -> -	    {Module, Function, Arity}; -	undefined -> -	    {unknown, unknown, 0} -    end. - -%% r_processes(Node) -> Pids -%% Return a list of all processes at Node. -%% -%% If there is a problem with getting information from a remote  -%% node, an empty list is returned. -r_processes(Node) -> -    ordsets:from_list(r_processes1(Node)). - -r_processes1(Node) -> -    if -	Node==node() -> -	    processes(); -	true -> -	    case rpc:block_call(Node, erlang, processes, []) of -		{badrpc, _} -> -		    []; -		Pids -> Pids -	    end -    end. - -%% is_running(Object) -> {true, {shell,Pid}} | {true, Pid} | false -%%   Object = {shell, Pid} | {link, Pid, ?} | Pid -is_running({shell,Pid}) ->  -    case is_running(Pid) of -	{true,Pid} -> -	    {true,{shell,Pid}}; -	false -> -	    false -    end; -is_running({link,Pid,_}) ->  -    is_running(Pid); -is_running(Pid) -> -    case is_pid_or_shell(Pid) of -	true -> -	    case pinfo(Pid) of -		undefined -> false; -		_PInfo -> {true, Pid} -	    end; -	false -> -	    false -    end. - -%% is_pid_or_shell(Object) -> bool() -%% Checks if the argument is an pid or a tuple {shell, Pid}. -is_pid_or_shell({shell,Pid}) when is_pid(Pid) -> -    true; -is_pid_or_shell(Pid) when is_pid(Pid) -> -    true; -is_pid_or_shell(_) -> -    false. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% get_pid/1 - returns the Pid of the object provided that  -%%   it is a proper process specifier. -%% -%% Arguments: -%%   Object	A process specifier -%% -%% Returns: -%%   The Pid. - -get_pid({shell,Pid}) -> -    Pid; -get_pid(Pid) when is_pid(Pid) -> -    Pid. - -%% is_system_process(Pid) -> bool() -%% Returns true if Pid is a "system process". -%% This is a prototype version, use file configuration later. -is_system_process(Pid) -> -    catch is_system_process2(Pid). - -is_system_process2(Pid) -> -     -    %% Test if the registered name is a system registered name -    case pinfo(Pid, registered_name) of -	undefined -> ignore; -	"" -> ignore; -	Name -> -	    case lists:member(Name, ?SYSTEM_REG_NAMES) of -		true -> throw(true); -		false -> ignore -	    end -    end, -     -    %% Test if the start specification is a "system start function" -    MFAi = case pinfo(Pid, initial_call) of -	       {proc_lib, init_p, 5} -> -		   proc_lib:translate_initial_call(Pid); % {M,F,A} | Fun -	       Res -> Res % {M,F,A} | undefined -	   end, -    case lists:member(MFAi, ?SYSTEM_INIT_CALLS) of -	true -> throw(true); -	false -> ignore -    end, - -    %% Test if the running specification is a "system running function" -    case pinfo(Pid, current_function) of -	undefined -> false; -	MFAc -> -	    lists:member(MFAc, ?SYSTEM_RUNNING_CALLS) -    end. - -%% is_hidden_by_module(Pid, Modules) -> bool() -%% Checks if Pid is to be hidden because it executes code from one -%% of Modules -is_hidden_by_module(Pid, Modules) -> -    case pinfo(Pid, current_function) of -	{Module, _Function, _Arity} -> -	    lists:member(Module, Modules); -	undefined -> false -    end. - -%% get_name(Pid) -> Name | " " -%% Returns the registered name of a process, if any, or " " otherwise. -get_name(Pid) -> -    case pinfo(Pid, registered_name) of -	undefined -> " "; -	"" -> " "; -	Name -> Name -    end. - -%% msg(Pid) -> int() -msg(Pid) -> -    case pinfo(Pid, messages) of -	undefined -> 0; -	Msgs -> length(Msgs) -    end. - -%% reds(Pid) -> int() -reds(Pid) -> -    case pinfo(Pid, reductions) of -	undefined -> 0;	     -	Reds -> Reds -    end. - -%% psize(Pid) -> int() -%% Returns the total process size (stack + heap). -psize(Pid) -> -    Stack = pinfo(Pid, stack_size), -    Heap = pinfo(Pid, heap_size), -    case {Heap, Stack} of -	{undefined, undefined} -> 0; -	{undefined, Sz} -> Sz; -	{Sz, undefined} -> Sz; -	{Sz0, Sz1}  -> Sz0 + Sz1 -    end. diff --git a/lib/pman/src/pman_relay.erl b/lib/pman/src/pman_relay.erl deleted file mode 100644 index 289765492f..0000000000 --- a/lib/pman/src/pman_relay.erl +++ /dev/null @@ -1,127 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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 : Interface function to  relay calls (esp. trace calls)  -%%           to processes on other  nodes. Some of the calls -%%           are conditionally relayed. -%%---------------------------------------------------------------------- - --module(pman_relay). - -%%-compile(export_all). --export([start/1, -	 ok_to_trace/1, -	 trac/3]). - - --include("assert.hrl"). - -%% -------------------------------------------------------------- -%%                  DISTRIBUTION -%% -------------------------------------------------------------- -%% (???) Process dictionary alert!!! -%% -%% Since we are not allowed to do erlang:trace/3 on remote -%% processe we create a help process at the remote node to -%% do the job for us  -%% --------------------------------------------------------------- - -start(P) when is_pid(P), node(P)/=node() -> -     -    %% Remote supervision, relaying necessary -     -    put(relay, spawn_link(node(P), pman_relay_server, init, [self()])); - - -start(_) -> -     -    %% Local supervision, no relaying -     -    ignore. - - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% ok_to_trace/1 - Tests wheter we can actually start tracing  -%%    a process. -%% -%% Arguments: -%%   Pid		Pid of the process to trace (on local or remote node) -%% -%% Returns -%%   true		If it is OK to trace the process -%%   false		If the process is already traced, or some other -%%			condition prevents it from being traced. - -ok_to_trace(Pid) when node(Pid) == node()-> - -    %% Local trace, no relaying - -    case catch erlang:trace(Pid, false, [send]) of -	1 -> -	    true; -	_Otherwise -> -	    false -    end; -ok_to_trace(Pid) -> - -    %% Remote trace, relaying necessary - -    PidRelay =  get(relay), -    PidRelay ! {ok_to_trace, self(), Pid}, -    receive -	{ok_to_trace, PidRelay} -> -	    true; -	{not_ok_to_trace, PidRelay} -> -	    false; -	_Otherwise -> -	    ?ALWAYS_ASSERT("Unexpected message from relay process") -    after -	5000 -> -	    false -    end. - - -     -	      -     - -%% --------------------------------------------------------------- -%% Possibly send a request to do tracing to a remote node. -%% --------------------------------------------------------------- - -trac(Pid, How, Flag) when node(Pid) == node() -> - -    %% Local trace, no relaying necessary - - -    case catch erlang:trace(Pid, How, Flag) of -	1 -> ok; -	_ -> pman_win:format("** Illegal trace request ** \n", []) -    end; -	 -trac(Pid, How, Flag) -> - - - -    %% Remote trace, relaying necessary - -    get(relay) ! {self(), erlang, trace, [Pid, How, Flag]}. - diff --git a/lib/pman/src/pman_relay_server.erl b/lib/pman/src/pman_relay_server.erl deleted file mode 100644 index 2fcbb663bc..0000000000 --- a/lib/pman/src/pman_relay_server.erl +++ /dev/null @@ -1,57 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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 : Relay server code. -%%%---------------------------------------------------------------------- - --module(pman_relay_server). - -%%-compile(export_all). --export([init/1]). - - - -init(P) -> -    process_flag(trap_exit, true), - -    loop(P). - -loop(P) -> -    receive -	{ok_to_trace, PidSender, PidToTrace} -> -	    case catch erlang:trace(PidToTrace, false, [send]) of -		1 -> -		    PidSender ! {ok_to_trace, self()}, -		    loop(P); -		_Otherwise -> -		    PidSender ! {not_ok_to_trace, self()} -	    end; - -	{P, M,F,A} -> -	    case catch apply(M, F, A) of -		1 -> ok; -		_Other ->  P ! {print, "** Illegal trace request **\n", []} -	    end, -	    loop(P); -	{'EXIT', P, _Reason} -> -	    exit(normal); -	Other ->             %% Here is the normal case for trace i/o -	    P ! Other,  -	    loop(P) -    end. diff --git a/lib/pman/src/pman_shell.erl b/lib/pman/src/pman_shell.erl deleted file mode 100644 index 2d2b8ce000..0000000000 --- a/lib/pman/src/pman_shell.erl +++ /dev/null @@ -1,827 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1996-2012. 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: Create a trace window with process  -%%          information or a help window with information  -%%          about pman. -%% -%% --------------------------------------------------------------- - --module(pman_shell). --compile([{nowarn_deprecated_function,{gs,config,2}}, -          {nowarn_deprecated_function,{gs,destroy,1}}, -          {nowarn_deprecated_function,{gs,start,0}}, -          {nowarn_deprecated_function,{gs,start,1}}]). - -%% --------------------------------------------------------------- -%% The user interface exports  -%% --------------------------------------------------------------- - --export([start_list/3, -	 start/2, -	 start/1, -	 find_shell/0]). - -%% --------------------------------------------------------------- -%% Includes -%% --------------------------------------------------------------- --include("assert.hrl"). --include("pman_options.hrl"). --include("pman_buf.hrl"). - - -%% --------------------------------------------------------------- -%% Internal record declarations -%% --------------------------------------------------------------- --record(pman_shell,{win, -		    editor, -		    pid, -		    buffer, -		    father, -		    shell_flag,			% boolean, true for shell -		    trace_options,		% Keeps trace options -		    db}).                       % DB for trace windows - - -%% -%% Constants -%% - --define (PMAN_DB, pman_db).  % The pman db for trace windows - - - -%% --------------------------------------------------------------- -%% start/1, start/2 -%% -%% Starts a new trace shell process. -%% -%% start(Pid, DefaultOptions) -%% Pid			The Pid of the process to trace -%% DefaultOptions	The default trace options passed along from -%%			the calling process. -%% -%% -%% start(Pid) -%% Pid                   The Pid of the process to trace -%% -%% start(Pid) starts without using any default options except for those -%% hardwired into the application. (See pman_options.hrl). -%% -%% -%% Return: Both functions return a process id -%% --------------------------------------------------------------- - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% start_list/3 - Starts a trace window for each of the processes -%%    in the list - -start_list(LIPid, Father, Options) -> -    StartFun = fun(Pid) -> -		       start({Pid,Father}, Options) -	       end, -    lists:foreach(StartFun, LIPid). - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% start/1  - Starts a trace window for the specified Pid. -%% - -start(Pid) -> -    start(Pid, #trace_options{}). - -%% -%% start/2 -%% - -start(Pid,DefaultOptions) when is_pid(Pid) -> -    start({Pid,self()}, DefaultOptions); - -start(Var,DefaultOptions) -> -    Db = db_start(), -    spawn_link(fun() -> internal(Var, DefaultOptions, Db) end). -     -%% --------------------------------------------------------------- -%% Initialize the enviroment for tracing/viewing Object -%% -%% Object can either be {shell,Shell} or a Pid. -%% The main loop is then called, which handles trace and event  -%% requests. The window dies whenever Supervisor dies, while -%% message windows die whenever their parent dies. -%% --------------------------------------------------------------- - -internal({Object,Supervisor}, DefaultOptions, Db) -> - -    %% (???) This call will cause minor problems when the window has been -    %% invoked with proc/1 from for instance the shell.  The shell -    %% does not handle the exit-signals, so it will exit -    %% when the window is exited. -     - -    %% First check that no other process is tracing the process we want -    %% to trace. There is no well defined way of doing this, so the  -    %% code below is used instead. (???) - -    pman_relay:start(Object),				%(???) Uses proc. dict. - -    Pid = pman_process:get_pid(Object), - -    case pman_relay:ok_to_trace(Pid) of - -	%% Tracing cannot be performed on the specified process - -	false -> -	    T = lists:flatten(io_lib:format("ERROR: Process ~p is already being~ntraced by some other process.~nOr there may be a problem communicating with it.",[Pid])), -	    tool_utils:notify(gs:start(),T), -	    exit(quit); - -	%% Tracing can be performed, go ahead! - -	true -> -	     -	    case db_insert_key (Db, Pid) of -		true -> -	     -		    link(Supervisor), -		    process_flag(trap_exit, true), - -		    case catch pman_win:window(Object) of -			{'EXIT', badrpc} -> -			    T = "ERROR: Could not access node", -			    pman_win:dialog_window(gs:start(),T); -			{'EXIT', dead} -> -			    T = "ERROR: The process is dead", -			    pman_win:dialog_window(gs:start(),T); -			{'EXIT',_W} ->   -			    T = "ERROR: Untracable process \n(unexpected EXIT reason)", -			    pman_win:dialog_window(gs:start(),T); -			{Win, Ed} -> -			    init_monitor_loop(Win, -					      Ed, -					      Object, -					      Supervisor, -					      DefaultOptions, -					      Db) -		    end; -		 -		false -> -		    T = lists:flatten(io_lib:format("ERROR: Process ~p is already being~ntraced by some other process.",[Pid])), -		    tool_utils:notify(gs:start(),T), -		    exit(quit); - -		Error -> -		    Error -	    end -	     -	end. - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% init_monitor_loop/5  - -init_monitor_loop(Win,Ed,Object,Supervisor, DefaultOptions, Db) -> - -    process_flag(priority, max), -     -    %% Most default options come from the main window. Now we must set -    %% the default file name to something that is shows what process -    %% is being traced. - -    %% Find out an appropriate file name to write the trace output -    %% to if the output should go to a file. - -    FileName = case pman_process:is_pid_or_shell(Object) of -		   true -> -		       default_file_name(pman_process:get_pid(Object)); -		   false -> -		       "NoName" -	       end, - -    Buff = pman_buf:start(Ed, FileName),       - -    case pman_process:is_running(Object) of - -	%% We are tracing a shell process. -	{true,{shell,Pid}} -> -	    safe_link(Pid), -	    NewDefaultOptions = -		DefaultOptions#trace_options{file=FileName}, -	    perform_option_changes(Pid, NewDefaultOptions, Buff), -	    monitor_loop(#pman_shell{win=Win, editor=Ed, pid=Pid, buffer=Buff, -				     father = Supervisor, -				     shell_flag = true, -				     trace_options = NewDefaultOptions, -				     db = Db}); - -	%% We are tracing an ordinary process. -	{true,Pid} -> - 	    safe_link(Pid), -	    NewDefaultOptions = -		DefaultOptions#trace_options{file=FileName}, -	    perform_option_changes(Pid, NewDefaultOptions, Buff), -	    monitor_loop(#pman_shell{win=Win, editor=Ed, pid=Pid, buffer=Buff, -				     father = Supervisor, -				     shell_flag = false, -				     trace_options = NewDefaultOptions, -				     db = Db}); - -	%% The process being traced is dead. -	false -> -	    monitor_loop(#pman_shell{win=Win, editor=Ed, pid=nopid, -				     buffer=Buff, -				     father = Supervisor, -				     shell_flag = false, -				     trace_options= DefaultOptions, -				     db = Db}) -    end. - -%% ---------------------------------------------------------------- -%% What is the Pid of the shell on our node? -%%  ---------------------------------------------------------------- - -find_shell() -> -    case shell:whereis_evaluator() of -	undefined ->				% noshell -	    noshell; -	Pid -> -	    Pid -    end. - -%% --------------------------------------------------------------- -%% Functions called in case of an exit message  -%% --------------------------------------------------------------- - -clean_up(Win, Buff,Pid) -> - -    %% (???) Unlinks the traced process, but since we are using a safe link -    %% it is probably unnecessary. - -    safe_unlink(Pid),  - -    %% Kill helper processes - -    exit(Buff#buffer.converter, topquit), -    exit(Buff#buffer.buffer, topquit), - -    gs:destroy(Win). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% exit_cmd/3 - Takes care of the necessary details when -%%    a linked process terminates. - - -exit_cmd(Pid,_Reason, State) -> -    case State#pman_shell.shell_flag of - -	%% This clause handles the case when a shell process dies. -	%% Since it is restarted and the intention is to continue tracing -	%% the restarted shell process, we need to handle it separately by -	%% finding the new shell process. -	true -> -	     -	    NewShell = find_shell(), -	    safe_link(NewShell), -	    pman_relay:start(NewShell), - -	    %% Update the window title with the new PID -	    Title = pman_win:title({shell, NewShell}), -	    Win = State#pman_shell.win, -	    gse:config(Win,[{title,Title}]), - -	    pman_relay:trac(NewShell, true, flags()), - -	    B = State#pman_shell.buffer, -	    B#buffer.converter!{raw,[{shell_died, Pid, NewShell}]}, - - - -	    State#pman_shell{pid=NewShell}; - -	%% This clause handles the case when a traced process that is -	%% not a shell process dies. -	false -> - -	    B = State#pman_shell.buffer, -	    B#buffer.converter!{raw,[{died, Pid}]}, - -	    lists:foreach(fun(X) -> gse:disable(X) end, -			  ['Options', -			   'Kill', -			   'LinksMenu']), -	    State#pman_shell{pid=undefined} -    end. - -flags() -> -    [send, 'receive', call, procs, -     set_on_spawn, set_on_first_spawn, set_on_link, set_on_first_link]. - -options_to_flaglists(Options) -> -    AssocList = -	[{Options#trace_options.send, send}, -	 {Options#trace_options.treceive, 'receive'}, -	 {Options#trace_options.inherit_on_1st_spawn, set_on_first_spawn}, -	 {Options#trace_options.inherit_on_all_spawn, set_on_spawn}, -	 {Options#trace_options.inherit_on_1st_link, set_on_first_link}, -	 {Options#trace_options.inherit_on_all_link, set_on_link}, -	 {Options#trace_options.events, procs}, -	 {Options#trace_options.functions,call}], - -    TrueFun = fun ({Option,Flag}) -> -		      case Option of -			  true -> Flag; -			  _Otherwise -> false -		      end -	      end, -    TrueFlags = mapfilter(TrueFun, AssocList), - -    FalseFun = fun ({Option,Flag}) -> -		       case Option of -			   false -> Flag; -			   _Otherwise -> false -		       end -	       end, -    FalseFlags = mapfilter(FalseFun, AssocList), -    {TrueFlags,FalseFlags}. -     - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% mapfilter/2 - Combines the functionality of lists:map and -%%   lists:filter. mapfilter applies the function argument to -%%   each element in the list. All returned values that are  -%%   not false will occur in the resulting list. -%% -%% Arguments: -%%   Fun	A fun that takes one argument -%%   List	A list. Each element will become an argument to Fun. -%% -%% Returns: -%%  A list of all results from the map operation that are not false. -%% - -mapfilter(Fun,[E|Es]) -> -    case apply(Fun,[E]) of -	false -> -	    mapfilter(Fun,Es); -	Value -> [Value | mapfilter(Fun,Es)] -    end; -mapfilter(_Fun, []) -> []. -  - -		       -perform_option_changes(Pid,Options,Buffer) -> - -    %% Notify the trace output functionality -    %% if the destination is supposed to go to a file... - -    case Options#trace_options.to_file of -	true ->  -	    FName = Options#trace_options.file, -	    Buffer#buffer.converter!{file,FName}; -	false -> -	    done -    end, - -    %%...then set the trace flags of the traced process - -    {OnFlags, OffFlags} = options_to_flaglists(Options), -    case catch begin -		    -		   %% (???) Note that the following calls cannot actually fail -		   %% This may be a problem. And the catch appears unnecessary -		   %% However, it may become necessary to let the  -		   %% pman_relay:trac/3 function retrun appropriate values. -		   pman_relay:trac(Pid,true, OnFlags), -		   pman_relay:trac(Pid,false, OffFlags) -	       end of -	true -> -	     ok; -	_ -> pman_win:format("** Illegal trace request ** \n", []) -    end. - - - - - - -%% --------------------------------------------------------------- -%% Take care of the command executed by the user. - -execute_cmd(Cmd,Shell_data) -> -    Window = Shell_data#pman_shell.win, -    Editor = Shell_data#pman_shell.editor, -    Shell = Shell_data#pman_shell.pid, -    Buffer = Shell_data#pman_shell.buffer, -    TraceOptions = Shell_data#pman_shell.trace_options, - -    case Cmd of -	'Close' -> -	    db_delete_key (Shell_data#pman_shell.db, Shell_data#pman_shell.pid), -	    clean_up(Window, Buffer, Shell), -	    exit(quit); -	'Destroy' -> -	    db_delete_key (Shell_data#pman_shell.db, Shell_data#pman_shell.pid), -	    exit(Buffer#buffer.buffer,topquit), -	    safe_unlink(Shell), -	    exit(Buffer#buffer.converter,topquit), -            exit(Buffer#buffer.buffer,topquit), -	    exit(quit); - -	'Clear' when is_pid(Shell) -> -	    New_buffer = pman_buf:clear(Buffer,pman_win:display(Shell), -				       TraceOptions#trace_options.file), -	    Shell_data#pman_shell{buffer = New_buffer}; -	'Save buffer' -> -	    DefaultFile = "Pman_buffer." ++ default_file_name(Shell), -	    Result = tool_utils:file_dialog([{type,save}, -					     {file,DefaultFile}]), -	    case Result of -		{ok, UserFile, _State} ->	     -		    Buffer#buffer.buffer!{save_buffer,UserFile}; -		{error,_Reason} -> -		    true -	    end, -	    Shell_data; -	'Help' -> -	    HelpFile = filename:join([code:lib_dir(pman), "doc", "html", "index.html"]), -	    tool_utils:open_help(gs:start([{kernel, true}]), HelpFile), -	    Shell_data; -	'Kill' when is_pid(Shell)  ->		 -	    exit(Buffer#buffer.converter,killed), -            exit(Buffer#buffer.buffer,killed), -	    lists:foreach(fun(X) -> gse:disable(X) end, -			  ['TraceMenu', -			   'Clear']), -	    catch exit(Shell, kill), -	    Shell_data#pman_shell{pid = undefined}; -	'All Links' when is_pid(Shell)  -> -	    LIPid = pman_process:pinfo(Shell, links), -	    ?ALWAYS_ASSERT("Just a brutal test"),	    	     -	    start_list(LIPid, -		       Shell_data#pman_shell.father, -		       Shell_data#pman_shell.trace_options),  -	    Shell_data; -	'Module' when is_pid(Shell) -> -	    {ModuleName,_,_} = pman_process:function_info(Shell), -	    pman_module_info:start(ModuleName), -	    Shell_data; -	'Options' when is_pid(Shell) -> -	    case pman_options:dialog(Window, -                                     "Trace Options for Process", -                                     TraceOptions) of -		{error, _Reason} -> -		    Shell_data; -		Options -> -		    perform_option_changes(Shell, Options, Buffer), -		    Shell_data#pman_shell{trace_options=Options} -	    end; -	 -	{trac,Choice,Bool} when is_pid(Shell) -> -	    pman_relay:trac(Shell, Bool, [Choice]), -	    Shell_data; - - -	{configure,{X,Y}} -> -	    configure (Editor, X, Y), -	    Shell_data; - -	Pid when is_pid(Pid) -> -	    pman_shell:start({Pid, Shell_data#pman_shell.father}, -			     Shell_data#pman_shell.trace_options), -	    Shell_data; -	_Other -> -	    ?ALWAYS_ASSERT("Received unexpected event"), -	    Shell_data -    end. -	     - -default_file_name(Shell) when is_pid(Shell) -> -    [A,B,C] =  string:tokens(pid_to_list(Shell),[$.,$<,$>]), -    "pman_trace." ++ A ++ "_" ++ B ++ "_" ++ C; -default_file_name(_OTHER) -> -    "shell". - - - - - -%% Key accellerators - -key(e) -> 'Clear'; -key(s) -> 'Save buffer'; -key(c) -> 'Close'; -key(a) -> 'All'; -key(r) -> 'Reset'; -key(m) -> 'Module'; -key(l) -> 'All Links'; -key(k) -> 'Kill'; -key(h) -> 'Help'; -key(z) -> 'Close'; -key(O) -> O. - - - -%% --------------------------------------------------------------- -%% The main loop takes care of data coming in from the traces, as  -%% well as exit signals from proceses we are monitoring. Events -%% caused by the user or window manager are also handled here. -%% --------------------------------------------------------------- - - -monitor_loop(Shell_data) -> -    receive - -	%% WM destroy -	{gs,_Window,destroy,[],[]} ->  %%Avoid links menus -	    execute_cmd('Destroy', Shell_data); - - -	%% Handle EXIT signal from parent process -	{'EXIT', _Pid, topquit} -> -	    clean_up(Shell_data#pman_shell.win, -		     Shell_data#pman_shell.buffer, -		     Shell_data#pman_shell.pid), -	    exit(topquit); - -	%% (???) Ignore "stray" EXIT signal from converter -	{'EXIT', _Pid, win_killed} -> -	    monitor_loop(Shell_data); - - -	%% Handle EXIT signal from safely linked Pid -	%% This is received when a traced process dies. -	{'SAFE_EXIT', Pid, Reason} -> -	    New_Shell_data = exit_cmd(Pid, Reason,Shell_data ), -	    monitor_loop(New_Shell_data); - - -	%% Handle EXIT signal from processes where we expect -	%% some EXIT signals, such as the file_dialog opened, and possibly -	%% others.  - -	{'EXIT', _Pid, _Reason} -> -	    monitor_loop(Shell_data); - -	%% Handle incoming trace messages -	Message when is_tuple(Message) , element(1,Message) == trace-> -	    {L, Suspended} = collect_tracs([Message]), -	    Buffer = Shell_data#pman_shell.buffer, -	    Buffer#buffer.converter!{raw,L}, -	    lists:foreach(fun(P) -> erlang:resume_process(P) end, Suspended), -	    monitor_loop(Shell_data); - - -	%% All other messages on the form {...,...,...} -	Message when is_tuple(Message) -> -	    do_link_stuff(Shell_data), -	     -	    New_Shell_data = process_gs_event(Message,Shell_data), -	    monitor_loop(New_Shell_data); - -	%% Catch all for unexpected messages -	_Anything -> -	    ?ALWAYS_ASSERT("Received unexpected event"),	     -	    monitor_loop(Shell_data) -	   -    end.		 -			 -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% process_event/1 - Error handling wrapper for gs_cmd - -process_gs_event(Message, Shell_data) -> -    case catch gs_cmd(Message,Shell_data) of - -	%% -	%% Error exits from gs_cmd - -	{'EXIT', badrpc} -> -	    Text = "\nERROR: Could not access node", -	    pman_win:msg_win(Text), -	    Shell_data; -	{'EXIT', dead} -> -	    Text = "\nERROR: The process is dead", -	    pman_win:msg_win(Text), -	    Shell_data; - -	%% A controlled application initiated termination -	{'EXIT', quit} -> -	    db_delete_key (Shell_data#pman_shell.db, Shell_data#pman_shell.pid), -	    exit(quit); - - -	{'EXIT',Reason} -> -	    db_delete_key (Shell_data#pman_shell.db, Shell_data#pman_shell.pid), -	    io:format("Debug info, Reason: ~p~n",[Reason]), -	    ?ALWAYS_ASSERT("Unexpected EXIT reason"), -	    exit({unexpected_EXIT_reason,Reason}); -	 -	%% -	%% "Proper" exits from gs_cmd - -	New_Shell_data -> -	    New_Shell_data -    end. - - - -gs_cmd(Cmd, Shell_data) -> -      case Cmd of - -	  %%User Command -	  {gs, Command, click, _Data, _Args}       -> -	      execute_cmd(Command,Shell_data); - -	  %%Key accellerator -	  {gs,_Window,keypress,_D,[Key,_,0,1]}     -> -	      execute_cmd(key(Key),Shell_data); - -	  %%Window Resize -	  {gs,_Window,configure,_,[X,Y|_]}        -> -	      execute_cmd({configure,{X,Y}},Shell_data); - - -	  {gs, _Object, _Event, _Data, _Args} -> -	      ?ALWAYS_ASSERT("Unhandled gs event"), -	      Shell_data -	   -    end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% (???) do_link_stuff/1 - I have no clue. -%% - -do_link_stuff(Shell_data) -> - -    %% This appears to be code to execute for adding -    %% dynamic links menus. - -    case Shell_data#pman_shell.pid of -	undefined -> -	    ok; -	Pid -> -	    case pman_process:pinfo(Pid, links) of -		Links when is_list(Links) -> -		    pman_win:links_menus(Links); -		undefined -> -		    ok -	    end -    end. - - -%% (???) Process dictionary used to safe Pid-Pid pairs. -%%  -%% safe_link/1 - Spawns a process, that links to the Pid, and sends -%%    a message to the caller when the linked process dies. -%% -%% Since we (think we) need to link to the traced process, we want -%% to do it in a way that has the smallest possible risk. The process -%% that links to the Pid is small and simple, which is safer than if -%% the calling process would link directly to the Pid. - -safe_link(Pid) when is_pid(Pid) -> -    Self = self(), -    PidSafe = spawn_link(fun() -> safe_init(Self, Pid) end), -    put(Pid, PidSafe). -     - -%% safe_unlink/1 - Removes a safe link -%% - -safe_unlink(Pid) when is_pid(Pid) -> -    PidSafe = get(Pid), -    PidSafe ! {unlink, self(), Pid}, -    erase(Pid); - -safe_unlink(_Anything)-> -    true. - -%% safe_init/2 - Initialize a simple receive loop that controls safe linking -%%    to application processes. -%%  -safe_init(Caller, Pid) -> - -    process_flag(trap_exit, true), -    link(Pid), - -    safe_loop(Caller, Pid). - - -%% safe_loop/2 - Simply waits for an exit signal from the linked Pid, -%%   all other messages are disregarded. -%%  - - -safe_loop(Caller, Pid) -> -    receive -	%% Linked process dies -	{'EXIT' , Pid, Reason} -> -	    Caller ! {'SAFE_EXIT', Pid, Reason}; - -	%% Caller dies -	{'EXIT', Caller, _Reason} -> -	    unlink(Pid); -	 - -	%% Unlink request -	{unlink, Caller, Pid} -> -	    unlink(Pid); - -	%% Ignore everything else -	_Anything -> -	    safe_loop(Caller, Pid) -    end. -	     -     - -configure (Editor, W, H) -> -    gs:config (Editor, [{width, W - 3}, -			{height, H - 40}]). -     - - - -%%% The DB is used to avoid multiple trace windows  -%%% of the same process. - -%%% db_start  /0 -%%% - -db_start() -> -    case ets:info(?PMAN_DB) of -	undefined -> ets:new(?PMAN_DB, [public, named_table]); -	_ -> ?PMAN_DB -    end. - - - -%%% db_insert_key  /2 -%%% - -db_insert_key (Db, Pid) -> -    case ets:lookup (Db, Pid) of -	[] -> -	    case catch ets:insert (Db, {Pid}) of -		true -> -		    true; -		 -		_Error -> -		    error_insert_db -	    end; - -	_already_exists -> -	    false -    end. - - - -%%% db_delete_key  /2 -%%% - -db_delete_key (Db, Pid) -> -    ets:delete (Db, Pid). - - -%% Function to collect all trace messages in the receive queue. -%% Returns: {Messages,SuspendedProcesses} - -collect_tracs(Ack) -> collect_tracs(Ack, ordsets:new()). -     -collect_tracs(Ack, Procs) -> -    receive -	Trac when is_tuple(Trac), element(1, Trac) == trace -> -	    P = suspend(Trac, Procs), -	    collect_tracs([Trac | Ack], P) -    after 0 -> -	    {lists:reverse(Ack), ordsets:to_list(Procs)} -    end. - -suspend({trace,From,call,_Func}, Suspended) when node(From) == node() -> -    case ordsets:is_element(From, Suspended) of -	true -> Suspended; -	false -> -	    case (catch erlang:suspend_process(From)) of -		true -> -		    ordsets:add_element(From, Suspended); -		_ -> -		    Suspended -	    end -    end; -suspend(_Other, Suspended) -> Suspended. diff --git a/lib/pman/src/pman_tool.erl b/lib/pman/src/pman_tool.erl deleted file mode 100644 index 36382745af..0000000000 --- a/lib/pman/src/pman_tool.erl +++ /dev/null @@ -1,146 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-2012. 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% -%% --module(pman_tool). --compile([{nowarn_deprecated_function,{gs,read,2}}]). - -%% Listbox selection window - --export([select/3]). - --record(state, {topwin, -		frame, -		listbox}). - -%% Constants --define(WIN_WIDTH, 350). --define(WIN_HEIGHT, 350). - -select(Win, Title, Choices) -> -    Self = self(), -    Pid = spawn_link(fun() -> init(Self, Win, Title, Choices) end), -    receive  -	{Pid, Result} -> -	    Result -    end. - -init(Pid, Win, Title, Choices) -> - -    %% Create window -    State = create_window(Win, Title, Choices), - -    gse:map(State#state.topwin), -     -    %% enter event loop -    loop(Pid, Choices, State). - -loop(Pid, Choices, State) -> -    receive -	{gs, _, destroy, _Data, _Args} -> -	    Pid ! {self(), cancelled}; -	{gs, _, configure, _Data, [W, H|_]} -> -	    gse:resize(State#state.frame, W, H), -	    loop(Pid, Choices, State); -	{gs, _, click, ok, _Args} -> -	    case gs:read(State#state.listbox, selection) of -		[] -> -		    Pid ! {self(), cancelled}; -		Indices -> -		    Selection = selection(Indices, Choices), -		    Pid ! {self(), Selection} -	    end; -	{gs, _, click, cancel, _Args} -> -	    Pid ! {self(), cancelled}; -	{gs, Obj, doubleclick, _Data, _Args} -> -	    self() ! {gs, Obj, click, ok, []}, -	    loop(Pid, Choices, State); -	_GSEvent -> -	    loop(Pid, Choices, State) -    end. - -selection(Indices, Choices) -> -    selection(0, Indices, Choices). - -selection(I, [I|Is], [{Val,_Str}|Vals]) -> -    [Val | selection(I+1, Is, Vals)]; -selection(I, [I|Is], [Val|Vals]) -> -    [Val | selection(I+1, Is, Vals)]; -selection(_I, [], _Vals) -> -    []; -selection(I, Is, [_Val|Vals]) -> -    selection(I+1, Is, Vals). -     -create_window(Win, Title, Choices) -> -    Font = pman_win:font(Win), - -    %% Top window and a frame that covers it entirely, to allow -    %% usage of the packer for geometry management. -    Topwin = gse:window(Win, [{width, ?WIN_WIDTH}, -			      {height,?WIN_HEIGHT}, -			      {configure, true}, -			      {title, Title}]), -    Frame = gse:frame(Topwin, [{packer_x,[{stretch,1}, -					  {stretch,1}]}, -			       {packer_y,[{stretch,1}, -					  {stretch,5}, -					  {stretch,1}]}]), - -    %% Caption above the list of items -    CaptionTxt = "Select one or more of the following:", -    gse:label(Frame, [{pack_x,{1,2}}, -		      {pack_y,{1,1}}, -		      {label,{text,CaptionTxt}}, {font,Font}]), - -    %% List of selectable items -    Listbox = gse:listbox(Frame, [{pack_x,{1,2}}, -				  {pack_y,{2,2}}, -				  {selectmode,multiple}, -				  {doubleclick, true}, -				  {font,Font}, -				  {items, str_choices(Choices)}]), - -    %% OK and Cancel buttons in a separate frame. -    F13 = gse:frame(Frame, [{bw,1}, -			    {pack_xy,{{1,2},3}}, -			    {packer_x,[{stretch,1}, -				       {fixed, 60}, -				       {stretch,1}, -				       {fixed, 60}, -				       {stretch,1}]}, -			    {packer_y,[{stretch,1}, -				       {fixed, 30}, -				       {stretch,1}]}]), - -    gse:button(F13, [{pack_xy,{2,2}}, -		     {label,{text,"OK"}}, {font,Font}, -		     {data,ok}]), -    gse:button(F13, [{pack_xy,{4,2}}, -		     {label,{text,"Cancel"}}, {font,Font}, -		     {data,cancel}]), - -    gse:resize(Frame, ?WIN_WIDTH, ?WIN_HEIGHT), -    #state{topwin=Topwin, frame=Frame, listbox=Listbox}. - -str_choices(Choices) -> -    lists:map( -      fun({Val, Str}) -> -	      lists:flatten(io_lib:format("~p: ~s", [Val, Str])); -	 (Term) -> -	      lists:flatten(io_lib:format("~p", [Term])) -      end, -      Choices). diff --git a/lib/pman/src/pman_win.erl b/lib/pman/src/pman_win.erl deleted file mode 100644 index aec7dc4412..0000000000 --- a/lib/pman/src/pman_win.erl +++ /dev/null @@ -1,677 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1996-2013. 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:  window management and the gs interface -%% ------------------------------------------------------------ - --module(pman_win). --compile([{nowarn_deprecated_function,{gs,button,2}}, -          {nowarn_deprecated_function,{gs,canvas,2}}, -          {nowarn_deprecated_function,{gs,config,2}}, -          {nowarn_deprecated_function,{gs,create,3}}, -          {nowarn_deprecated_function,{gs,create,4}}, -          {nowarn_deprecated_function,{gs,destroy,1}}, -          {nowarn_deprecated_function,{gs,read,2}}, -          {nowarn_deprecated_function,{gs,start,1}}, -          {nowarn_deprecated_function,{gs,text,2}}, -          {nowarn_deprecated_function,{gs,window,2}}]). - -%% --------------------------------------------------------------- -%% The user interface exports  -%% --------------------------------------------------------------- - --export([pman_window/3, window/1, module_data/1, display/1, format/2, -	 dialog_window/2, configeditor/2, configwin/3, -	 update/1, update/3, -	 msg_win/1, title/1, -	 remove_menu/1, add_menu/3, -	 change_colour/3, links_menus/1, calc_columnwidths/1]). --export([font/0, font/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Constants -%% --include("pman_win.hrl"). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% pman_window/3 - Create a GS window and components for the -%%   Pman overview window, the main window. -%% -%% Arguments: -%%   Size		number of processes -%%   HiddenModules	list of modules  -%%   Nodes		list of supervised nodes -%% -%% Return:  -%%   {Win, Grid, Frame, Procnum, W, H} where -%%   Win	The GS top window -%%   Grid	The GS grid -%%   Procnum	Number of displayed processes -%% - -pman_window(Size, _HiddenModules, Nodes) -> -    GS = gs:start([{kernel,true}]), -    Font = font(GS), -    Win_Options = [{title, lists:concat(["Pman: Overview on ",node()])}, -		   {width, ?WIN_WIDTH}, {height, ?WIN_HEIGHT}, -		   {destroy, true}, -		   {keypress,true}], -    Win = gs:create(window, GS, Win_Options), - -    %% Menu bar -    MenuBar = gs:create(menubar, Win, []), -    MBFile = gs:create(menubutton, MenuBar, [{label,{text," File "}}, -					     {font,Font}, -					     {underline,1}]), -    MBView = gs:create(menubutton, MenuBar, [{label,{text, " View "}}, -					     {font,Font}, -					     {underline,1}]), -    MBTrace = gs:create(menubutton, MenuBar, [{label,{text, " Trace "}}, -					      {font,Font}, -					      {underline,1}]), -    MBHelp = gs:create(menubutton, MenuBar, [{label, {text, " Help "}}, -					     {font,Font}, -					     {side,right}, -					     {underline,1}]), - -    %% Addition of a menu for distribution -    add_node_menu(MenuBar, Nodes, Font), - -    %% All menu buttons -    MenuFile = gs:create(menu, MBFile, []), -    MenuView = gs:create(menu, MBView, []), -    MenuTrace = gs:create(menu, MBTrace, []), -    MenuHelp = gs:create(menu, MBHelp, []), - -    %% File menu -    gse:named_menuitem('Default Options', MenuFile, -		       [{label,{text,"Options..."}}, {font,Font}, -			{underline,0}]), -    gse:named_menuitem('Save Options',MenuFile, -		       [{label,{text,"Save Options"}}, {font,Font}]), -    gse:named_menuitem('Exit', MenuFile, -		       [{label,{text,"Exit"}}, {font,Font}, -			{underline,0}]), - -    %% View menu -    gse:named_menuitem('Hide All',MenuView, -		       [{label, {text, "Hide All Processes"}}, -			{font,Font}, -			{underline,1}]), - -    gse:named_menuitem('Hide Modules', MenuView, -		       [{label, {text, "Hide Modules..."}}, -			{font,Font}, -			{underline,8}]), - -    gse:named_menuitem('Hide Selected Process', MenuView, -		       [{label, {text, "Hide Selected Process"}}, -			{font,Font}, -			{underline,2}]), - -    gse:named_menuitem('Module',MenuView, -		       [{label, {text, "Module Info..."}}, {font,Font}, -			{underline,7}]), - -    gse:named_menuitem('Refresh', MenuView, -		       [{label, {text, "Refresh"}}, {font,Font}, -			{underline,0}]), - -    gse:named_menuitem('Show All',MenuView, -		       [{label, {text, "Show All Processes"}}, -			{font,Font}]), - -    gse:named_menuitem('Show Selected',MenuView, -		       [{label, {text, "Show Processes..."}}, -			{font,Font}]), - -    %% Trace menu -    gs:create(menuitem, 'Kill', MenuTrace, [{label,{text, "Kill"}}, -					    {font,Font}, -					    {underline,0}]), - -    gs:create(menuitem, 'Trace Process', MenuTrace, -	      [{label, {text, "Trace Selected Process"}}, {font,Font}, -	       {underline,0}]), - -    gs:create(menuitem,'Trace Shell', MenuTrace, -	      [{label, {text,"Shell Process"}}, {font,Font}, -	       {underline,0}]), - -    %% Help menu -    gs:create(menuitem,'Help', MenuHelp,  [{label, {text, "Help" }}, -					   {font,Font}, -					   {underline,0}]), - -    %% Window contents - -    %% Geometry managing frame -    Frame = gse:frame(Win, [{y,?MENU_HEIGHT}, -			    {packer_x,[{stretch, 1}]}, -			    {packer_y,[{stretch,10}, -				       {fixed,?CHECKBAR_HEIGHT}]}]), - - - -    %% Grid  -    Grid_Options = [ -		    {pack_x,1}, {pack_y,1}, -		    {fg,black},  -		    {vscroll,right},{hscroll,bottom}, -		    calc_columnwidths(739), -		    {rows, {1,Size}}],  -    Grid = gse:grid(Frame,Grid_Options), - - -    %% Checkbutton bar at the bottom of the window - -    CheckBar = gse:frame(Frame, [{pack_x,1}, -				 {pack_y,2}, -				 {packer_x,[{stretch, 2, 100,300}, -					    {stretch, 2, 100,300}, -					    {stretch,1}, -					    {stretch, 2,100,300}]}, -				 {packer_y,[{stretch,1}]}]), -    gse:named_checkbutton('Hide System',CheckBar, -			  [{pack_xy,{1,1}}, -			   {justify, left}, -			   {align,w}, -			   {width, 200}, -			   {font, Font}, -			   {label, {text, "Hide System Processes" }}]), -     -    gse:named_checkbutton('Auto Hide New',CheckBar, -			  [{pack_xy,{2,1}}, -			   {width, 200}, -			   {justify, left}, -			   {align,w}, -			   {font, Font}, -			   {label, {text, "Auto-Hide New" }}]), -     -    gse:named_label('Number Hidden',CheckBar, -			  [{pack_xy,{4,1}}, -			   {justify, left}, -			   {align,w}, -			   {width, 200}, -			   {font, Font}, -			   {label, {text, ?CPIDHIDDENTEXT }}]), - -    %% Finalize it! -    gse:map(Win), -    gse:config(Win,[raise]), -    gse:config(Win,[{configure,true}]), - - -    {Win, Grid, Frame, length(processes())+1, ?WIN_WIDTH, ?WIN_HEIGHT}. - - -%% Calculate columnwidths in respect to the size of the window. - -calc_columnwidths(Width) -> -    if -	Width =< 739 ->  -	    {columnwidths,[75,215,146,90,105,105]}; -       true ->  -	    S = (Width - 75)/(215+146+90+105+105), -	    {columnwidths,[75,round(215*S),round(146*S),round(90*S), -			   round(105*S),round(105*S)]} -    end. - -%% --------------------------------------------------------------- -%% Create a trace window -%% -%% Process, a process id or an atom -%% -%% Return: A window and a editor -%% --------------------------------------------------------------- - - -window(Process) -> -    GS = gs:start([{kernel,true}]), -    Font = font(GS), -    Win_Options = [{title,title(Process)}, {width,550}, {keypress,true},  -		   {configure,true}, -		   {destroy,true},{height, 400}], -    Win = gs:create(window,GS,Win_Options), -     -    MenuBar = gs:create(menubar, Win, []), - -    %% File menu -    MBFile =  gs:create(menubutton,MenuBar,[{label,{text," File "}}, -					    {font,Font}, -					    {underline, 1}]), -    MenuFile = gs:create(menu, MBFile, []), -    make_menus(pman_process:is_running(Process), MenuBar, MenuFile, -	       Font), - -    gse:named_menuitem('Save buffer',MenuFile, -		       [{label,{text, "Save buffer..."}}, -			{font,Font}, -			{underline,0}]), -    gse:named_menuitem('Close',MenuFile, -		       [{label, {text, "Close"}}, -			{font,Font}, -			{underline,0}]), - - -    Editor = gs:create(editor,Win,[{x,3}, {y,40}, -				   {width,546}, {height,348}, -				   {font,Font}]), -    gs:config(Editor, [{keypress, true},{insert, {'end', display(Process)}}]), -    gs:config(Editor, [{enable, false},{vscroll, right}, {hscroll, bottom}, -		       {wrap,none}]), -    gs:config(Win, [{map, true}]), -    {Win, Editor}. - -%% --------------------------------------------------------------------- -%% Menu Help Fuctions -%% --------------------------------------------------------------------- - - -links_menus(Links) -> -    gs:destroy('Links'), -    gs:create(menu,'Links','LinksMenu',[]), -    Flag =  case links_menus(Links,[]) of -		[] -> false; -		Pids -> -		    add_menu('Links', Pids, "Trace"), -		    true -	    end, -    gse:config('LinksMenu',[{enable,Flag}]). -	     -links_menus([],Pids) -> Pids; -links_menus([Pid|Links],Pids) when is_pid(Pid) -> -    links_menus(Links,[Pid|Pids]); -links_menus([_Port|Links],Pids) -> -    links_menus(Links,Pids). - - -%% Create the node menu.  - -add_node_menu(MenuBar, Nodes, Font) -> -    MBNode = gs:create(menubutton, MenuBar, [{label,{text, " Nodes "}}, -					     {font,Font}, -					     {underline, 1}]), -    gs:create(menu, node, MBNode, []), -    add_menu(node, Nodes, "Show", Font), -    gse:disable(node()). - - -%% --------------------------------------------------------------------- -%% Add Menus in the list under Menu menuitem. - -add_menu(Menu, Names, Tag) -> -    add_menu(Menu, Names, Tag, font()). - -add_menu(_Menu, [], _Tag, _Font) -> ok; -add_menu(Menu, [Name|Names], Tag, Font) -> -    Title = io_lib:format("~s ~p",[Tag, Name]), -    gs:create(menuitem,Name,Menu,[{label,{text,Title}}, -				  {font,Font}, -				  {data,{Menu,Name}}]), -    add_menu(Menu, Names, Tag, Font). - -%% --------------------------------------------------------------------- -%% Remove a specific menu item, or a whole menu, or a list of both. -%% - -remove_menu(List) when is_list(List)-> -    lists:foreach(fun(X) -> gs:destroy(X) end, List); - -remove_menu(Object) -> -    gse:destroy(Object). - - -%% --------------------------------------------------------------------- -%% If the trace window opened is supposed to trace a real pid, let us -%% add the trace menu, and other items specific to tracing. If not, -%% the only menus available are the ones in the default defined in -%% window(Pid). - -make_menus(false, _, _, _) -> ok; -make_menus({true,Pid}, MenuBar, MenuFile, Font) -> -    MBView = gs:create(menubutton,'ViewMenu',MenuBar, -				[{underline,1}, -				 {label,{text," View "}}, {font,Font}, -				 {side,left}]), -    MenuView = gs:create(menu, MBView, []), - -    MBTrace = gs:create(menubutton,'TraceMenu',MenuBar, -			      [{underline,1}, -			       {label,{text," Trace "}}, {font,Font}, -			       {side,left}]), -    MenuTrace = gs:create(menu, MBTrace, []), - - -    MBHelp =  gs:create(menubutton,'HelpMenu',MenuBar, -			      [{underline,1}, -			       {label,{text," Help "}}, {font,Font}, -			       {side,right}]), -    MenuHelp = gs:create(menu, MBHelp, []), - -    %% File menu -    gse:named_menuitem('Options', MenuFile, -		       [{label, {text, "Options..."}}, {font,Font}, -			{underline,0}]), - -    %% Trace menu -    gse:named_menuitem('All Links', MenuTrace, -		       [{label, {text, "All Linked Processes"}}, -			{font,Font}, -			{underline,0}]), -    gse:named_menuitem('LinksMenu', MenuTrace, -		       [{underline,0}, -			{label, {text, "Linked Process..."}}, -			{font,Font}, -			{itemtype, cascade}, -			{enable,false}]), -    gs:create(menu,'Links','LinksMenu',[]), -    case pman_process:pinfo(Pid, links) of -	Links when is_list(Links) -> -	    links_menus(Links); -	undefined -> -	    lists:foreach(fun(X) -> gse:disable(X) end,['LinksMenu']) -    end, -    gse:named_menuitem('Kill', MenuTrace, -		       [{label, {text, "Kill"}}, {font,Font}, -			{underline,0}]), - -    %% View menu -    gse:named_menuitem('Clear', MenuView, -		       [{label, {text, "Clear buffer"}}, {font,Font}, -			{underline,0}]), - -    gse:named_menuitem('Module', MenuView, -		       [{label, {text, "Module Info"}}, {font,Font}, -			{underline,0}]), - -    %% Help menu -    gse:named_menuitem('Help', MenuHelp, -		       [{label, {text, "Help"}}, {font,Font}, -			{underline,0}]). - -%% --------------------------------------------------------------------- -%% Configurate the actual editor -%% -%% Editor, actual editor -%% Options, actual options for the editor -%% -%% Return: A configurated editor with the actual options -%% --------------------------------------------------------------------- - -configeditor(Editor, Options) -> -    gs:config(Editor, Options). - -%% --------------------------------------------------------------------- -%% Configure the actual window after it has been resized. -%% --------------------------------------------------------------------- - -configwin(Object, W, H) -> -    Dx = abs(W - gs:read(Object,width) - 4), -    Dy = abs(H - gs:read(Object,height) - 42), -    if -	Dx + Dy =/= 0 -> -	    gs:config(Object,[{width,W - 4}]); -	true -> ok -    end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% update/1, 3 -update(NoOfHidden) -> -    Str = lists:flatten(io_lib:format(?CPIDHIDDENTEXT++"~w", -				      [NoOfHidden])), -    gse:config('Number Hidden', [{label, {text,Str}}]). -     -update(Grid, ShowInfoR, NoOfHidden) -> - -    %% We reverse the list because we want the processes to appear with -    %% the newest (=highest) pid first in the list. -    ShowInfo = lists:reverse(ShowInfoR), - -    %% Set the length of the grid -    CGridline = length(ShowInfo) + 1, -    gs:config(Grid, [{rows, {1,CGridline}}]), - -    %% Add the header line  -    add_gridline(Grid, -		 1, -		 {'Pid','Current Function','Name','Msgs','Reds','Size'}, -		 []), - -    update(NoOfHidden), - -    %% Recurse through the ordset of pids -    update_r(Grid, ShowInfo, 2). - -update_r(Grid, [], Row) -> -    delete_gridlines(Grid, Row); -update_r(Grid, [{Pid,Func,Name,Msgs,Reds,Psize}|ShowInfo], Row)  ->  -    {M, F, A} = Func, -    FuncText = lists:flatten(io_lib:format("~w:~w/~w", [M, F, A])), -    add_gridline(Grid, -		 Row,  -		 {Pid, FuncText, Name, Msgs, Reds, Psize}, -		 [{data,{pidfunc,Pid,Func}}]), -    update_r(Grid, ShowInfo, Row+1). - -add_gridline(Grid, Row, Tuple, LIOptSpec) -> -    {Pid, FuncText, Name, Msgs, Reds, Psize} = Tuple, -    LIOpt = [{click,true}, -	     {doubleclick,true}, -	     {fg, colour(Row)}, -	     {text,{1,Pid}}, -	     {text,{2,FuncText}}, -	     {text,{3,Name}}, -	     {text,{4,Msgs}}, -	     {text,{5,Reds}}, -	     {text,{6,Psize}} |LIOptSpec], -    case gs:read(Grid, {obj_at_row, Row}) of -	undefined -> -	    gse:gridline(Grid,[{row, Row}|LIOpt]); -	GridLine -> -	    gs:config(GridLine,LIOpt) -    end. -     -delete_gridlines(Grid, Row) ->  -    case gs:read(Grid, {obj_at_row, Row}) of -	undefined -> -	    ok; -	GridLine -> -	    gs:destroy(GridLine), -	    delete_gridlines(Grid, Row+1) -    end. - -colour(1) -> -    ?HEADER_COLOUR; -colour(_Row) -> -    ?UNSELECTED_COLOUR. - -%% Interchange colours between two rows -change_colour(Grid, Row, Row) -> -    Gitem = gs:read(Grid, {obj_at_row,Row}), -    gs:config(Gitem, {fg,?SELECTED_COLOUR}); -change_colour(Grid, From, To) -> -    Gitem_to = gs:read(Grid, {obj_at_row,To}), -    Gitem_fr = gs:read(Grid, {obj_at_row,From}), -    gs:config(Gitem_to, {fg,?SELECTED_COLOUR}), -    gs:config(Gitem_fr, {fg,colour(From)}). -     -%% -------------------------------------------------------------- -%% Create a title for the window -%% Return: the title -%% -------------------------------------------------------------- - -title({module, Mod}) -> -    lists:flatten([io_lib:format("Pman: Module info ~p", [Mod])]); - -title({shell,  Sh} ) -> -    lists:flatten([io_lib:format("Pman: Shell process ~p on ~p", -				 [Sh,node(Sh)])]); - -title(Sh) -> -    lists:flatten([io_lib:format("Pman: Process ~p on ~p", -				 [Sh, node(Sh)]),name(Sh)]). -name(Pid) -> -    case pman_process:pinfo(Pid, registered_name) of -	undefined -> ""; -	Name -> -	    lists:flatten([io_lib:format("[~p]", [Name])]) -    end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% module_data/1 - %% Returns the module information for a -%%   module, on a format suitable to insert into a GS editor. -%% -%% Arguments: -%%   ModuleName		The module -%% -%% Returns: -%%   A string with module information. -%% - -module_data(ModuleName) -> -    vformat("", catch apply(ModuleName, module_info, [])). - - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% display/1 -  -%% - -display({_,Pid,_}) -> display(Pid); -display({_,Pid}) -> display(Pid); -display(Pid) when is_pid(Pid) -> -    case pman_process:pinfo(Pid) of -	undefined -> -	    format('Process is dead~n',[]); -	Other -> -	    proc_format(Other) -    end. - -%% -------------------------------------------------------------- -%% Format functions for the shell and help window. -%% -------------------------------------------------------------- - -vformat(Pad, {M,F,A}) when is_atom(F) ->  -    Pad2 = lists:append(Pad,mkpad(io_lib:format("~w:~w",[M,F]))), -    lists:flatten([format("~p:~p", [M,F]),argformat(Pad2, A)]); - -vformat(Pad, [H|T]) -> -    kvformat(Pad, [H|T],"["); - -vformat(_Pad, X) -> format("~p~n", [X]). - -format(Format) -> format(Format, []). - -format(Format, Args) -> -   io_lib:format(Format, Args). -    - -kvformat(S, [Item],Buff) -> -    lists:reverse([format("\n~s~p]\n",[S,Item])|Buff]); - -kvformat(S,[H|T],Buff) -> -    kvformat(S,T,[format("\n~s~p, ",[S,H])|Buff]); - -kvformat(_,[],Buff) ->  -    lists:reverse(["]\n"|Buff]). - -argformat(_Pad,A) when is_integer(A) -> -    format("/~p\n", [A]); -argformat(_,A) -> -    lists:flatten([format("/~p\n", [length(A)]), -		   format("args: \n"), -		   argformat2("      ", A)]). - -argformat2(Pad, Arglist) -> -    Chars = lists:flatten(io_lib:format("~p",[Arglist])), -    if -	length(Chars) < (70 - length(Pad)) -> -	    format("~s~s\n", [Pad, Chars]); -	true -> -	    argformat3(Pad, Arglist) -    end. - -argformat3(_,[]) -> format("\n"); -argformat3(Pad, [H|T]) -> -    Chars = truncate(65,io_lib:format("~s~p",[Pad, H])), -    format("~s,\n", [Chars]), -     argformat3(Pad, T). - -pformat(false) -> []; -pformat({value,{_, 0}}) -> []; -pformat({value,{_, []}}) -> []; -pformat({value, {Key, Vals}}) -> -    Pad = mkpad(io_lib:format("~p ",[Key])), -    format(lists:flatten(["~p: " ,vformat(Pad, Vals), "~n"]), [Key]). -    -truncate(0, _Chars) -> "....."; -truncate(I, [H|T]) -> [H|truncate(I-1, T)]; -truncate(_I, []) -> []. - -mkpad([_|T]) -> [32|mkpad(T)]; -mkpad([]) -> []. - -proc_format(Pi) ->  %% process_info struct -    X1 = pformat(lists:keysearch(initial_call, 1, Pi)), -    X2 = pformat(lists:keysearch(current_function, 1,Pi)), -    X3 = pformat(lists:keysearch(messages, 1,Pi)), -    X4 = pformat(lists:keysearch(dictionary,1, Pi)), -    X5 = pformat(lists:keysearch(heap_size, 1,Pi)), -    X6 = pformat(lists:keysearch(stack_size, 1,Pi)), -    X7 = pformat(lists:keysearch(reductions, 1,Pi)), -    X8 = pformat(lists:keysearch(links, 1,Pi)), -    X9 = pformat(lists:keysearch(trap_exit, 1,Pi)), -    lists:flatten([X1, X2, X3, X4, X5,X6,X7,X8,X9]). - - -%% Using the tool_utils function for presenting messages. -dialog_window(GSParent, Text) -> -    spawn_link(tool_utils, notify, [GSParent, Text]). - -%% Create a window with a dismiss button. -msg_win(Text) -> -    spawn_link(fun() -> display_msg_win(Text) end). - -display_msg_win(Text) -> -    GS = gs:start([{kernel,true}]), -    Font = font(GS), -    Win = gs:window(GS, [{width,200}, {height,75}, {destroy,true}, -			 {title,"Pman Message"}]), -    Can = gs:canvas(Win, [{width,200}, {height, 75},{x,0},{y,0}]), -    gs:text(Can, [{text,Text}, {coords,[{10,0}]}, {justify,center}]), -    Btn = gs:button(Win, [{label,{text,"Dismiss"}}, {font,Font}, -			  {width,100}, {x,50}, {y,40}]), -    gs:config(Win, {map,true}), -    receive -	{gs, Btn, click, _, _} -> -	    ok -    end. - -%% Choose default font -font() -> -    font(gs:start([{kernel,true}])). - -font(GS) -> -    case gs:read(GS, {choose_font, {screen,[],12}}) of -	Font when element(1, Font)==screen -> -	    Font; -	_ -> -	    gs:read(GS, {choose_font, {courier,[],12}}) -    end. diff --git a/lib/pman/src/pman_win.hrl b/lib/pman/src/pman_win.hrl deleted file mode 100644 index 8a2778d5b7..0000000000 --- a/lib/pman/src/pman_win.hrl +++ /dev/null @@ -1,39 +0,0 @@ -%% -%% %CopyrightBegin% -%%  -%% Copyright Ericsson AB 1997-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% -%% - --define(WIN_HEIGHT, 390). --define(WIN_WIDTH, 745). - --define(MENU_HEIGHT, 40). --define(CHECKBAR_HEIGHT, 40). - --define(CPIDHIDDENTEXT, "# Hidden: "). - --define(HEADER_COLOUR, blue). --define(UNSELECTED_COLOUR, black). --define(SELECTED_COLOUR, white). - - - - - - - - - | 
