Using DBMS_DEBUG

Overview

To debug server-side code, you must have two database sessions: one session to run the code in debug mode (the target session), and a second session to supervise the target session (the debug session).

The target session becomes available for debugging by making initializing calls with DBMS_DEBUG. This marks the session so that the PL/SQL interpreter runs in debug mode and generates debug events. As debug events are generated, they are posted from the session. In most cases, debug events require return notification: the interpreter pauses awaiting a reply.

Meanwhile, the debug session must also initialize itself using DBMS_DEBUG: This tells it which target session to supervise. The debug session may then call entry points in DBMS_DEBUG to read events that were posted from the target session and to communicate with the target session.

The following subprograms are run in the target session (the session that is to be debugged):

DBMS_DEBUG does not provide an interface to the PL/SQL compiler, but it does depend on debug information optionally generated by the compiler. Without debug information, it is not possible to examine or modify the values of parameters or variables.

Constants

A breakpoint status may have the following value:

breakpoint_status_unused--breakpoint is not in use

Otherwise, the status is a mask of the following values:

breakpoint_status_active--a line breakpoint

breakpoint_status_disabled--breakpoint is currently disabled

breakpoint_status_remote--a shadow breakpoint (a local representation of a remote breakpoint)

Variables

Variable

Description

default_timeout

The timeout value (used by both sessions).The smallest possible timeout is 1 second. If this value is set to 0, then a large value (3600) is used.

BREAKPOINT_TABLE Type

TYPE breakpoint_table IS TABLE OF breakpoint_info INDEX BY BINARY_INTEGER;

INDEX_TABLE Type

This type is used by GET_INDEXES to return the available indexes for an indexed table.

TYPE index_table IS table of BINARY_INTEGER INDEX BY BINARY_INTEGER;

PROGRAM_INFO Types

This type specifies a program location. It is a line number in a program unit. This is used for stack backtraces and for setting and examining breakpoints. The read-only fields are currently ignored by Probe for breakpoint operations. They are set by Probe only for stack backtraces.

Type

Description

EntrypointName

Null, unless this is a nested procedure or function.

LibunitType

Disambiguate among objects that share the same namespace (for example, procedure and package specifications).

TYPE program_info IS RECORD
(
-- The following fields are used when setting a breakpoint
Namespace BINARY_INTEGER, -- See 'NAMESPACES' in following sections
Name VARCHAR2(30), -- name of the program unit
Owner VARCHAR2(30), -- owner of the program unit
Dblink VARCHAR2(30), -- database link, if remote
Line# BINARY_INTEGER,
-- Read-only fields (set by Probe when doing a stack backtrace)
LibunitType BINARY_INTEGER,
EntrypointName VARCHAR2(30)
);

VC2_TABLE Type

This type is used by SHOW_SOURCE.

TYPE vc2_table IS TABLE OF VARCHAR2(90) INDEX BY BINARY_INTEGER;

Exceptions

These values are returned by the various functions called in the debug session (SYNCHRONIZE, CONTINUE, SET_BREAKPOINT, and so on). If PL/SQL exceptions worked across client/server and server/server boundaries, then these would all be exceptions rather than error codes.

Value

Description

success

Normal termination.

Statuses returned by GET_VALUE and SET_VALUE:

Status

Description

error_bogus_frame

No such entrypoint on the stack.

error_no_debug_info

Program was compiled without debug symbols.

error_no_such_object

No such variable or parameter.

error_unknown_type

Debug information is unreadable.

error_indexed_table

Returned by GET_VALUE if the object is a table, but no index was provided.

error_illegal_index

No such element exists in the collection.

error_nullcollection

Table is atomically null.

error_nullvalue

Value is null.

Statuses returned by SET_VALUE:

Status

Description

error_illegal_value

Constraint violation.

error_illegal_null

Constraint violation.

error_value_malformed

Unable to decipher the given value.

error_other

Some other error.

error_name_incomplete

Name did not resolve to a scalar.

Statuses returned by the breakpoint functions:

Status

Description

error_no_such_breakpt

No such breakpoint.

error_idle_breakpt

Cannot enable or disable an unused breakpoint.

error_bad_handle

Unable to set breakpoint in given program (nonexistent or security violation).

General error codes (returned by many of the DBMS_DEBUG subprograms):

Status

Description

error_unimplemented

Functionality is not yet implemented.

error_deferred

No program running; operation deferred.

error_exception

An exception was raised in the DBMS_DEBUG or Probe packages on the server.

error_communication

Some error other than a timeout occurred.

error_timeout

Timout occurred.

Exception

Description

illegal_init

DEBUG_ON was called prior to INITIALIZE.

The following exceptions are raised by procedure SELF_CHECK:

Exception

Description

pipe_creation_failure

Could not create a pipe.

pipe_send_failure

Could not write data to the pipe.

pipe_receive_failure

Could not read data from the pipe.

pipe_datatype_mismatch

Datatype in the pipe was wrong.

pipe_data_error

Data got garbled in the pipe.

Operational Notes

There are two ways to ensure that debug information is generated: through a session switch, or through individual recompilation.

To set the session switch, enter the following statement:

ALTER SESSION SET PLSQL_DEBUG = true;

This instructs the compiler to generate debug information for the remainder of the session. It does not recompile any existing PL/SQL.

To generate debug information for existing PL/SQL code, use one of the following statements (the second recompiles a package or type body):

Figure 27-3 Debug Session (Cont.)

Control of the Interpreter

At startup of the interpreter so any deferred breakpoints may be installed prior to execution.

At any line containing an enabled breakpoint.

At any line where an interesting event occurs. The set of interesting events is specified by the flags passed to DBMS_DEBUG.CONTINUE in the breakflags parameter.

Session Termination

There is no event for session termination. Therefore, it is the responsibility of the debug session to check and make sure that the target session has not ended. A call to DBMS_DEBUG.SYNCHRONIZE after the target session has ended causes the debug session to hang until it times out.

Deferred Operations

The diagram suggests that it is possible to set breakpoints prior to having a target session. This is true. In this case, Probe caches the breakpoint request and transmits it to the target session at first synchronization. However, if a breakpoint request is deferred in this fashion, then:

SET_BREAKPOINT does not set the breakpoint number (it can be obtained later from SHOW_BREAKPOINTS if necessary).

SET_BREAKPOINT does not validate the breakpoint request. If the requested source line does not exist, then an error silently occurs at synchronization, and no breakpoint is set.

Diagnostic Output

To debug Probe, there are diagnostics parameters to some of the calls in DBMS_DEBUG. These parameters specify whether to place diagnostic output in the RDBMS tracefile. If output to the RDBMS tracefile is disabled, these parameters have no effect.

Common and Debug Session Sections

Common Section

The following subprograms may be called in either the target or the debug session:

OER Breakpoints

Exceptions that are declared in PL/SQL programs are known as user-defined exceptions. In addition, there are Oracle Errors (OERs) that are returned from the Oracle kernel. To tie the two mechanisms together, PL/SQL provides the exception_init pragma that turns a user-defined exception into an OER, so that a PL/SQL handler may be used for it, and so that the PL/SQL engine can return OERs to the Oracle kernel. As of the current release, the only information available about an OER is its number. If two user-defined exceptions are exception_init'd to the same OER, they are indistinguishable.

Namespaces

Program units on the server reside in different namespaces. When setting a breakpoint, specify the desired namespace.

Namespace_cursor contains cursors (anonymous blocks).

Namespace_pgkspec_or_toplevel contains:

Package specifications.

Procedures and functions that are not nested inside other packages, procedures, or functions.

Object types.

Namespace_pkg_body contains package bodies and type bodies.

Namespace_trigger contains triggers.

Libunit Types

These values are used to disambiguate among objects in a given namespace. These constants are used in PROGRAM_INFO when Probe is giving a stack backtrace.

LibunitType_cursor

LibunitType_procedure

LibunitType_function

LibunitType_package

LibunitType_package_body

LibunitType_trigger

LibunitType_Unknown

Breakflags

These are values to use for the breakflags parameter to CONTINUE, in order to tell Probe what events are of interest to the client. These flags may be combined.

Value

Description

break_next_line

Break at next source line (step over calls).

break_any_call

Break at next source line (step into calls).

break_any_return

Break after returning from current entrypoint (skip over any entrypoints called from the current routine).

break_return

Break the next time an entrypoint gets ready to return. (This includes entrypoints called from the current one. If interpreter is running Proc1, which calls Proc2, then break_return stops at the end of Proc2.)

break_exception

Break when an exception is raised.

break_handler

Break when an exception handler is executed.

abort_execution

Stop execution and force an 'exit' event as soon as DBMS_DEBUG.CONTINUE is called.

Information Flags

These are flags which may be passed as the info_requested parameter to SYNCHRONIZE, CONTINUE, and GET_RUNTIME_INFO.

Flag

Description

info_getStackDepth

Get the current depth of the stack.

info_getBreakpoint

Get the breakpoint number.

info_getLineinfo

Get program unit information.

Reasons for Suspension

After CONTINUE is run, the program either runs to completion or breaks on some line.

ATTACH_SESSION Procedure

Syntax

Parameters

Table 27-2 ATTACH_SESSION Procedure Parameters

Parameter

Description

debug_session_id

Debug ID from a call to INITIALIZE in target session.

diagnostics

Generate diagnostic output if nonzero.

CONTINUE Function

This function passes the given breakflags (a mask of the events that are of interest) to Probe in the target process. It tells Probe to continue execution of the target process, and it waits until the target process runs to completion or signals an event.

DELETE_OER_BREAKPOINT Function

Syntax

Parameters

Table 27-8 DELETE_OER_BREAKPOINT Function Parameters

Parameter

Description

oer

The OER (positive 4-byte number) to delete.

DETACH_SESSION Procedure

This procedure stops debugging the target program. This procedure may be called at any time, but it does not notify the target session that the debug session is detaching itself, and it does not terminate execution of the target session. Therefore, care should be taken to ensure that the target session does not hang itself.

Syntax

DBMS_DEBUG.DETACH_SESSION;

DISABLE_BREAKPOINT Function

This function makes an existing breakpoint inactive but leaves it in place.

Parameters

Table 27-11 ENABLE_BREAKPOINT Function Parameters

Return Values

Table 27-12 ENABLE_BREAKPOINT Function Return Values

Return

Description

success

Success.

error_no_such_breakpt

No such breakpoint exists.

error_idle_breakpt

Cannot enable an unused breakpoint.

EXECUTE Procedure

This procedure executes SQL or PL/SQL code in the target session. The target session is assumed to be waiting at a breakpoint (or other event). The call to DBMS_DEBUG.EXECUTE occurs in the debug session, which then asks the target session to execute the code.

Syntax

DBMS_DEBUG.EXECUTE (
what IN VARCHAR2,
frame# IN BINARY_INTEGER,
bind_results IN BINARY_INTEGER,
results IN OUT NOCOPY dbms_debug_vc2coll,
errm IN OUT NOCOPY VARCHAR2);

Parameters

Table 27-13 EXECUTE Procedure Parameters

Parameter

Description

what

SQL or PL/SQL source to execute.

frame#

The context in which to execute the code. Only -1 (global context) is supported at this time.

bind_results

Whether the source wants to bind to results in order to return values from the target session.

Parameters

Table 27-14 GET_INDEXES Function Parameters

Number of frame in which the variable or parameter resides; NULL for a package variable.

handle

Package description, if object is a package variable.

entries

1-based table of the indexes. If non-NULL, then entries(1) contains the first index of the table, entries(2) contains the second index, and so on.

Return Values

Table 27-15 GET_INDEXES Function Return Values

Return

Description

error_no_such_object

Either:

- The package does not exist.

- The package is not instantiated.

- The user does not have privileges to debug the package.

- The object does not exist in the package.

GET_MORE_SOURCE Procedure

When source does not fit in the buffer provided by that version of the SHOW_SOURCE Procedures which produce a formatted buffer, this procedure provides additional source.

Syntax

DBMS_DEBUG.GET_MORE_SOURCE (
buffer IN OUT VARCHAR2,
buflen IN BINARY_INTEGER,
piece# IN BINARY_INTEGER);

Parameters

Table 27-16 GET_MORE_SOURCE Procedure Parameters

Parameter

Description

buffer

The buffer.

buflen

The length of the buffer.

piece#

A value between 2 and the value returned in the parameter pieces from the call to the relevant version of the SHOW_SOURCE Procedures.

Usage Notes

This procedure should be called only after the version of SHOW_SOURCE that returns a formatted buffer.

GET_LINE_MAP Function

This function finds line and entrypoint information about a program so that a debugger can determine the source lines at which it is possible to place breakpoints.

Syntax

DBMS_DEBUG.GET_LINE_MAP (
program IN program_info,
maxline OUT BINARY_INTEGER,
number_of_entry_points OUT BINARY_INTEGER,
linemap OUT RAW)
RETURN BINARY_INTEGER;

Parameters

Table 27-17 GET_LINE_MAP Function Parameters

Parameter

Description

program

A top-level program unit (procedure / package / function / package body, and so on). Its Namespace, Name, and Owner fields must be initialized, the remaining fields are ignored.

maxline

The largest source code line number in 'program'.

number_of_entry_points

The number of subprograms in 'program'

linemap

A bitmap representing the executable lines of 'program'. If line number N is executable, bit number N MOD 8 will be set to 1 at linemap position N / 8. The length of returned linemap is either maxline divided by 8 (plus one if maxline MOD 8 is not zero) or 32767 in the unlikely case of maxline being larger than 32767 * 8.

Return Values

Table 27-18 GET_LINE_MAP Function Return Values

Return

Description

success

A successful completion.

error_no_debug_info

The program unit exists, but has no debug info.

error_bad_handle

No such program unit exists.

GET_RUNTIME_INFO Function

This function returns information about the current program. It is only needed if the info_requested parameter to SYNCHRONIZE or CONTINUE was set to 0.

Return Values

The newly-registered debug session ID (debugID)

Usage Notes

You cannot use DBMS_DEBUG and the JDWP-based debugging interface simultaneously. This call will either fail with an ORA-30677 error if the session is currently being debugged with the JDWP-based debugging interface or, if the call succeeds, any further use of the JDWP-based interface to debug this session will be disallowed.

Calls to DBMS_DEBUG will succeed only if either the caller or the specified debug role carries the DEBUGCONNECTSESSION privilege. Failing that, an ORA-1031 error will be raised. Other exceptions are also possible if a debug role is specified but the password does not match, or if the calling user has not been granted the role, or the role is application-enabled and this call does not originate from within the role-enabling package.

The CREATEANYPROCEDURE privilege does not affect the visibility of routines through the debugger. A privilege DEBUG for each object has been introduced with a corresponding DEBUGANYPROCEDURE variant. These are required in order to see routines owned by users other than the session's login user.

Authentication of the debug role and the check for DEBUGCONNECTSESSION privilege will be done in the context of the caller to this routine. If the caller is a definer's rights routine or has been called from one, only privileges granted to the defining user, the debug role, or PUBLIC will be used to check for DEBUGCONNECTSESSION. If this call is from within a definer's rights routine, the debug role, if specified, must be one that has been granted to that definer, but it need not also have been granted to the session login user or be enabled in the calling session at the time the call is made.

The checks made by the debugger after this call is made looking for the DEBUG privilege on individual procedures will be done in the context of the session's login user, the roles that were enabled at session level at the moment this call was made (even if those roles were not available within a definer's rights environment of the call), and the debug role.

PING Procedure

This procedure pings the target session to prevent it from timing out. Use this procedure when execution is suspended in the target session, for example at a breakpoint.

If the timeout_behaviour is set to retry_on_timeout then this procedure is not necessary.

Syntax

DBMS_DEBUG.PING;

Exceptions

Oracle will display the no_target_program exception if there is no target program or if the target session is not currently waiting for input from the debug session.

Usage Notes

Timeout options for the target session are registered with the target session by calling set_timeout_behaviour.

retry_on_timeout - Retry. Timeout has no effect. This is like setting the timeout to an infinitely large value.

continue_on_timeout - Continue execution, using same event flags.

nodebug_on_timeout - Turn debug-mode OFF (in other words, call debug_off) and then continue execution. No more events will be generated by this target session unless it is re-initialized by calling debug_on.

abort_on_timeout - Continue execution, using the abort_execution flag, which should cause the program to terminate immediately. The session remains in debug-mode.

retry_on_timeout CONSTANT BINARY_INTEGER:= 0;

continue_on_timeout CONSTANT BINARY_INTEGER:= 1;

nodebug_on_timeout CONSTANT BINARY_INTEGER:= 2;

abort_on_timeout CONSTANT BINARY_INTEGER:= 3;

PRINT_BACKTRACE Procedure

This procedure prints a backtrace listing of the current execution stack. This should only be called if a program is currently running.

Syntax

Table 27-27 PRINT_BACKTRACE Procedure Parameters

Parameter

Description

listing

A formatted character buffer with embedded newlines.

backtrace

1-based indexed table of backtrace entries. The currently-running procedure is the last entry in the table (that is, the frame numbering is the same as that used by GET_VALUE). Entry 1 is the oldest procedure on the stack.

PRINT_INSTANTIATIONS Procedure

This procedure returns a list of the packages that have been instantiated in the current session.

Syntax

DBMS_DEBUG.PRINT_INSTANTIATIONS (
pkgs IN OUT NOCOPY backtrace_table,
flags IN BINARY_INTEGER);

Parameters

Table 27-28 PRINT_INSTANTIATIONS Procedure Parameters

Parameter

Description

pkgs (OUT)

The instantiated packages

flags

Bitmask of options:

1 - show specs

2 - show bodies

4 - show local instantiations

8 - show remote instantiations (NYI)

16 - do a fast job. The routine does not test whether debug information exists or whether the libunit is shrink-wrapped.

Exceptions

no_target_program - target session is not currently executing

Usage Notes

On return, pkgs contains a program_info for each instantiation. The valid fields are: Namespace, Name, Owner, and LibunitType.

In addition, Line# contains a bitmask of:

1 - the libunit contains debug info

2 - the libunit is shrink-wrapped

PROBE_VERSION Procedure

This procedure returns the version number of DBMS_DEBUG on the server.

Syntax

DBMS_DEBUG.PROBE_VERSION (
major out BINARY_INTEGER,
minor out BINARY_INTEGER);

Parameters

Table 27-29 PROBE_VERSION Procedure Parameters

Parameter

Description

major

Major version number.

minor

Minor version number: increments as functionality is added.

SELF_CHECK Procedure

This procedure performs an internal consistency check. SELF_CHECK also runs a communications test to ensure that the Probe processes are able to communicate.

If SELF_CHECK does not return successfully, then an incorrect version of DBMS_DEBUG was probably installed on this server. The solution is to install the correct version (pbload.sql loads DBMS_DEBUG and the other relevant packages).

Syntax

DBMS_DEBUG.SELF_CHECK (
timeout IN binary_integer := 60);

Parameters

Table 27-30 SELF_CHECK Procedure Parameters

Parameter

Description

timeout

The timeout to use for the communication test. Default is 60 seconds.

Exceptions

Table 27-31 SELF_CHECK Procedure Exceptions

Exception

Description

OER-6516

Probe version is inconsistent.

pipe_creation_failure

Could not create a pipe.

pipe_send_failure

Could not write data to the pipe.

pipe_receive_failure

Could not read data from the pipe.

pipe_datatype_mismatch

Datatype in the pipe was wrong.

pipe_data_error

Data got garbled in the pipe.

All of these exceptions are fatal. They indicate a serious problem with Probe that prevents it from working correctly.

SET_BREAKPOINT Function

This function sets a breakpoint in a program unit, which persists for the current session. Execution pauses if the target program reaches the breakpoint.

Syntax

Parameters

Table 27-32 SET_BREAKPOINT Function Parameters

Parameter

Description

program

Information about the program unit in which the breakpoint is to be set. (In version 2.1 and later, the namespace, name, owner, and dblink may be set to NULL, in which case the breakpoint is placed in the currently-running program unit.)

line#

Line at which the breakpoint is to be set.

breakpoint#

On successful completion, contains the unique breakpoint number by which to refer to the breakpoint.

fuzzy

Only applicable if there is no executable code at the specified line:

0 means return error_illegal_line.

1 means search forward for an adjacent line at which to place the breakpoint.

-1 means search backward for an adjacent line at which to place the breakpoint.

Syntax

Parameters

Table 27-36 SET_TIMEOUT Function Parameters

The timeout to use for communication between the target and debug sessions.

SET_TIMEOUT_BEHAVIOUR Procedure

This procedure tells Probe what to do with the target session when a timeout occurs. This call is made in the target session.

Syntax

DBMS_DEBUG.SET_TIMEOUT_BEHAVIOUR (
behaviour IN PLS_INTEGER);

Parameters

Table 27-37 SET_TIMEOUT_BEHAVIOUR Procedure Parameters

Parameter

Description

behaviour - One of the following:

retry_on_timeout

Retry. Timeout has no effect. This is like setting the timeout to an infinitely large value.

continue_on_timeout

Continue execution, using same event flags.

nodebug_on_timeout

Turn debug-mode OFF (in other words, call debug_off) and continue execution. No more events will be generated by this target session unless it is re-initialized by calling debug_on.

abort_on_timeout

Continue execution, using the abort_execution flag, which should cause the program to terminate immediately. The session remains in debug-mode.

Exceptions

unimplemented - the requested behavior is not recognized

Usage Notes

The default behavior (if this procedure is not called) is continue_on_timeout, since it allows a debugger client to reestablish control (at the next event) but does not cause the target session to hang indefinitely.

SET_VALUE Function

This function sets a value in the currently-running program. There are two overloaded SET_VALUE functions.

Parameters

Table 27-38 SET_VALUE Function Parameters

Frame in which the value is to be set; 0 means the currently executing frame.

handle

Description of the package containing the variable.

assignment_statement

An assignment statement (which must be legal PL/SQL) to run in order to set the value. For example, 'x := 3;'.

Only scalar values are supported in this release. The right side of the assignment statement must be a scalar.

Return Values

Table 27-39 SET_VALUE Function Return Values

Return

Description

success

-

error_illegal_value

Not possible to set it to that value.

error_illegal_null

Cannot set to NULL because object type specifies it as 'not null'.

error_value_malformed

Value is not a scalar.

error_name_incomplete

The assignment statement does not resolve to a scalar. For example, 'x := 3;', if x is a record.

error_no_such_object

Either:

- Package does not exist.

- Package is not instantiated.

- User does not have privileges to debug the package.

- Object does not exist in the package.

Usage Notes

In some cases, the PL/SQL compiler uses temporaries to access package variables, and does not guarantee to update such temporaries. It is possible, although unlikely, that modification to a package variable using SET_VALUE might not take effect for a line or two.

However, this does not work for nonpersistent programs (for example, anonymous blocks and trigger invocation blocks). For nonpersistent programs, call SHOW_SOURCE. There are two flavors: one returns an indexed table of source lines, and the other returns a packed (and formatted) buffer.

The second overloading of SHOW_SOURCE returns the source in a formatted buffer, complete with line-numbers. It is faster than the indexed table version, but it does not guarantee to fetch all the source.

If the source does not fit in bufferlength (buflen), then additional pieces can be retrieved using the GET_MORE_SOURCE procedure (pieces returns the number of additional pieces that need to be retrieved).

SYNCHRONIZE Function

This function waits until the target program signals an event. If info_requested is not NULL, then it calls GET_RUNTIME_INFO.