Dynamic connection to a remote tool in a distributed processing system environment used for debugging6058393Abstract The present invention provides a dynamic connection for distributed applications that need to locate application development tools, including but not limited to debuggers, trace collection tools, compilers, etc.) which may be running on different machines, and to send the tools messages. The program requesting debugging service (i.e., a debugger client) sends, to a tool locator, criteria which specifies the properties of a desired debugger. The tool locator maintains a registry of all tools, e.g. debuggers, and their properties, which remain active within the network by receiving tool registration information from each tool as it is started on any machine within the network. When a message is received by the tool locator from a debugger client specifying the criteria of a desired debugger, the tool locator searches its registry and returns a list of debuggers matching the specified properties along with a communication endpoint address that can be used to establish a connection with a debugger meeting the criteria. The debugger client then sends a message, using the established connection, to the desired debugger requesting debugging services on behalf of the debugger client or another program. As a result, a dynamic connection is made, at run time, between an application program and a debugger having certain desired properties wherein the debugger may be active, if at all, at any time on any machine within the network. Claims We claim: Description BACKGROUND OF THE INVENTION
______________________________________
DEBUGEE A program that is to be debugged.
DEBUGGER SERVER
A program that provides debugging
services (e.g., a distributed
debugger front-end).
DEBUGGER CLIENT
A program that sends a request to a
debugger server to start a debugging
session on a debugee. The debugee can
be the debugger client itself, or another
program running anywhere on the
network.
MONITOR/CONTROLLER
A program that is attached to the debugee
by the debugger server to monitor and
control its execution and read and write
state information (e.g., a distributed
debugger back-end).
______________________________________
The debugger client will call a debugger library routine to send a message to a debugger server that contains the information necessary for the debugger server to locate the debugee and obtain authorization to start a debugging session. Additionally, the message will include the instruction address in the debugee where the user would like the debugging session to begin (e.g., the current instruction address of the debugee or at entry to a routine in the debugee program). The debugger server may or may not be running on the same machine as the debugee. To locate the debugger server a component named TOOL LOCATOR is used. The debugger client and debugger server can communicate with the tool locator through a socket connection such as a connectionless internet family socket that is bound to an internet address specified in an environment variable named TOOLLOCATORHOST, and a reserved well-known port. FIG. 2 shows the steps of a debugger client requesting debugging services for another program. When a debugger server 100 is started, it will register itself with the tool locator 200, (message 20, FIG. 2) indicating that it is available to service debugging requests. A debugger client 210, can then send a message 204 to request debugging services for itself or for another program running on the network. It does this by first sending a message 202 to the tool locator to locate a debugger server specified by the debugger client 210. The tool locator 200 will return the socket address of a debugger server that matches the debugger client's specification, message 203. The debugger client 210 then sends a "debugIt" message 204 to the debugger server 100 to request debugging service from the debugger server. The debugger server 100 will then attach a monitor/controller 101 (FIG. 1) to the debugee 111, message 205. Tool Locator The tool locator is a general purpose mechanism for locating programs that have certain properties in a distributed environment. An application program (i.e., the debugger client) can call a debugger library routine which will use the tool locator to find a distributed debugger front-end (i.e., the debugger server) which has registered with certain properties such as the user ID its running under, the machine its running on, the X-Windows display its using, the programming languages and operating systems it supports, etc. When a distributed debugger front-end is started, it can call a debugger library routine to register with the tool locator passing to it a string that contains a list of the form "property-name=property-value" separated by commas. This string is referred to as the "property list". For example, the string: "hostname=atlantic,userid=hpan,opersys=AIX,language=C,language=CP P" could be used to indicate that the distributed debugger is running on a host named "atlantic" under the user ID "hpan" and that it supports the debugging of programs written in C and C++ on AIX.TM.. The following is the grammar for the property list: property-list: one-property.vertline.one-property, property-list; one-property: property-name=property-value; property-name: string; property-value: string; A "string" is an sequence of alpha-numeric characters and all special characters except "=" and ",". The application program could then execute the debugMe debugger library routine specifying a search criteria as one of its arguments to indicate that it is looking for any debugger front-end running under the user ID "hpan" that supports C++ on AIX.TM.. The search criteria argument is a string that contains conjunctions and disjunctions of "property-name=property-value" pairs. Parenthesis can be used to specify precedence. There are no predefined property names or property values, they are simply arbitrary sequences of case insensitive alpha-numeric characters. For example, the string: "userid=hpan and machtype=rs6000 and opersys=AIX and language=C and language=CPP" could be used to locate any debugger front-end running on any host under the user ID of "hpan" that supports the debugging of C and C++ programs running on a AIX.TM. on a RISC System/6000. For another example, the string: "opersys=WindowsNT and language=CPP and machtype=PowerPC and ((userid=hpan and hostname=davinci) or (userid=meier and hostname=atlantic) or userid=fuh)" could be used to locate any distributed debugger front-end that supports programs written in C++ for Windows NT.TM. on a PowerPC.TM. that is either running under the user ID of "hpan" on a host named "davinci" or running under the user ID of "meier" on a host named "atlantic" or running under the user ID of "fuh" on any host. All of the above examples, including, but not limited to, expressions using "AND," "OR," "NOT", etc., can be broadly categorized as expressing the search criteria in a boolean expression. The tool locator would then return a socket address of the first debugger front-end that matches the criteria to the debugMe routine. If more than one debugger font-end matches the search criteria then their socket address can be retrieved by subsequently executing a series of "FindNext" debugger library calls to the tool locator. The debugMe routine will use the socket address to create a socket connection and send a message to the debugger font-end requesting it to attach a monitor/controller to the process that is running the external program. The following is the grammar for the search criteria: search-criteria: search-and.vertline.search-criteria OR search-and; search-and: one-property]search-and AND one-property; one-property: property-name=property-value](search-criteria); property-name: string; property-value: string; A "string" is a sequence of alpha-numeric characters and all special characters except "=" and ",". The "AND" operator has higher precedence than the "OR" operator. Application Program Interface The tool locator has an application program interface (API) that can logically be broken down into 2 sets of routines. One set of routines is called by a debugger server, and the other set of routines is called by a debugger client. In the preferred embodiment, all communication is done by using internet sockets. Routines Called by the Debugger Server
______________________________________
CREATEREGISTEREDSOCKET
Create a socket and add its
socket address to the tool
locator registry.
CLOSEREGISTEREDSOCKET
Close a socket and delete its
socket address from the tool
locator registry.
STILLALIVE Inform the tool locator that the
debugger server is still available to
provide debugging services.
______________________________________
Routines Called by the Debugger Client
______________________________________
BEGINSEARCH Begin a search of the tool
locator registry to locate a
debugger server.
FINDNEXT Get the socket address of the
next debugger server that matches
the given specification.
ENDSEARCH End the search of the tool
locator registry.
______________________________________
Data Types The following describes a set of data types used by the tool locator. Socket Address In this invention a pair of sockets are used for communication between: The debugger server and the tool locator. The debugger client and the tool locator. The debugger client and the debugger server. Each socket is bound to a socket address. These socket addresses are used by the socket library routines to locate the two end-points of the communication. The following is the C language definition of a socket address. typedef struct { unsigned char len; unsigned char family; unsigned short port; unsigned long addr; } socketaddress.sub.-- t; Where: LEN is the length of the socket address (always 6). FAMILY is the socket family (always AF.sub.-- INET). PORT is the port address of the socket. ADDR is the 32 bit internet address of the machine. The tool locator of this preferred embodiment supports only the internet type socket address (i.e., family type AF.sub.-- INET). Message Messages are sent via socket communication using the RECVFROM, and SENDTO socket library routines. In a heterogeneous distributed computing environment there will be differences in the way that data is represented on different machine architectures. For example, integers are represented differently on a IBM.TM. RISC System/6000 than they are on an IBM.TM. PC. To handle these differences EXTERNAL DATA REPRESENTATION (XDR) library routines are used to encode all components of a message before a sendto routine is executed, and to decode the components of a message after the recvfrom routine is executed. The following is the C language definition of a message. typedef struct { unsigned char type; char data[1000]; } message.sub.-- t; Where: Type A one byte unsigned integer that represents the message type that is used to identify a particular MESSAGE HANDLER routine. The valid values are: 1. register 2. unregister 3. still alive 4. begin search 5. find next 6. end search 7. debug it Data The rest of the message. This is decoded as appropriate by the message handler. Tool Locator Registry The tool locator registry is used and maintained by the tool locator to keep track of all of the registered debugger servers. When a debugger server is registered with the tool locator a structure is allocated and appended to the end of a linked list of structures. The following is the C language definition of a registry item. typedef struct PROPERTYSTRUCT { PROPERTYSTRUCT *next; char *name; char *value; Where: NEXT is a pointer to the next property item. NAME is a character sting which contains the name of the property. VALUE is a character sting which contains the value of the property. typedef struct REGISTRYSTRUCT { REGISTRYSTRUCT *next; REGISTRYSTRUCT *previous; PROPERTYSTRUCT *propertylist; socketaddress.sub.-- t sockaddr; int interval; time.sub.-- t timestamp; } registry.sub.-- t; Where: NEXT is a pointer to the next registry item. PREVIOUS is a pointer to the previous registry item. PROPERTYLIST is a pointer to a linked list of properties. SOCKADDR is socket address of the debugger server. INTERVAL is frequency in seconds that the debugger server promised to send still alive messages. If 0 then the debugger server will not be sending any still alive messages. TIMESTAMP is the time that the entry was initialized or the last time a still alive messages was received. Search Session List The search session list is used and maintained by the tool locator to keep track of all of the requests from debugger clients to search the tool locator registry for a debugger server. When a debugger client sends a begin search message, a structure is allocated that represents the search session list item. This item is appended to the end of the search session list. The following is the C language definition of a registry item. typedef struct SESSIONSTRUCT { SESSIONSTRUCT *next; SESSIONSTRUCT *previous; socketaddress.sub.-- t sockaddr; char *searchcriteria; registry.sub.-- t *cursor; } session.sub.-- t; Where: NEXT is a pointer to the next search session item. PREVIOUS is a pointer to the previous search session item. SOCKADDR is a socket address of the debugger client. This socket address is used as the key to the search session list. SEARCHCRITERIA is a string that contains the search criteria that was specified as an argument of the call to the BeginSearch routine. CURSOR is a pointer to the registry item that was found as a result of the most recent call to the FindNext routine. Tool Locator API Routines The following describes a set of Application Program Interface (API) routines provided by the tool locator. These API routines will be called by debugger servers and debugger clients. RegisterTool Routine Register a tool and an associated property list with the tool locator and return a connectionless internet family socket. The caller must supply a property list. The routine will return a connectionless internet family socket to the caller (i.e., the debugger server) which will be used to communicate with any of its debugger clients or the tool locator using the recvfrom and sendto socket library routines. void RegisterTool(char *propertylist, int interval, int *dbgserversocket, int *status); where: PROPERTYLIST A string that contains a property list. INTERVAL The debugger server promises to send a still alive message to the tool locator every interval seconds. If the tool locator stops receiving still alive messages from the debugger server, it can free up its entry in the tool locator registry. A value of 0 means that the debugger server will not be sending any still alive messages and therefore the tool locator should keep its tool locator registry entry until it receives an unregister message. DBGSERVERSOCKET A pointer to a variable of type int where a socket is returned that can be used by the debugger server to communicate with any of its debugger clients. STATUS A pointer to an int where the status code is returned. The values returned will be one of:
______________________________________
ERROR.sub.-- STATUS.sub.-- OK
normal completion
NO.sub.-- TOOL.sub.-- LOCATOR.sub.-- HOST
The environment
variable
TOOLLOCATORHOST
is not set.
TOOL.sub.-- LOCATOR.sub.-- NOT.sub.-- RESPONDING
The tool locator is
not responding.
______________________________________
StillAlive Routine Inform the tool locator that the debugger server is still available. Its C declaration is: void StillAlive(int dbgserversocket, int *status); where: DBGSERVERSOCKET The socket that was returned by the call to RegisterTool. This socket is used by the debugger server to communicate with its debugger clients and the tool locator. STATUS a pointer to an int where the status code is returned. The values returned will be one of:
______________________________________
ERROR.sub.-- STATUS.sub.-- OK
normal completion
NO.sub.-- TOOL.sub.-- LOCATOR.sub.-- HOST
The environment
variable
TOOLLOCATORHOST
is not set.
TOOL.sub.-- LOCATOR.sub.-- NOT.sub.-- RESPONDING
The tool locator
is not responding.
INVALID.sub.-- SOCKET
The specified
socket is not valid.
______________________________________
UnregisterTool Routine Close a socket that was created by RegisterTool and remove it from the tool locator registry. Its C declaration is: void UnregisterTool(int dbgserversocket, int *status); where: DBGSERVERSOCKET The socket that was returned by the call to CreateRegisteredSocket. This socket is used by the debugger server to communicate with its debugger client and the tool locator. STATUS a pointer to an int where the status code is returned. The values returned will be one of:
______________________________________
ERROR.sub.-- STATUS.sub.-- OK
normal completion
NO.sub.-- TOOL.sub.-- LOCATOR.sub.-- HOST
The environment
variable
TOOLLOCATORHOST
is not set.
TOOL.sub.-- LOCATOR.sub.-- NOT.sub.-- RESPONDING
The tool locator
is not responding.
INVALID.sub.-- SOCKET
The specified socket
is not valid.
______________________________________
BeginSearch Routine Begin a search of the tool locator registry to locate a debugger server. A search criteria can be specified. To search the tool locator registry the debugger client executes a call to BeginSearch specifying a search criteria. The debugger client will then make one or more calls to FindNext. Each call will return the socket address of a debugger server that matches the search criteria specified on the BeginSearch call. Once a suitable debugger server is found, a call to EndSearch is made to end the search. The BeginSearch routine will create a connectionless internet socket and return it to the caller (i.e., the debugger client). This socket is used to communicate with the tool locator and must be passed on all subsequent calls to FindNext and EndSearch. The EndSearch routine will close the socket. The C declaration for this routine is: void BeginSearch(char *searchcriteria, int *dbgclientsocket, int *status); where: SEARCHCRITERIA A string that contains a search criteria. DBGCLIENTSOCKET A pointer to a variable of type int where a socket is returned that can be used by the debugger client to communicate with the tool locator. STATUS a pointer to an int where the status code is returned. The values returned will be one of:
______________________________________
ERROR.sub.-- STATUS.sub.-- OK
normal completion
NO.sub.-- TOOL.sub.-- LOCATOR.sub.-- HOST
The environment
variable
TOOLLOCATORHOST
is not set.
TOOL.sub.-- LOCATOR.sub.-- NOT.sub.-- RESPONDING
The tool locator
is not responding.
______________________________________
FindNext Routine Find the next debugger server and return a socket address that can be used to communicate with that server. The C declaration for this routine is: void FindNext(int dbgclientsocket, socketaddress.sub.-- t *dbgserversockaddr, int *status); where: DBGCLIENTSOCKET The socket that was returned by the call to BeginSearch. This socket is used by the debugger client to communicate with the tool locator. DBGSERVERSOCKADDR A pointer to a variable of type socketaddress.sub.-- t where the socket address is returned that the debugger client can use to communicate with the debugger server. STATUS a pointer to an int where the status code is returned. The values returned will be one of:
______________________________________
ERROR.sub.-- STATUS.sub.-- OK
normal completian
NO.sub.-- MORE No more debugger
servers can be found.
NO.sub.-- BEGIN.sub.-- SEARCH
A call to BeginSearch
must be made before
calling FindNext.
NO.sub.-- TOOL.sub.-- LOCATOR.sub.-- HOST
The environment
variable
TOOLLOCATORHOST
is not set.
TOOL.sub.-- LOCATOR.sub.-- NOT.sub.-- RESPONDING
The tool locator
is not responding.
______________________________________
EndSearch Routine End the search of the tool locator registry and close the socket that was created by the BeginSearch routine. The C declaration for this routine is: void EndSearch(int dbgclientsocket, int *status); where: DBGCLIENTSOCKET The socket that was returned by the call to BeginSearch. This socket is used by the debugger client to communicate with the tool locator. STATUS a pointer to an int where the status code is returned. The values returned will be one of:
______________________________________
ERROR.sub.-- STATUS.sub.-- OK
normal completion
NO.sub.-- TOOL.sub.-- LOCATOR.sub.-- HOST
The environment
variable
TOOLLOCATORHOST
is not set.
TOOL.sub.-- LOCATOR.sub.-- NOT.sub.-- RESPONDING
The tool locator
is not responding.
NO.sub.-- BEGIN.sub.-- SEARCH
A call to BeginSearch
must be made before
calling EndSearch.
______________________________________
Tool Locator Message Handler Routines These routines handle messages that are received from various debugger clients and debugger servers via a connectionless internet socket that is bound to the well known port address of the tool locator. The recvfrom and sendto socket library routines are used to communicate with the debugger clients and debugger servers. The recvfrom will read both a message and the socket address of the debugger client or debugger server that sent the message. This socket address is used to send response back via the sendto routine and to uniquely identify a session between the tool locator and a debugger client or debugger server. Register Message Handler Routine The register message contains a property list and the frequency, in number of seconds, that the debugger server promises to send still alive messages. The socket address of a debugger server is returned by the recvfrom socket library routine call. An item is appended to the end of the tool locator registry which includes the property list, the debugger server socket address, and the frequency that still alive messages will be sent by the debugger server. Still Alive Message Handler Routine The still alive message contains a socket address which is used to locate the tool locator registry entry for the debugger server. A time-stamp in this entry is updated to indicate the last time the tool locator heard from the debugger server. If the tool locator doesn't receive a still alive message from a debugger server after a certain number of seconds that was specified when the debugger server was registered, then its entry will be removed from the tool locator registry. Unregister Message Handler Routine The unregister message contains a socket address which is used to delete the tool locator registry entry for the debugger server. Before the tool locator registry entry is deleted, all of the items in the search session list are examined to determine if the current cursor points to the registry entry that will be deleted. If it does, then the current cursor is set to the previous tool locator registry entry. If there is no previous entry, (i.e. we are deleting the first entry in the tool locator registry), then the current cursor is set to NULL. Begin Search Message Handler Routine The begin search message contains a search criteria. The socket address of a debugger client is returned by the recvfrom socket library routine call. An item is added to a search session list which is keyed by the socket address of the debugger client. The new search session item will contain information such as the search criteria and the current cursor position in tool locator registry (see "Search Session List"). Find Next Message Handler Routine The find next message does not contain any data. The socket address of a debugger client is returned by the recvfrom socket library routine call. The socket address of the debugger client is used to locate a search session list item that was created by the begin search message handler. The item contains the current cursor position in the tool locator registry. The first time a find next message is received, the cursor position will be at the beginning of the tool locator registry. A search of the tool locator registry is done using the search criteria specified in the begin search message from the debugger client. The search criteria is applied to each of the property lists stored in the tool locator registry entries. These property lists were previously supplied by the various debugger servers when they registered with the tool locator. When a match occurs, the socket address of the debugger server from the tool locator registry is written back to the debugger client. The current cursor position in the search session list item is updated to point to the matched tool locator registry item. End Search Message Handler Routine The end search message does not contain any data. The socket address of a debugger client is returned by the recvfrom socket library routine call. The socket address of the debugger client is used to delete the entry from the search session list. Tool Locator Control Flow A daemon process is needed for the tool locator and is invoked according to the following steps as shown in FIG. 3, which illustrates the control flow of a tool mapper daemon. Step 301: Create a connectionless internet socket. Step 302: Bind the socket to the well-known port address of the tool locator. Step 303: Execute a recvfrom on the socket to receive a message and the socket address of the tool locator client. Step 304: Remove all expired tool locator registry entries. Step 305: Call a message handler routine based on the received message type. Step 306: Go to 303. Debugger Debugger Client Application Program Interface Debugger clients will call the following two application program interfaces (API) routines provided by the debugger library to request debugging services. DebugIt Routine A call to the debugit routine is made passing a search criteria which is used to locate a debugger server. The arguments to the debugit routine include all of the information necessary for that debugger server to locate a particular application program and attach a monitor/controller to it. void debugit(char *searchcriteria, char *inetaddr, char *userid, char *password, int addrspaceid, int threadid, unsigned int instraddr; char *dbgservargs, int *status); where:
__________________________________________________________________________
SEARCHCRITERIA A string that contains the search criteria
described above. If NULL is specified, then the
current value of the DEBUGSEARCHCRITERIA
environment variable will be used.
INETADDR The internet address of the machine where the
debugee is running.
USERID The user ID that the debugee is running under.
PASSWORD The password of the user ID that the debugee is
running under.
ADDRSPACEID The address-space ID (i.e., UNIX .TM. process ID)
that the debugee is running under.
THREADID The thread ID that the debugee is running
under.
INSTRADDR The instruction address where the debugging
session should begin. If zero is specified
then the current instruction address of the
debugee is used.
DBGSERVARGS is a string that can contain arguments for the
debugger (e.g. where to find source code).
STATUS a pointer to an int where the status code is
returned. The values returned will be one of:
ERROR.sub.-- STATUS.sub.-- OK
normal completion
DBG.sub.-- NO.sub.-- DEBUGGER.sub.-- SERVER.sub.-- FOUND
No debugger server found
that matches the
specified search
criteria.
DBG.sub.-- DEBUGGER.sub.-- SERVER.sub.-- REJECT
The debugger server has
rejected the request for
debugging services.
__________________________________________________________________________
For example: debugIt("hostname=davinci and userid=hpan and language=CPP", "thistle.stl.ibm.com", "meier", "mypasswd", 35647, 1, 0, "-s /u/hpan/code -s /u/hpan/src", &status); will cause the following to occur (refer to FIG. 4): Step 401: Look for an environment variable named DEBUGME. If found and value is NO return to caller. Otherwise continue with next step. Step 402: Look for an environment variable named TOOLLOCATORHOST that specifies the internet address of the tool locator. If the TOOLLOCATORHOST environment variable is not defined then the internet address of the current host is used. Step 403: Execute a BeginSearch routine passing the search criteria. The BeginSearch routine will return a connectionless internet socket that is used to communicate with both the tool locator and the debugger server. Step 404: Execute a FindNext routine which, if successful, returns the socket address of the corresponding debugger server. If there is a failure then return to the caller passing back the error status. Step 405: Send a debug it message to the debugger server that includes all of the arguments of the debugit routine such as internet address, login ID, password, address-space ID, thread ID, instruction address and the debugger server arguments. The message is sent to the debugger server by executing a call to the sendto socket library routine passing the socket returned by the BeginSearch routine and the debugger server socket address returned by the FindNext routine as arguments of the sendto call. NOTE: This is an optimization to avoid creating a new socket just to send the one debug it message. Step 406: Receive from the debugger server an acknowledgement message. If a negative acknowledgement is received or a timeout occurs then repeat the previous two steps until a status of no.sub.-- more is returned from the call to FindNext. Step 407: Execute a EndSearch to end the search session and close the socket. DebugMe Routine A call to the debugMe routine is made passing a search criteria which is used to locate a debugger server. In this case the debugee is the program that is currently running the debugMe routine. The debugMe routine calls the debugit routine passing the specified search criteria along with the current internet address, login ID, password, address-space ID, thread ID, and an instruction address which is the return address of the debugMe call. void debugMe(char *searchcriteria, char *dbgservargs, int *status); where:
__________________________________________________________________________
SEARCHCRITERIA A string that contains the search criteria
described above. If NULL is specified, then the
current value of the DEBUGSEARCHCRITERIA
environment variable will be used.
DBGSERVARGS is a string that can contain arguments for the
debugger (e.g. where to find source code).
STATUS is a pointer to an int where the status code is
returned. The values returned will be one of:
ERROR.sub.-- STATUS.sub.-- OK
normal completion
DBG.sub.-- NO.sub.-- DEBUGGER.sub.-- SERVER.sub.-- FOUND
No debugger server
found that matches
the specified search
criteria.
DBG.sub.-- TOOL.sub.-- LOCATOR.sub.-- FAILURE
A call to the tool
locator failed.
DBG.sub.-- NO.sub.-- TOOL.sub.-- LOCATOR.sub.-- FOUND
No tool locator found.
__________________________________________________________________________
For example: debugMe("hostname=davinci and userid=hpan and language=CPP", "-s /u/hpan/code", &status); will cause the debugit routine to be called passing the current internet address, login ID, password, address-space ID, thread ID, and the return address of the debugMe routine. The string "-s /u/hpan/code" will be used by the debugger server to locate the source code. Debugger Server Message Handler Routine This routine handles messages that are received from various debugger clients via a connectionless internet socket that is created by the RegisterTool routine. The recvfrom and sendto socket library routines are used to communicate with the debugger clients. The recvfrom will read both a message and the socket address of the debugger client that sent the message. This socket address is used to send the response back to the debugger client via the sendto routine. Debug it Message Handler Routine The debug it message contains the internet address, login ID, password, address-space ID, thread ID, instruction address of a debugee, and a debugger server argument string. The socket address of a debugger client is returned by the recvfrom socket library routine call. If this is the first debug it message for the debugee, then the debugger server will parse the debugger server arguments string to set various debugger options, such as where to locate the source code, and then "attach" a monitor/controller to the debugee. A breakpoint is set at the instruction address specified in the message and an acknowledgement message is sent back to the debugger client. Implementation of The Dynamic Connection Mechanism The following describes implementations of this dynamic connection invention to debug client/server application programs based on DB2.TM./6000 and CICS.TM./6000. In these two implementations, three ways are shown in which a debugee can be attached by a debugger server; 1) the debugee is started under the debugger server; 2) a third program referred to as a debugger client issues a "debugit" request specifying a debugee; 3) the debugee issues a "debugMe" request. In the third case, the debugee is also the debugger client. Debugging DB2.TM./6000 Client/Server Application FIG. 5 shows a parallel and distributed debugger 500, 501, 502, 503, monitoring and controlling a DB2.TM./6000 application program. A client program "myclient" 504 is running in a process on machine 1, 552. DB2.TM./6000 external programs (i.e., stored procedure 513 and user defined functions 511) are executed under the control of DB2.TM./6000 system on machine 3, 551. The DB2.TM./6000 system is a set of control processes, represented by the DBMS Control Unit box 553, created at database instance creation time. The control unit 553 listens for "connection" requests from clients 504. For each connection request, the control unit 553 spawns a new set of processes which is referred to as agent unit 505. The newly created agent unit is then connected to the corresponding client for receiving and serving the subsequent database requests. The agent unit consists of an agent process 509 and, optionally, a set of fenced UDF processes 511, and/or a set of stored procedure processes 513. The agent process 509 runs the major part of the database engine code and is, therefore, also referred to as the "database engine". The agent process 509 takes the request from the client and distributes the request to various service components of the database engine to accomplish the requested action. Besides the database engine code, the agent process also runs un-fenced UDF code. A fenced UDF process 511 runs the run-time code which communicates with the agent process, dynamically loads the UDF library, and runs fenced UDF code. The number of fenced UDF processes varies from one implementation to another. For example, there could be one fenced UDF process shared by all the fenced UDFs invoked in a current application or there could be more than one such processes, each serves a set of fenced UDFs that are run under the same user ID. In many aspects, a stored procedure process 513 has the same run-time characteristics as that of a fenced UDF process. Unlike fenced UDF process 511, a stored procedure process 513 runs the external program as if it were a stand alone application sitting on the server machine. In general, there could be more than one stored procedure process 513 associated with a client program. In this example, the client program "myclient" 504 executes a stored procedure named "mysp" 513. The store procedure then executes a SQL SELECT command that contains a call to a fenced UDF named "myudf" 511. The database server loads the stored procedure (mysp) 513 and the fenced UDF (myudf) 511 in their own separate process on the same machine that the DBMS is running (i.e., machine 3), 551. A separate monitor/controller (debugger back-end), 501, 502, 503 will be "attached" to each of the processes that are running the client program, stored procedure, and user defined function using the "dynamic connection" mechanism. Just before the external program is about to be executed in a stored procedure or fenced UDF process, a library routine is called to do the following two steps. First, the process checks to see if a monitor/controller is already attached to the current process. If not, the process will execute a debugMe library routine as illustrated in FIG. 2, to locate a debugger server and to obtain the socket address of the debugger server through the tool locator. The debugMe routine will then send a message to the debugger server to have it attach a monitor/controller to the current process (i.e., the debugee). Second, the process calls a particular library routine that executes a breakpoint which tells the debugger that an external program is about to be executed. The debugger will then run the current process to the first executable statement of the external program and execute a breakpoint. The application programmer is then able to debug the program by using the various debugger commands (e.g., line step, call step, display/modify variables, set breakpoints etc.) After the external program returns, the current process calls a particular library routine that executes a breakpoint to notify the debugger about the ending of the external program. If the stored procedure or fenced UDF process can be shared between users (i.e., DB2.TM. client/server connections), the debugger will detach the monitor/controller from the process that ran the external program. If it cannot be shared between users, the debugger can leave the monitor/controller attached for better efficiency. This is particularly useful for UDFs which will generally be called many times for each SQL SELECT statement. In the above example, the stored procedure process and fenced UDF process play the role of both debugger client and debugee. Debugging Distributed CICS.TM. Application FIG. 6 illustrates the environment of debugging a distributed CICS.TM./6000 sample application. Each CICS.TM./6000 region, 620, 630, consists of many UNIX.TM. processes. The CICS.TM./6000 implementation includes the following system processes. The "cics" process 640 is a CICS.TM./6000 root process that is created at initialization. This process starts (spawns) other processes including "cicsam" 641. The "cicsam" is a CICS.TM./6000 application monitor and is responsible for managing CICS.TM. application servers (i.e., "cicsas") 642. Each "cicsas" process 622 is a CICS.TM./6000 application server where the individual CICS.TM. transaction programs are run. This example of a distributed CICS.TM. application has a client program "epi2cics" 604, which is running on machine 1, 652, that uses the External Presentation Interface (EPI) to invoke the transaction "ept1," 622, in Region A, which is running on machine 2, 653. The "ept1" transaction program, in turn, uses the "EXEC CICS LINK" call to invoke a second transaction named "ept2," 632, in Region B, 630, which is running on machine 3, 651. After the client program "epi2cics" invokes the "ept1" transaction, the CICS.TM. application monitor (cicsam) 641 for Region A 620 allocates an available application server (cicsas). The "cicsas" then arranges to have the application server dynamically load the associate transaction program and calls the UNIX.TM. system "sleep" routine (with a very large time value) right before it is about to execute the transaction program. Next, the application server (cicsas) 622 will invoke the debugMe library routine to locate a debugger server 600 (which is running on machine 4) and to obtain its socket address using the tool locator 200, also running on different machine, machine 5. The debugMe routine uses the socket address to send a "debug me" message to the debugger server (i.e., the debugger front-end) requesting service. The debugger server, in turn, attaches a monitor/controller 602 to the CICS.TM. application server (cicsas) process 622 that will run the transaction program. Once the monitor/controller 602 is attached to the application server process 622, the debugger will send the application server process a UNIX.TM. signal to wake it out of its sleep. The debugger will then run the application server to the first executable statement of the transaction program and execute a breakpoint. The application programmer is then able to debug the program by using the various debugger commands (e.g., line step, call step, display/modify variables, set breakpoints etc.) The "ept1" transaction program 622 will eventually execute the "EXEC CICS LINK" command to invoke the "ept2" transaction 632 in Region B 630. The following steps will have the debugger server attach a monitor/controller to the application server process that runs the associated transaction program in Region B. The CICS.TM. application monitor (cicsam) 641 in Region B 630, will invoke the debugit library routine to locate a debugger server 600 (which is running on machine 4) and to obtain its socket address using the tool locator 200, also running on different machine, machine 5. The debugit routine uses the socket address to send a "debug it" message to the debugger server (i.e., the debugger front-end) requesting service. The debugger server, in turn, attaches a monitor/controller 603 to the CICS.TM. application server (cicsas) process 632 that will run the transaction program. Once the monitor/controller is attached to the application server process, the debugger will send the application server process a UNIX.TM. signal to wake it out of its sleep. The debugger will then run the application server to the first executable statement of the transaction program and execute a breakpoint. The application programmer is then able to debug the program by using the various debugger commands (e.g., line step, call step, display/modify variables, set breakpoints etc.) After the "ept2" transaction completes, the CICS.TM. application server calls a particular library routine that executes a breakpoint to signal the debugger about the completion of the transaction program. The debugger then detaches the monitor/controller from the application server process and allows it to continue its execution. Using the foregoing specification, the invention may be implemented using standard programming and/or engineering techniques using computer programming software, firmware, hardware or any combination or subcombination thereof. Any such resulting program(s), having computer readable program code means, may be embodied within one or more computer usable media such as fixed (hard) drives, disk, diskettes, optical disks, magnetic tape, semiconductor memories such as ROM, Proms, etc., or any memory, transmitting, or other device, thereby making a computer program product, i.e., an article of manufacture, according to the invention. The article of manufacture containing the computer programming code may be made and/or used by executing the code directly from one or more media, by copying the code from one medium to another medium, or by transmitting the code over a network. An apparatus for making, using, or selling the invention may be one or more processing systems including, but not limited to, cpu, memory, storage devices, communication links, communication devices, servers, I/O devices, or any subcomponents or individual parts of one or more processing systems, including software, firmware, hardware or any combination or subcombination thereof, which embody the invention as set forth in the claims. User input may be received from the keyboard, mouse, pen, voice, touch screen, or any other means by which a human can input data to a computer, including through other programs such as application programs. One skilled in the art of computer science will easily be able to combine the software created as described with appropriate general purpose or special purpose computer hardware to create a computer system and/or computer subcomponents embodying the invention and to create a computer system and/or computer subcomponents for carrying out the method of the invention. While the preferred embodiment of the present invention has been illustrated in detail, it should be apparent that modifications and adaptations to that embodiment may occur to one skilled in the art without departing from the spirit or scope of the present invention as set forth in the following claims. For example, although the foregoing specification described the dynamic connection invention based on a socket mechanism that is supported across many operating systems (e.g., AIX.TM., OS/2.TM., and MVS.TM.), the invention could be implemented using other address locating mechanisms supported by other operating systems. In addition, although the invention has been described with reference to a CICS.TM./6000 implementation, the invention is applicable to other transaction monitoring systems, database management systems, message queuing systems, and other software systems. In addition, although the invention has been described with reference to distributed applications running in a distributed environment, the invention is applicable to application programs running on a single machine. Description of a Method and System for Debugging Parallel and Distributed Applications Background The prior art for parallel and distributed debuggers is illustrated by serial debuggers and parallel and distributed debuggers. Serial debuggers are incapable of effectively debugging parallel and distributed applications (e.g., client/server, peer-to-peer, etc.). Parallel and distributed debuggers generally have required a complete instantiation of the debugger for every program that makes up the distributed application on each machine where the distributed application is running, thus yielding multiple debuggers and multiple user interfaces. In view of the above, there is a need for a method of, and system for, debugging parallel and distributed applications having multiple programs with many threads of execution running on various machines on a variety of operating systems, from a single user interface. Summary One of the major inhibitors to developing parallel and distributed applications (e.g. client/server, peer-to-peer) is the lack of good debugging tools. To debug a parallel and distributed application the tool should provide dbx-like functions that will allow the user to monitor and control the execution of multiple programs with many threads of execution running on various machines. It must also allow the user to display and modify the run-time state of all of those programs in a coherent fashion from a single user interface. The present invention provides such a method for debugging parallel and distributed applications. This invention can be applied to debugging applications running on variety of operating systems including UNIX.TM., OS/2.TM., WINDOWS.TM., and MVS.TM.. Description With reference now to the figures and in particular with reference to FIG. 7, there is depicted a pictorial representation of a data processing system 8 which may be utilized to implement the method of the present invention. As may be seen, data processing system 8 may include a plurality of networks, such as Local Area Networks (LAN) 10 and 32, each of which preferably includes a plurality of individual computers 12 and 30, respectively. Of course, those skilled in the art will appreciate that a plurality of Intelligent Work Stations (IWS) coupled to a host processor may be utilized for each such network. As is common in such data processing systems, each individual computer may be coupled to a storage device 14 and/or a printer/output device 16. One or more such storage devices 14 may be utilized, in accordance with the method of the present invention, to store the various computer programs which may be accessed, executed, and debugged by a user within data processing system 8, in accordance with the method of the present invention. In a manner well known in the prior art, each such computer program may be stored within a storage device 14. Still referring to FIG. 7, it may be seen that data processing system 8 may also include multiple mainframe computers, such as mainframe computer 18, which may be preferably coupled to Local Area Network 10 by means of communication link 22. Mainframe computer 18 may also be coupled to a storage device 20 which may serve as remote storage for Local Area Network 10 which may be coupled via communications controller 26 and communications link 34 to a gateway server 28. Gateway server 28 is preferably an individual computer or Intelligent Work Station which serves to link Local Area Network 32 to Local Area Network 10. As discussed above with respect to Local Area Network 32 and Local Area Network 10, a plurality of server computer programs may be stored within storage device 20 and executed by mainframe computer 18. Similarly, a plurality of client computer programs may be stored within storage devices 14 and executed by individual computers 12 such that distributed client/server computer programs are provided. Of course, those skilled in the art will appreciate that the mainframe computer 18 may be located a great geographical distance from Local Area Network 10, and similarly, Local Area Network 10 may be located a substantial distance from Local Area Network 32. That is, Local Area Network 32 may be located in California while Local Area Network 10 may be located within Texas and mainframe computer 18 may be located in New York. As will be appreciated upon reference to the foregoing, it is often desirable for a user within one portion of distributed data processing system 8 to execute computer programs on one or more portions of data processing system 8. For example, the user may execute an client computer program on computer 12 which requests services from a server program executing on mainframe 18 which further requests services from service routines executing on computer 30. To verify the proper operation of such a distributed set of client/server programs, the user may wish to debug the distributed set of client/server programs as if they were one single program. Therefore, it should be obvious that a need exists for a method whereby the user may debug the distributed set of client/server programs as if they were one single program. Referring now to FIG. 8, the preferred embodiment of the present invention is a debugger 800 which is itself a client/server application. It consists of a front-end 100 and one or more back-ends 101 as illustrated in FIG. 8 and FIG. 1. This invention creates a Director 815 component which handles most of the initialization and parallel execution control issues and a rp.sub.-- client 820 and rp.sub.-- server 825 component which handles most of the distributed execution issues. The Director 815 allows the Debug Engine 830 to be unaware of most of the parallel and distributed aspects of the application. Thus, the Debug Engine can be created by re-using a serial debugger for presenting the state information about the various programs that make up the application. Back-End Referring now to FIG. 1, a back-end (101, 102, and 103) is allocated for each program (111, 112, and 113) (i.e. client or server program) involved in the application. The creation of back-ends (101, 102, and 103) is done by the front-end Director component 815 when the debugger 800 is invoked. Each application program (111, 112, and 113) is monitored by its corresponding back-end (101, 102, and 103) during the debugging process. The back-end (101, 102, and 103) will execute requests from the front-end 100 to control the execution of the application program (111, 112, and 113) and read/write state information. For the single client/server paradigm, which is a very common case, if the client or server program is on the same machine as the debugger front-end, then the program is directly monitored by the front-end (rp.sub.-- client component) to avoid the overhead of allocating a back-end. This optimization is especially effective for debugging a non-distributed program that will eliminate the need to allocate a back-end. In some operating systems, an address-space can create additional address-spaces. For example, a program running in a UNIX.TM. process (i.e. address-space) such as P2 112 can create additional processes (such as P21 135, P22 140, and P23 145) during execution by executing fork system call, and then load a new program into that process using the exec system call. The process for the application program 112 and all processes that it has created (135, 140, and 145) can be monitored by a single back-end 102. In addition, the back-end handles interrupt signals from those processes and passes information to the front-end as needed. The rp.sub.-- server component (150, 155, and 160) in the back-end (101, 102, and 103 respectively) is responsible for the communication with the rp.sub.-- client component 820 in the front-end. The message requests that flow from the front-end to the back-end are: Establish Connection Establishes the connection between the front-end and the back-end. Load A Program Load a program and begin monitoring it. Get Loader Information Read information about a program that is currently loaded and being monitored by the back-end. Read Program State A request to read the value from a register or location in memory of a program being monitored by the back-end. Write Program State A request to write a value to a register or location in memory of a program being monitored by the back-end. Start Execution Start the execution of all the programs that are monitored by the back-end. Wait For Interrupt Determine if a interrupt (e.g. breakpoint) has occurred in any thread. Stop Execution Stop the execution of the programs that are monitored by the back-end. Read Thread Information Read information about a particular thread. The information sent back to the front-end includes the thread state (e.g. running, ready, waiting) and status (e.g. breakpoint, interrupted, floating point exception), current instruction pointer, and current frame pointer. This routine can be called iteratively to obtain information about all of the threads running in an address-space. Unload A Program Unload a program and stop monitoring it. Quit Terminate the back-end and disconnects it from the front-end. The communication between the front-end and the back-end (835, 165, 170, and 175) can be implemented using any of a variety of standard protocols including TCP/IP, SNA, NETBIOS. The general model of the communication is Remote Procedure Call (RPC). FIG. 1 illustrates an example of a multiple client/server UNIX.TM. application. Programs P1 111 and P3 113 each have one process only, but P2 112 spawns three processes (P21 135, P22 140, and P23 145) during execution. The communication functions of every back-end talks to the same component of the front-end, rp.sub.-- client using SUN.TM. RPC running on a TCP/IP communications protocol. Front-End Referring back to FIG. 8, the debugger front-end 100 is composed of the Director 815, Debug Engine 830, Interface 840, and rp.sub.-- client 820 components. The shadow area in FIG. 8 (i.e., Interface 840 and Debug Engine 830) are both re-used from a serial debugger with some modifications. Note that it is very common for a serial debugger to be divided into an Interface component and a Debug Engine component. For example, dbx for AIX.TM./6000 supplies a programming interface between its command line processor and debug engine. This allows other debugger front-ends (e.g. xde or the workbench debugger) to re-use the dbx Debug Engine. Director The Director 815 allows the Debug Engine 830 and Interface 840 components to be unaware of most of the parallel and distributed aspects. A serial debugger will generally have a set of global variables that are used to record the state of the debugging session. For example, which breakpoints or watchpoints have been set, the location of the symbol table information, the name of the program that is currently loaded etc. In the present invention, the serial debugger's global variables will become fields of new data structures that are allocated by the Director component. Referring now to FIG. 9 for each back-end (101, 102, and 103) created during initialization, the Director 815 allocates a data structure called a controller (905, 910, and 915 respectively). The controller is used to record information such as the absolute path where the source code can be found, the hostname of the machine where the application program is executing, the name of the original program that was loaded etc. The controller also points to a set of address-space data structures (925, 930, 935, 940, 945, and 950) that keep track of the current execution state for each program (e.g. UNIX.TM. process) that is being monitored by the back-end. The execution state includes the name of the program that is currently being executed, the ID of the current thread, the current program counter, a pointer to the current stack frame, and information about the most recent program interrupt. The address-space data structure also contains information such as: the setting of breakpoints and watchpoints, the location of the symbol table information, and the format of variables when they are displayed to the interface. As an example, when the user requests the Interface component 840 to display a particular thread of an application 111, the Director 815 instructs the rp.sub.-- client component 820 to send all future communications to the back-end 101 that is monitoring the selected thread 111. The Director 815 then makes assignments to a set of variables that point to the controller 905 and address-space data structures 925 which correspond to the specific machine, address-space, and thread that was selected. A set of macros are defined to allow the routines in the Debug Engine 830 and Interface 840 components to access and update the serial debugger's global variables by de-referencing the fields in the selected controller and address-space data structures. Also, additional macros are written so that calls to read and write the program state will be handled by routines in the rp.sub.-- client 820 and rp.sub.-- server 825 components. Therefore, the Debug Engine 830 and Interface 840 components can be coded as if they are debugging a single program. This technique minimizes the changes to the original source code from the serial debugger. In response to a start execution command from the user, the Director 815 will supervise the execution of the parallel and distributed application. It starts the application by sending commands to each back-end (101, 102, and 103) to start or continue executing the programs (111, 112, and 113 respectively) they are monitoring. The Director 815 will then poll the back-ends (101, 102, and 103) for current status until one of the back-ends reports that a program it is monitoring has encountered a breakpoint, watchpoint, program interrupt, or termination. At that moment, the Director 815 will send a stop command to all other back-ends which in turn send an interrupt program execution signal (e.g., SIGINIT in UNIX.TM.) to each of the programs they are monitoring. Meanwhile, the Director 815 tells the Interface 840 and Debug Engine 830 components which thread caused the application to stop. The Interface 840 is then called to allow the user to display and modify the frozen state of that thread. As a result, the Interface 840 will call the Debug Engine 830 to read and write the thread state. Debug Engine The Debug Engine component 830 is derived from an existing serial debugger which supports conventional serial debugging commands (e.g., symbol table resolution, setting breakpoints, step execution, etc.). It uses the set of macros mentioned above to allow the routines in the Debug Engine 830 to access and update the controller (905, 910, and 915) and address-space data structures (925, 930, and 935 respectively) that record the state of the debugging session and to read and write the program state. This component can be coded as if it is debugging a non-distributed serial program. Interface The Interface component 840 is also derived from the serial debugger. It uses the same set of macros defined above to access and update the controller (905, 910, and 915) and address-space data structures (925, 930, and 935 respectively) and to read and write the program state. This again minimizes changes to the original source code from the serial debugger. This component needs to be modified so that it commands to start and stop the execution of the parallel and distributed application are sent to the Director component 815 rather than directly to the Debug Engine 830. In addition, modifications are needed to list and select the various machines, address-spaces, and threads of the parallel and distributed application. For example, if the debugger 800 has a window based interface 840 a new window could be added to list all of the machines, address-spaces, and threads involved in the application in an indented list: machine1 address-space1 thread1 thread2 thread3 address-space2 thread1 thread2 machine2 address-space1 thread1 thread2 thread3 address-space2 thread1 thread2 thread3 When the application is stopped the user can select any of the threads in that window by clicking on it. A call is made to a routine in the Director component 815 to set the current machine, address-space, and thread. Routines in the Interface component 840 are then called to re-draw the state of the selected machine, address-space, and thread. In the case of a command driven non-window interface, two new commands need to be added: one to list the various machines, address-spaces, and threads; and a second one to set the current machine, address-space, and thread. rp.sub.-- client The rp.sub.-- client component 820 contains an Application Programming Interface (API) for a set of routines that are used to communicate with the various back-ends (101, 102, and 103). There is one routine for every type of message request that flows between the front-end 205 and back-end (101, 102, and 103). Also, there is a routine which is called by the Director 815 to specify which back-end to communicate with. The rp.sub.-- client 820 marshalls the argument passed by the API call into a message and sends it to the back-end (101, 102, and 103) using a synchronous protocol (e.g. RPC) (835, 165, 170, and 175). Eventually, the rp.sub.-- client 820 component will receive a response message from the back-end (101, 102, and 103) which contains return arguments. These arguments are unmarshalled from the message and passed back to the caller of the API routine. The rp.sub.-- client component 820 communicates with only one back-end at a time that is specified by the Director 815. Control Flows of Director Initialization The Director component 815 is invoked during the initialization of the debugger 800 to start the application running under the debugger 800. The application may be made up of multiple programs with many threads of execution running on various machines. The user needs to specify the various programs that make up the application. For each program the user needs to specify the program arguments, the host machine the program should run on, and the user ID the program should run under. In addition, the role the program plays with respect to client/server and peer-to-peer communication may be specified. The valid roles are client, server, both, peer-to-peer, or none. The Director component 815, for example, may use the role information to determine the order in which the programs need to be started (e.g., servers must start before clients). Optionally, additional information may be specified for passwords, debugging options, etc. For example, the debugger 800 may allow the user to specify this information in a file such as in the following example: -H davinci -U hpan -P secrets -R client calc.sub.-- client 264167 -H davinci -U hpan -P secrets -R client calc.sub.-- client 545555 -H atlantic -U meier -P dontlook -R server calc.sub.-- servera -H thistle -U hpan -P hideit -R both calc.sub.-- serverb This example file shows a distributed application made up of four programs running on three different machines under three different user ID's. The first line specifies a program named calc.sub.-- client should be started on a machine named davinci under the user ID of hpan with password secrets. The program will play the role of a client and is passed one argument which is 264167. The second line starts a second instance of the client program calc.sub.-- client on the same machine and user ID. In this case, the program argument is 545555. The third line specifies that a program named calc.sub.-- servera should be started on a machine named atlantic under the user ID of meier with password dontlook. This program will play the role of a server. And finally, the fourth line specifies that a program named calc.sub.-- serverb should be started on a machine named thistle under the user ID of hpan with password hideit. This program is both a client program and a server program. The following procedure is executed once for each of the programs that make up the application. During initialization, the debugger 800 will call the Director component 815 passing the name of the file that specifies the various programs for the application. The director component 815 will open the above file and for each program specified will do the following: 1. Read in the name of the program, arguments, host machine etc. 2. Allocate and initialize a controller data structure. 3. Start a debugger back-end on the host machine that the program should run on using the remote execution command (rexec). 4. Allocate and initialize an address-space data structure. 5. Send a Establish Connection message request to the debugger back-end. 6. Send a Load A Program message request to the back-end to load the application program. 7. Send a Get Loader Information message request to the back-end to update the address-space data structure with information about what programs and library routines were loaded as a result of the Load A Program message request. 8. Send a Get Symbol Table message request to the back-end to update the address-space data structure with the symbol tables for the programs and library routines. 9. Call the Debug Engine to perform standard initialization routines (e.g., run the program to the first executable source line). Running the Application Program In response to one of the start execution commands from the user, the Interface component 840 will call the Director component 815 to supervise the execution of the parallel and distributed application. The Director component 815 starts the application by sending commands to each back-end (101, 102, and 103) to start or continue executing the programs they are monitoring. In many client/server applications, it is necessary for the server programs to be running before the clients can be started. By specifying the roles of client, server, or both for the programs, the Director 815 may ensure that the client programs are not started until all of the programs that are servers or both are ready to receive client requests. In the general case, the user can add a call to a library routine named dbgServerReady at the point in the server program where it is ready to receive client messages. The C language syntax for this library routine is: dbgServerReady();. This dbgServerReady routine notifies the Director component 815 of the debugger 800 that the server is ready to receive client requests by, for example, sending a signal or executing a breakpoint. If the server is not running under the debugger 800, dbgServerReady will simply return. To improve ease of use, the communication middle-ware may automatically execute the call to dbgServerReady. For example, for RPC it may be executed at the beginning of the RPC "server listen" routine. After the application is started, the Director 815 will poll the back-ends (101, 102, and 103) for current status until one of the back-ends reports that a program it is monitoring has encountered a breakpoint, watchpoint, program interrupt, or termination. The Director 815 will then send a Stop Execution message request to all other back-ends, which in turn will send an "interrupt program execution" signal (e.g., SIGINIT in UNIX.TM.) to each of the programs they are monitoring. The following are the steps preferred in carrying out the method of, and system for, the Director 815 when it is called by the Interface component 840 in response to a command from the user to start or continue the execution of a distributed application. These steps are sufficient to enable one of ordinary skill to write code in any suitable computer programming language. 1. Start or continue the execution of the application by looping thru all of the controllers and, for each one, doing the following: a. If the role of the program associated with the controller is client, check to see that all of the programs that have a role of server or both have executed the dbgServerReady library routine and are therefore ready to receive client requests. If not skip to the next controller. b. For all address-space structures pointed to by this controller execute the conventional debugger routine that will start the program executing. 2. Execute polling loop. a. Get the first controller from the list of controllers created at debugger initialization. b. Send a Check For Interrupt message request to the back-end. If an interrupt has occurred, exit the polling loop by going to step 3. c. If not at the end of the list of controllers, get the next controller and go to step 2.b. d. Call a user interface routine to determine if the user has executed a Stop command. If yes, exit the polling loop by going to step 3. e. Wait for one second to limit the contention of network resources (e.g. execute a sleep(1) UNIX.TM. system call). f. Go back to the beginning of the polling loop at step 2.a. 3. Stop the execution of the application by looping thru all of the controllers and sending a Stop Execution message request to any controller that has at least one thread still running. 4. Update the controller and address-space data structures by looping thru all of the controllers again and, for each one, doing the following: a. Get the first address-space ID running under the back-end by sending a Get Next Address Space ID message request with a address-space ID of 0. b. If no more address-space IDs are found, continue to next controller. c. Search the list of address-space data structures pointed to by the controller data structure to determine if this is a new address space (e.g., created by fork system call on UNIX.TM.). If this is a new address-space: Allocate and initialize an address-space data structure. Send a Get Loader Information message request to the back-end to update the address-space data structure with information about what programs and library routines were loaded. Send a Get Symbol Table message request to the back-end to update the new address-space data structure with the symbol tables for the programs and library routines. d. Send a Get Address Space Information message request to the back-end and update the address-space data structure. e. Send a Get Thread Information message request to the back-end for the current thread ID and update the address-space data structure. f. If the information about that last program interrupt in the address-space indicates that a dynamic load has occurred do the following: Send a Get Loader Information message request to the back-end to update the address-space data structure with information about what programs and library routines were loaded. Send a Get Symbol Table message request to the back-end to update the new address-space data structure with the symbol tables for the programs and library routines. g. If the information about that last program interrupt in the address-space indicates the program has executed a call to the dbgServerReady library routine, set a flag in the address-space data structure to indicate that this server is ready to receive client requests. h. Check to see if there are any more address-spaces running under the back-end by sending a Get Next Address Space ID message request and go to step 4.b. 5. After all the controller and address-space data structures have been updated, return to the User Interface component which will display the current state of the application to the user and process commands. The above describes a debugger client/server application comprising a front-end and one or more back-ends, including a Director component which handles most of the initialization and parallel execution control issues and a rp.sub.-- client component and rp.sub.-- server component which handles most of the distributed execution issues. The Director allows a Debug Engine to be unaware of most of the parallel and distributed aspects of the application. Thus, the Debug Engine can be created by re-using a serial debugger for presenting the state information about the various programs that make up the application. More specifically, the above describes a system for debugging a distributed computer program comprising: a Front End means comprising: a Director means for allocating a controller data structure for storing an execution state of the distributed computer program; a Debug Engine means derived from a serial debugger supporting conventional serial debugging commands and having global variables for storing a state of a debug session; and means for accessing the controller data structure to update the global variables; and a Back End means for executing requests from the Front End means to control execution of the distributed computer program. Also, the above describes a method of debugging a distributed computer program, comprising the steps of: allocating a controller data structure by a Front End for storing an execution state of the distributed computer program; storing a state of a debug session in global variables of a Debug Engine derived from a serial debugger supporting conventional serial debugging commands; accessing the controller data structure to update the global variables; and executing requests by a Back End from the Front End to control execution of the distributed computer program. In addition, the above describes a computer program for debugging a distributed computer program, comprising: a Front End program means comprising: a Director program means for allocating a controller data structure for storing an execution state of the distributed computer program; a Debug Engine program means derived from a serial debugger supporting conventional serial debugging commands and having global variables for storing a state of a debug session; and program means for accessing the controller data structure to update the global variables; and a Back End program means for executing requests from the Front End program means to control execution of the distributed computer program. All of the above described data structures, definitions, routines, and interfaces bear the following copyright notice: Copyright IBM Corporation 1995 Using the foregoing specifications, the invention may be implemented using standard programming techniques. The resulting programs may be stored on disk, diskettes, memory cards, ROM or any other memory device for use in a computer. For execution, the program may be copied into the RAM of the computer. One skilled in the art of computer science will easily be able to combine the software created as described with appropriate general purpose or special purpose computer hardware to create a system for executing the programs. While the preferred embodiment of the present invention has been illustrated in detail, it should be apparent that modifications and adaptations to that embodiment may occur to one skilled in the art without departing from the scope of the present invention as set forth in the following claims.
|
Same subclass | ||||||||||
