If you're not familiar with code instrumentation, this blog post :-
gives a good overview of its basic concepts, all of which are made available to PL/SQL by BMC_DEBUG. Its interesting to note that this particular blog is nothing to do with PL/SQL (It's actually written by a .Net development company) but the concepts it describes are applicable to all procedural code development irrespective of the language used.
If you have experience of supporting a production PL/SQL application, you may recognise the following sequence of events :-
A problem is found with execution of a procedure in the live production environment
The only details of the error you can gain from the production system are the name of the failing package, and the line number at which the exception occurred
You create a subset of live data in a test environment to try to reproduce the error
You manage to reproduce the error on the test system
You add some debugging statements to the failing procedure, such as calls to DBMS_OUTPUT, or INSERTs into a logging table to try to locate the cause of the error
You find the cause of the problem, and implement a fix
You remove the code which you added to monitor the execution of the failing procedure, and drop the tables containing the test data
The code with the fix applied is deployed to the live production system
A few hours/days/weeks later, another problem is found and you are back to step 1 ...
If this sounds familiar, you'll be pleased to hear that instrumentation can massively assist with the process of identifying and fixing errors in live code.
The key difference between instrumentation and traditional debugging is that instrumentation statements remain in your code when it is deployed into your live production system. You don't add instrumentation to find a specific problem, then remove it once the problem is found. BMC_DEBUG gives you the ability to dynamically control which aspects of the live execution of your code are monitored and when, simply by changing entries in the instrumentation parameter tables.
For example, you can change which application messages are written to the log table and when, or change which statistics are captured and how they are recorded ,without the need to recompile or redeploy your code.
Other features which BMC_DEBUG provides are :-
Monitoring of code execution via V$SESSION or a global context
The message store, a rolling window of recent messages, so details of the last n messages can be included in an unhandled exception report even if they weren't being written to the log table
The ability to log which parameter values were passed into a procedure, and include them when logging the details of an unhandled exception
The ability to apply instrumentation to triggers, so you can record which triggers fire and when during the execution of a procedure
Conditional statistics gathering, so you can record, for example, when a procedure runs for more than x seconds, and log the parameters which were passed to that invocation of the procedure.
These features make debugging code much easier, and reduce the amount of work needed to reproduce or remedy unhandled exceptions or performance problems.
Performance Concerns
A question which is often asked about code instrumentation is - Doesn't it impact performance? Surely adding extras calls into your own code will slow it down?
Tom Kyte has some interesting opinions on this subject :-
https://web.archive.org/web/20150622040417/http://tkyte.blogspot.co.uk/2005/06/instrumentation.html
But if you're still not convinced, consider the Oracle RDBMS. It is packed to the eyeballs with instrumentation (the V$ and X$ views, the event model, AWR, ASH etc).
Imagine if there were two versions of the Oracle RDBMS, one which was instrumented and the other which wasn't. Naturally you'd run your production workload on the non-instrumented version, to take advantage of the performance gains from not having to perform the extra calls.
This would be fine until you hit a problem, finding a solution to which needed the extra information which instrumentation provided. Then you would :-
Shutdown your production system
Point it at the instrumented version of Oracle
Startup the database
Run your production system until the problem occurred
Capture the information you needed to solve the problem
Shutdown the production system
Point it at the non-instrumented version of Oracle
Startup the database
Run the production system as normal
After doing this a couple of times, you might decide that the one or two percent performance loss from running the instrumented version all the time was worth it, due to the extra convenience of being able to capture statistics, events and error details while your live system is running.
The same goes for your own code. With instrumentation in place and enabled, your code will be running some extra SQL statements, but exactly which operations the instrumentation performs is highly configurable, and can even be dynamically disabled for individual users or for every database connection, so hopefully this ability will ease your concerns about deploying instrumented code into your production environment.