|
Digital DCE for OpenVMS VAX and OpenVMS
Alpha Product Guide
16.8.1 The idl_cs_convert_t Type
An enumeration type is defined to enable a user routine to indicate
whether I-char data needs conversion from on-the-wire form to local
form, and if so, whether this conversion can be done in place.
typedef enum {
idl_cs_no_convert, /* No codeset conversion required */
idl_cs_in_place_convert, /* Codeset conversion can be done in a single
storage area */
idl_cs_new_buffer_convert /* The converted data must be written to a
new storage area */
} idl_cs_convert_t;
|
16.8.2 Routine Usage
If a cs_tag_rtn attribute is specified on the client side, it
is called on entry to the client stub. If a cs_tag_rtn
attribute is specified on the server side, it is called after all
in parameters have been unmarshalled, and before the manager
application code is invoked. Note that if this routine reports an error
status the manager application code is not executed.
For each piece of I-char data being marshalled, the _net_size
and _to_netcs routines are called once each.
For each piece of I-char data being unmarshalled the
_local_size and _from_netcs routines are called once
each.
16.8.3 Marshalling
The following routine is called before the marshalling of each piece of
I-char data to enable the stub to set up the necessary buffers.
void ltype_net_size(
/* [in] */ rpc_binding_handle_t h,
/* [in] */ idl_ulong_int tag,
/* [in] */ idl_ulong_int l_storage_len,
/* [out] */ idl_cs_convert_t *p_convert_type,
/* [out] */ idl_ulong_int *p_w_storage_len,
/* [out] */ error_status_t *p_st
)
|
Where:
|
h
|
Is the binding handle for the call, unless the routine is being called
from an IDL encoding services stub, in which case it is NULL.
|
|
tag
|
Identifies the codeset to be used on the wire. When the routine is
called from a client stub, this is the
cs_stag value. When the routine is called from a server stub,
it is the
cs_rtag value.
|
|
l_storage_len
|
Is the size, in units of
ltype, of the local storage allocated for the I-char data.
This is the local value of the
size_is variable for the array.
|
|
p_convert_type
|
Is the address to which the routine must write an indication of whether
data conversion is necessary. During marshalling, an intermediate
buffer is always used for a conversion. However, if the value given
here is
idl_cs_in_place_convert, assume that
l_storage_len can be used for the buffer size.
If
p_w_storage_len is not NULL when the routine is called, a
conformant or conformant varying array is being marshalled. In this
case, if the value written to
p_convert_type is
idl_cs_new_buffer_convert, the routine must write the storage
size, in units of the on-the-wire type, for the data being put on the
wire, to the address specified by
p_w_storage_len. This is used as the on-the-wire value of the
size_is variable for the array. If the
p_convert_type value is not
idl_cs_new_buffer_convert, the local and on-the-wire values of
the
size_is variable are assumed to be the same.
|
|
p_st
|
Is the address to which the routine must write a completion status. If
the routine cannot handle the codeset indicated by
tag, it should return
rpc_s_ss_incompatible_codesets. Otherwise, it usually returns
error_status_ok.
|
The following routine converts data from local format to the
on-the-wire format. If a varying or conformant varying array is being
marshalled, it must also convert the local data length to an
on-the-wire data length.
void ltype_to_netcs(
/* [in] */ rpc_binding_handle_t h,
/* [in] */ idl_ulong_int tag,
/* [in] */ ltype *ldata,
/* [in] */ idl_ulong_int l_data_len,
/* [out] */ my_byte *wdata,
/* [out] */ idl_ulong_int *p_w_data_len,
/* [out] */ error_status_t *p_st
)
|
Where:
|
h
|
Is the binding handle for the call, unless the routine is being called
from an IDL Encoding Services stub, in which case it is NULL.
|
|
tag
|
Identifies the codeset that will be used on the wire. When the routine
is called from a client stub, this is the
cs_stag value. When the routine is called from a server stub,
it is the
cs_rtag value.
|
|
ldata
|
Is the address of the local data.
|
|
l_data_len
|
Is the number of
ltype data elements to be processed. For a varying or
conformant varying array, this is the local value of the
length_is variable. For a conformant array, it is the local
value of the
size_is variable. For a fixed array, it is the array size
specified in the IDL.
|
|
wdata
|
Is the address to which the converted data is to be written.
|
|
p_w_data_len
|
Is NULL if the array is not varying or conformant varying. Otherwise,
it is the address to which the routine must write the on-the-wire data
length.
|
|
p_st
|
Is the address to which the routine must write a completion status. If
the routine cannot handle the codeset indicated by
tag, it should return
rpc_s_ss_incompatible_codesets. Otherwise, it usually returns
error_status_ok.
|
16.8.4 Unmarshalling
The following routine is called before the unmarshalling of each piece
of I-char data, to enable the stub to set up the necessary buffers.
void ltype_local_size(
/* [in] */ rpc_binding_handle_t h,
/* [in] */ idl_ulong_int tag,
/* [in] */ idl_ulong_int w_storage_len,
/* [out] */ idl_cs_convert_t *p_convert_type,
/* [out] */ idl_ulong_int *p_l_storage_len,
/* [out] */ error_status_t *p_st
)
|
where:
|
h
|
Is the binding handle for the call, unless the routine is being called
from an IDL Encoding Services stub, in which case it is NULL.
|
|
tag
|
Identifies the codeset used on the wire for the data being received.
When the routine is called from a server stub, this is the
cs_stag value. When the routine is called from a client stub,
it is the
cs_rtag value.
|
|
w_storage_len
|
Is the storage size of the on-the-wire data.
|
|
p_convert_type
|
Is the address to which the routine must write an indication of whether
data conversion is necessary, and if so, whether an intermediate buffer
is required for the conversion.
If
p_l_storage_len is not NULL when the routine is called, a
conformant or conformant varying array is being unmarshalled. In this
case, if the value written to
p_convert_type is
idl_cs_new_buffer_convert, the routine must write the size, in
units of
ltype, of the local storage to be used for the data, to the
address specified by
p_l_storage_len. This is used as the local value of the
size_is variable for the array. If the
p_convert_type value is not
idl_cs_new_buffer_convert, the on-the-wire and local values of
the
size_is variable are assumed to be the same.
|
|
p_st
|
Is the address to which the routine must write a completion status. If
the routine cannot handle the codeset indicated by
tag, it should return
rpc_s_ss_incompatible_codesets. Otherwise, it usually returns
error_status_ok.
|
The following routine is called to convert data from on-the-wire format
to local format if the p_convert_type value in the preceding
call to a _local_size routine was not
idl_cs_no_convert. If a varying or conformant varying array is
being unmarshalled, it must also convert the on-the-wire data length to
a local data length.
void ltype_from_netcs(
/* [in] */ rpc_binding_handle_t h,
/* [in] */ idl_ulong_int tag,
/* [in] */ my_byte *wdata,
/* [in] */ idl_ulong_int w_data_len,
/* [in] */ idl_ulong_int l_storage_len,
/* [out] */ ltype *ldata,
/* [out] */ idl_ulong_int *p_l_data_len,
/* [out] */ error_status_t *p_st
)
|
Where:
|
h
|
Is the binding handle for the call, unless the routine is being called
from an IDL Encoding Services stub, in which case it is NULL.
|
|
tag
|
Identifies the codeset used on the wire for the data being received.
When the routine is called from a server stub, this is the
cs_stag value. When the routine is called from a client stub,
it is the
cs_rtag value.
|
|
wdata
|
Is the address of the received data in on-the-wire format.
|
|
w_data_len
|
Is the length in units of the on-the-wire data type of the data to be
processed. For a varying or conformant varying array, this is usually
the on-the-wire value of the
length_is variable. On the client side, if the
length_is variable is
in only, it is the on-the-wire value for this variable that
was calculated when it was marshalled. For a conformant array, it is
usually the on-the-wire value of the
size_is variable. On the client side, if the
size_is variable is
in only, it will be the on-the-wire value for this variable
that was calculated when it was marshalled. For a fixed array, it is
the array size specified in the IDL.
|
|
l_storage_len
|
Is the size, in units of
ltype, of the storage available at
ldata. It is supplied to this routine so that, for
unmarshalling on the client side, the user can detect an error if the
sender has sent data that cannot be unmarshalled into the space
available.
|
|
ldata
|
Is the address to which the converted data is to be written.
|
|
p_l_data_len
|
Is NULL if the array is not varying or conformant varying. Otherwise,
it is the address to which the routine must write the local data length
in units of
ltype.
|
|
p_st
|
Is the address to which the routine must write a completion status. If
the routine cannot handle the codeset indicated by
tag, it should return
rpc_s_ss_incompatible_codesets. Otherwise, it usually returns
error_status_ok.
|
16.9 Interaction with IDL Encoding Services
The interaction with IDL Encoding Services is that the cs_stag
and cs_rtag attributes are applied to the same in,
out parameter.
If the cs_stag attribute is applied to an in
parameter of an operation that has only the encode attribute
applied to it, the cs_rtag attribute must be applied to the
corresponding parameter in the matching operation that has the
decode attribute applied to it.
The cs_drtag attribute has no effect when IDL Encoding
Services are in use. Therefore, this attribute would not normally be
applied to a parameter of an operation that has the encode or
decode attribute applied to it.
Chapter 17 Application Debugging with the RPC Event Logger
The Remote Procedure Call (RPC) Interface Definition Language (IDL)
compiler in Digital DCE for OpenVMS VAX and OpenVMS Alpha includes
enhanced application debugging support beyond the support provided with
OSF DCE. The OpenVMS IDL compiler includes the RPC Event Logger, a
software utility that records information about operations relating to
the execution of an application. Operational information about the
program state at a specific point during processing, called an event,
is recorded in a file, called an event log. You have the option of
directing event logging information to the terminal screen, rather than
to a file. In this chapter, the terms event log and log are used
interchangeably to refer to the stream of logging output captured in
the event log file or displayed on the screen.
Event logging provides a detailed, low-level view of the execution of
your RPC application. If development of your RPC application is
proceeding well, this level of detail may not be necessary. However,
when you are in the debugging phase of application development, the
continuous execution information provided by the Event Logger and the
ability to change the type and timing of logging can be valuable.
17.1 Introduction to the RPC Event Logging Facility
When event logging is enabled, the Event Logger creates one log for
each client and server process. To enable the RPC Event Logger you
specify an IDL compiler option that traces events (described in
Section 17.2.1).
Enabling event logging when compiling allows you the option of
generating logs at runtime without rebuilding the application. Once
logging is enabled, you can use OpenVMS symbols and the RPC Log Manager
(rpclm) to control logging operations. The Log Manager
provides a command interface for changing logging operations during
application execution.
The RPC Event Logger records events about application calls, context
handles, errors, miscellaneous events, and logging operations. These
are called event types. Typical RPC events include the following:
- call_start --- A client application made a call to a
server.
- call_failure --- A client stub terminated abnormally
either through an exception or failing status.
- exception --- An exception was detected in the server
stub, and the exception caused the call to terminate.
- context_rundown --- A context handle on a server was freed
by the context rundown procedure.
For application calls, the Event Logger generates events that signal
call activation, the call start and end, attempts to rebind to a
server, and termination of a server thread.
For context handles, the Event Logger generates events that signal
context handle creation and deletion by the client and server, and
context handle modification, removal, and rundown.
For errors, the Event Logger generates events that signal call and
receive failure from the client, exceptions, server failure, and call
transmission failure from the server.
The miscellaneous events provide information about the application
manager routine, and input and output argument processing events.
The logging operation itself generates events that display the logging
output device, and that signal modification of logging parameters, and
event log start and stop.
As a result of using the -trace option in the IDL compile
command, idl, RPC events are generated by code in the client
and server stub modules created by the compiler. Note that some events
are generated at selected points in the RPC runtime library. For this
reason, certain events, such as those relating to the logging
operation, are always generated into the application code in addition
to the event types you specify.
The events generated in each of these areas are shown in detail in
Section 17.6.
In the event log, each event is described on a single line divided into
five fields. The five fields are defined in Table 17-1.
Table 17-1 Event Log Fields
| Field |
Field Description |
|
Event Time
|
The system clock at the time of the event. Events are listed
chronologically in the log.
|
|
Thread Identity
|
The hostname, process ID, and thread ID.
|
|
Operation Name
|
The interface and operation name (if available).
|
|
Event Name
|
Name of the event.
|
|
Event Data
|
Data related to the event. This field contains either specific
information about logging operations or a string binding that uniquely
identifies the client process, server process, or Log Manager process.
|
The following is an example of an event log generated for an RPC
client. The log contains five columns. To improve readability, columns
four and five are shown below the first three columns. In addition, the
field names have been added to identify the events; the names do not
appear in an actual event log. (In subsequent event log examples, the
field names are occasionally used instead of actual data to improve
readability where necessary.)
EVENT TIME THREAD IDENTITY OPERATION NAME
1993-02-07:11:48:18.31.160-5:00I0.121 ifdef:8710/1 binopwk.binopwk_add
1993-02-07:11:48:18.32.170-5:00I0.121 ifdef:8710/1 binopwk.binopwk_add
1993-02-07:11:48:18.65.180-5:00I0.121 ifdef:8710/1 binopwk.binopwk_add
|
EVENT NAME EVENT DATA
log_start all
call_start ncacn_ip_tcp:16.31.48.109[1821]
call_end
|
This small event log indicates that the following events occurred:
- The log_start event indicates that logging started on
February 7, 1993, at 11:48 a.m. on the host named ifdef, in
process number 8710, and in thread number 1. Event logging was enabled
when the binopwk interface was compiled with the IDL
-trace option. The RPC call to the binopwk_add
operation in the binopwk interface caused logging to begin and
is the first event logged. The Event Data field indicates that all
events are being logged.
- The call_start event indicates an attempt to execute a
call to a server. The string binding in the Event Data field shows that
the call was made over the TCP/IP transport to host 16.31.48.109 with
endpoint 1821. This string binding identifies the server being
contacted.
- The call_end event indicates that the RPC call is
completed, and control has returned to the caller of
binopwk_add.
This log indicates that the RPC call to the binopwk_add
interface was successful because no error events occurred.
17.2 Generating RPC Event Logs
In general, to create an event log you must follow these four basic
steps:
- Specify the -trace option in your idl command
line to enable event logging.
- Compile and link the application.
- Assign the event log to a filename or to the screen.
- Run the application.
The next sections describe how to use the -trace option.
17.2.1 Enabling Event Logging
To enable event logging, you use a command line interface to the IDL
compiler. The IDL compiler supports two interfaces:
- A universal interface that can be used on any operating system
- A Digital Command Language (DCL) interface that can be used only on
the OpenVMS operating system
Your system manager determines which interface is available on your
system. The following sections describe each interface. The examples
use the universal interface to demonstrate event logging capabilities.
17.2.1.1 Universal IDL Compiler Interface
To enable event logging with the universal interface, specify the
-trace option when you use the idl command to compile
an interface. The syntax of the idl command with the
-trace option is as follows:
$ idl filename -trace value
|
Event types are specified as a value of -trace. Valid values
and the event types they denote are listed in Table 17-2.
Table 17-2 Event Values and Types
| Value |
Event Type |
|
all
|
Log all events.
|
|
none
|
Disable all previously specified trace options.
|
|
calls
|
Log events relating to start and end of all RPC calls.
|
|
context
|
Log events relating to context handle creation, deletion, and rundown.
|
|
errors
|
Log errors.
|
|
misc
|
Log all miscellaneous events.
|
|
log_manager
|
Enable command interface support which allows modification at runtime
of event logging options.
|
For more information about the -trace option, see Section 17.2.2.
17.2.1.2 Digital Command Language Interface for the Event Logger
This section defines the Digital Command Language (DCL) for the Event
Logger.
NAME
IDL /TRACE --- Invokes the Interface Definition Language (IDL) Compiler
with event logging enabled.
SYNOPSIS
IDL filename /TRACE
QUALIFIER
/TRACE=option[,...])
Controls whether event logging is enabled. If you do not specify this
qualifier, the compiler does not enable event tracing. To disable event
logging, specify /NOTRACE.
Specify one or more of the following options:
|
LOG_MANAGER
|
Controls whether the Log Manager command line interface is enabled. The
command line interface to the Log Manager allows you to modify event
logging options at runtime. If you do not specify the LOG_MANAGER
option, the command line interface will not be enabled. To disable the
Log Manager, specify NOLOG_MANAGER.
|
|
EVENTS=
value,...
|
Specifies the values for which event logging will be enabled. Specify
one or more of the values shown in the following table, except for the
value
log_manager. (This function is provided by the DCL LOG_MANAGER
qualifier.) If you specify only one option, you can omit the
parentheses.
|
Table 17-3 lists some commonly used event logging options in the
universal interface with DCL equivalents.
Table 17-3 Universal Interface with DCL Equivalents
| Universal Interface |
DCL Command |
|
-trace all
|
/TRACE=EVENTS=ALL
|
|
-trace log_manager
|
/TRACE=LOG_MANAGER
|
|
-trace all -trace log_manager
|
/TRACE=(LOG_MANAGER,EVENTS=ALL)
|
|
-trace errors -trace calls
|
/TRACE=EVENTS=(ERRORS,CALLS)
|
|