IBM®
Skip to main content
    Country/region [select]      Terms of use
 
 
      
     Home      Products      Services & solutions      Support & downloads      My account     

developerWorks > DB2 >
developerWorks
Debugging using the DBDK-generated tracing features
Downloade-mail it!
Contents:
Introduction
What are the DBDK Tracing Features?
How is the DBDK Tracing Activated?
Adding Your Own Trace Messages
Resources
Download
About the author
Rate this article
Subscriptions:
dW newsletters
dW Subscription
(CDs and downloads)

Level: Intermediate

William W. White
IBM
11 Sep 2001

This article shows how to debug an Informix C UDR using DBDK-generated tracing. Includes sample C source code.

Introduction
When you use the DataBlade Developer's Kit to kick-start your DataBlade project, your generated code can include some nice tracing features that you might find very useful someday if you ever have to debug your product at a customer site. But tracing capabilities may be more than just useful.

What are the DBDK Tracing Features?
Tracing features provided by the DataBlade Developer's Kit can be found in three places:

Tracing Features in the C Code
When you select "Generate DataBlade -> Source" in BladeSmith, a "stub" C source file is created for your DataBlade, which includes C functions to support each of the SQL functions that you declared and specified to be based on C code. By default, your generated source code does not include tracing. To enable tracing, select "Generate" and "Source", then set the "Tracing" property to "true". Your support.c file will now contain a routine called Gen_Trace(), and trace statements will be embedded in your DataBlade's function calls. In addition, a TraceSet_<bladename> routine will be generated in support.c.

If you look at the generated code for one of your functions, you'll see three kinds of tracing calls:

  • DBDK_TRACE_ERROR is called if an error occurs -- for example, if the function is unable to obtain a connection handle.

  • DBDK_TRACE_ENTER is called at the beginning of your function.

  • DBDK_TRACE_EXIT is called just before leaving your function.

Each of these macros calls Gen_Trace().

Tracing Features in the Header File
The macros used in the generated source code are defined in the header file that BladeGen creates for your DataBlade. There are two general categories of macros:

  • DBDK_TRACE_ERROR

  • DBDK_TRACE_MSG

The DBDK_TRACE_ENTER and DBDK_TRACE_EXIT macros are special cases of DBDK_TRACE_MSG. All of the macros are designed to simplify calls to Gen_Trace() by reducing the number of arguments required.

In addition to the tracing macros, the generated header file contains #define statements for a set of pre-defined error messages. These statements map the ERRORMESG numbers used by the tracing macros to the NAME column in the SYSTRACEMSGS catalog.

Tracing Features in the System Catalogs
As noted above, the trace messages used by the DBDK tracing modules are stored in the SYSTRACEMSGS system catalog.

If you create a new database and look at this table, you'll find that it's empty. When you register a DataBlade, the BladeSmith utility seeds the table with a collection of standard messages. These messages are shared by all DataBlade modules, and should not be changed. You can, however, add your own messages. See Adding Your Own Trace Messages below for details.

How is the DBDK Tracing Activated?
This section describes the steps you need to take to enable (and disable) tracing.

  1. Creating the TraceSet_<bladename> SQL procedure.

  2. Creating a trace class

  3. Setting the trace level for a session.

  4. Setting the trace output file (optional).

  5. Setting the appropriate locale.

Creating the TraceSet_<bladename> procedure.
If you specify "Tracing=True" when you "Generate DataBlade -> Source", DBDK generates a TraceSet_< bladename> function for your DataBlade module, where bladename is the name of your DataBlade module. This routine calls two DataBlade API functions:

  • mi_tracefile_set()

  • mi_tracelevel_set()

Although your DataBlade's .bld file will contain the executable code for your TraceSet_<bladename> routine, the generated scripts that register your DataBlade in a database don't include the directive to create the corresponding SQL procedure. This is because tracing is considered a development/debugging tool; it is assumed that end users won't normally use it.

To create the SQL procedure to turn on tracing for your DataBlade, follow the instructions in the comments block in the source for your TraceSet_<bladename> routine. The SQL statement will look like this:


 CREATE PROCEDURE TraceSet_myblade (lvarchar, int) 
  with(NOT VARIANT) EXTERNAL NAME 
   "/path/myblade.bld(TraceSet_myblade)" 
   LANGUAGE C END PROCEDURE; 

Where "myblade" is the name of your DataBlade module, and "/path" is the path to your DataBlade's installation directory, normally "$INFORMIXDIR/extend/<bladename.revision". The comments block in your TraceSet_<bladename> source code will show the exact syntax for your DataBlade.

Once you have run BladeManager to register your DataBlade in a database, and used the above SQL statement to create your TraceSet procedure, you can turn on tracing for an SQL session with the following SQL statement:


 EXECUTE PROCEDURE TraceSet_myblade("/path/file", 20); 

Where "/path/file" is the full path to your trace log.

Creating a trace class
The tracing features supported by the DataBlade API (DPRINTF and its internationalized counterpart GL_DPRINTF, which is used by the DBDK) are based on the concept of trace classes. These let you set up categories of tracing and turn them on or off independently, to "tune" your tracing output so that you only see trace messages associated with the part of your DataBlade where you suspect there might be a problem. See the DataBlade API Programmer's Manual for more information about trace classes.

The built-in tracing provided by the DBDK assumes you'll have a single trace class, and that its name is the same as the name of your DataBlade module.

Trace classes are maintained in the systraceclasses system catalog. If your DataBlade name is "Foo", use the following SQL statement to create a trace class "Foo":


 insert into systraceclasses (name) values ('Foo'); 

Setting a trace level
Trace level is the the "volume knob" in the DataBlade API tracing facility. You specify a level for each trace message in your code, and when you run your DataBlade with tracing turned on, you specify a threshold. Any message in your code whose level is specified to be within that threshold is printed to the trace file, and any that are not within that threshold are not printed.

The basic tracing provided by the DBDK uses trace level 20. So, to see the DBDK_TRACE_ENTER and DBDK_TRACE_EXIT messages, turn on tracing for the appropriate trace class, and set the level to at least 20.

Setting the trace output file
The TraceSet_myblade() routine that you created above takes two arguments:

  • A filename

  • A trace level

The filename argument specifies the file into which your trace messages will be written. So, to turn on tracing for a session, directing the output to "/tmp/myblade.trc", and setting the trace level to "20", use the following SQL call:


 EXECUTE PROCEDURE TraceSet_myblade ("/tmp/myblade.trc", 20); 

You have the option of letting the system assign an output file, instead of choosing one yourself. To do so, leave the filename argument blank when you call TraceSet_myblade:


 EXECUTE PROCEDURE TraceSet_myblade("", 20); 

The server will create a file in /tmp with a numeric base and the extension ".trc", e.g., "/tmp/123.trc". The base part of the name is your session number.

Setting your locale
So, you've created a trace class, created a TraceSet_<bladename> SQL procedure, called it to set the trace level to 20, and invoked a procedure in your DataBlade, and you don't see any useful output in your trace file. What's wrong?

If your trace file looks like this:


 ======================================= Tracing session: 61 on 10/20/1997  10:40:20 10:48:20 

then chances are you have your LOCALE variables set incorrectly. Take a look at your systracemsgs catalog, i.e.:


 SELECT * FROM SYSTRACEMSGS; 

Chances are the "locale" column is set to "en_us.8859-1"; this is the default for US English on the Unix platform. The system will only display messages to your session that match the locale specified in your session's CLIENT_LOCALE environment variable. To see the messages whose locale is en_us.8859-1, set your environment as follows:


 % setenv CLIENT_LOCALE en_us.8859-1 

(Note that this syntax is for the UNIX C shell. If you are using the Bourne shell, Bash, or ksh, modify your syntax accordingly. If you are using SQL Editor on NT, you can set this environment variable via SetNet32.)

Now try again. Your trace file should look something like this:


 ================================
  Tracing session: 62 on 10/20/1997 10:55:32 
 Entering function UpOne (TraceDemo.c). 
 10:55:32 Successfully exiting UpOne (TraceDemo.c). 

Adding Your Own Trace Messages
Once basic tracing is enabled for your DataBlade module, adding your own additional messages is easy. All you need to do is:

  1. Add an entry to the systracemsgs system catalog.

  2. Add tracing statements to your routine's C code.

  3. (Optional) Add messages with variable text.

Adding an entry to systracemsgs:
You should be able to add a message to the systracemsgs system catalog simply by adding an "Error" to your DataBlade using BladeSmith:

  1. Select "Edit", "Insert", "Error".

  2. Enter an appropriate "SQL error code".

  3. Specify the "Error locale" (typically "en_us.8859-1" for a Unix server, or "en_us.1252" for NT).

  4. Set "Register message as" to "Trace".

  5. Type in the appropriate "SQL error text", e.g., "User-defined trace message."

  6. "Save", and Generate Scripts.

When you register your DataBlade in a database, your new trace message will be added to the systracemsgs system catalog.

Note: In addition to h2traceh2 messages, you can also set h2errorh2 messages using BladeSmith. Follow the steps above, but set the "Register message as" to "Error" (step 4). Errors are used by the mi_db_error_raise() DataBlade API call. See the DataBlade API Programmer's Manual for detailed information about mi_db_error_raise().

Adding tracing statements to your C code:
Now you can use the DBDK tracing macros (defined in your DataBlade's generated .h file) to output your new message. For example, you might add the following statement to your C code:


 /* Trace message added for demo: */  DBDK_TRACE_MSG( "TraceDemo", "TD002", 20 ); 

In this example, we used the same trace class as is used by the DBDK_TRACE_ENTER and DBDK_TRACE_EXIT macros ("TraceDemo"), we used the new systracemsgs name ("TD002"), and we set the threshold to the same value as the _ENTER and _EXIT macros use (20).

Now when we run the demo as above, our trace file looks like this:


 ====================================== 
 Tracing session: 18 on 10/20/1997 11:14:22 
 Entering function UpOne (TraceDemo.c). 
 11:14:22 User-defined trace message. 
 11:14:22 Successfully exiting UpOne (TraceDemo.c). 

We could (and the demo does) create several new trace messages and set each one to fire at a different trace level setting. For example, we could create these trace messages:


 TD001     This will be a low-threshold message. 
 TD002     This will be a medium-threshold trace message. 
 TD003     This will be a high-threshold trace message. 

We could put the following code in our C routine:


 DBDK_TRACE_MSG( "TraceDemo", "TD001", 10 ); 
 DBDK_TRACE_MSG( "TraceDemo", "TD002", 20 ); 
 DBDK_TRACE_MSG( "TraceDemo", "TD003", 30 ); 

Now when we call our function, the messages we see in our trace file will depend on the trace level we use in the SQL session. Any trace level 10 or higher will cause TD001 to be printed, a trace level of 20 or higher will cause TD001 and TD002 to print, and a trace level of 30 or higher will cause all three messages to print to the trace log.

Adding messages with variable text
Suppose you want to include a trace message with text that you can specify when you make the call? For example, you may want to track the number of times you pass through a loop.

The DBDK doesn't provide macros that handle variable arguments, but you can call GL_DPRINTF directly to accomplish this.

To include variable text in your trace messages, enclose a keyword in percent signs in the "SQL error text", and then specify the keyword, a printf-style format specifier, and the substitution text when you invoke the message.

For example, your "SQL error text" might look like this:


 Times through the loop = %COUNTER% 

When you call GL_DPRINTF in your program, you include the keyword followed by a format specifier, and the value to substitute:


 GL_DPRINTF("TraceDemo", 60, 
   ("TD005", "COUNTER%d", i, MI_LIST_END)); 

In this example, TraceDemo is the trace class name, 60 is the trace level, TD005 is the trace message name, COUNTER is the keyword, %d is the format specifier, i is an integer value, and MI_LIST_END is a flag that signals the end of your list of substitution variables.

If you call your routine in an SQL session where the trace level is set to 60 or higher, you'll see lines like the following in your trace log:


 08:49:20     Times through the loop = 1 
 08:49:21     Times through the loop = 2 

The downloadable demo includes trace messages with variable text.


IBM, DB2, Informix, and WebSphere are trademarks or registered trademarks of IBM Corporation in the United States, other countries, or both.

Windows and Windows NT are registered trademarks of Microsoft Corporation in the United States, other countries, or both.

Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.

Other company, product, and service names may be trademarks or service marks of others.

IBM copyright and trademark information

Resources

Additional information can be found in the following sources:

  • DataBlade Developer's Kit User Guide

  • DataBlade API Programmer's Manual

  • Informix Guide to SQL: Reference

  • DataBlade Developer's Kit (see the online help)

Download
NameSizeDownload method
jTrace.1.0.tar.Z22.3 KBFTP|HTTP
*Information about download methods
About the author
William White is a contributing Informix author.


Downloade-mail it!
Rate this article

This content was helpful to me:

Strongly disagree (1)Disagree (2)Neutral (3)Agree (4)Strongly agree (5)

Comments?



developerWorks > DB2 >
developerWorks
    About IBM Privacy Contact