Rogue Wave banner
Previous fileTop of DocumentContentsIndexNext file

6.4 Using Set Declaration Macros

The Execution Tracing package groups traceable functions into trace event sets, which provide precise control of trace output. Once the sets have been defined, trace output can be toggled on or off at the package, class, or function level, simply by defining the appropriate environment variables.

To determine if a function should generate a trace event, the Execution Tracing package uses a hierarchical lookup through the sets, as shown in Figure 30. For example, if the environment variable mapping to a particular function is set to ON, the event is generated. If the environment variable is set to OFF, the event is not generated. If the environment variable is undefined (or defined to something else), the environment variable mapping to the class, if any, is checked. If the class environment variable is undefined, the package environment variable is checked. If it is OFF or undefined, no event is generated. Thus, coarse-grained control of trace output can be achieved by setting only the package or class environment variables to ON. Classes and global functions marked with the RW_USER macros default to the predefined rw_user package, as in the example on Example 52. See Section 6.4.4. for information on setting environment variables.

Figure 30 -- Search path for events generated by global and member functions

The set declaration macros implement the run-time lookup of environment variables that determine whether a function will generate a trace event. Trace does not work correctly if the set declaration macros are not used or are used improperly. Set declaration macro names all include the word TRACEABLE, to distinguish them from event generation macros. Set declaration macros come in three varieties: package declaration macros, class declaration macros, and function declaration macros.

6.4.1 Package Declaration Macros

The package declaration macros are optional. You use them only when your application is split into packages, and you want to control tracing separately for each package. For information on how you can create your own packages and package tracing macros, see Section 6.9, "Using Package-level Tracing."


NOTE: A predefined package set named rw_user acts as a default super set for your classes and functions. If this single package set is sufficient for your purposes, you can skip this section.

The package declaration macros are used in the implementation of the Execution Tracing package itself. To get a feel for what these macros do, you can check the userdefs.h and userdefs.cpp files in the trace source directories.

The macros take one parameter, packageName, to specify the name of the package to be traced. The packageName must be a valid C++ identifier. The DECLARE and DEFINE macros must be used in pairs, and the packageName of the DECLARE and DEFINE macros must match.

RW_TRACE_DECLARE_TRACEABLE_PACKAGE(packageName)

RW_TRACE_DEFINE_TRACEABLE_PACKAGE(packageName)

6.4.2 Class Declaration Macros

The class declaration macros declare classes to be traceable, with the rw_user package as the super set. If you intend to trace any of a class' functions (member or static member), you must use these macros. Friend functions can either be traced with these macros or traced as global functions.

If you have used the package declaration macros to define other packages, you need to create your own class declaration macros. See Section 6.9, "Using Package-level Tracing."

The macros take one parameter, className, to specify the name of the class to be traced. The className must be a valid C++ identifier. The DECLARE and DEFINE macros must be used in pairs, and the className of the DECLARE and DEFINE macros must match.

RW_USER_DECLARE_TRACEABLE_CLASS(className)

RW_USER_DEFINE_TRACEABLE_CLASS(className)

RW_USER_DECLARE_TRACEABLE_TEMPLATE_CLASS(className)

RW_USER_DEFINE_TRACEABLE_TEMPLATE_CLASS(className)

6.4.2.1 Implications for Template Classes

Because you can place only one class declaration macro in each template class, you get only one environment variable, which controls the trace output from every instantiation of that particular template. You can't tell which instantiation of a template function produced a particular trace message. This is a known limitation of the Execution Tracing package.

6.4.3 Function Declaration Macros

The function declaration macros declare functions to be traceable. In addition, the macros automatically generate ENTRY and EXIT trace events upon entry and exit of the function. Every function that requires tracing must have one of these macros, normally as the first line of the function. Attempting to use more than one function declaration macro in a function results in compile or link errors.

The macro families come in sets of four macros, including an INLINE version for inline functions, a TEMPLATE version for template functions, a INLINE_TEMPLATE version for inline template functions, and a basic version for all other functions. Using the incorrect version results in compile and link errors.

Function declaration macros can take these parameters:

6.4.3.1 Macros for Global Functions

RW_USER_TRACEABLE_FUNCTION("functionTag")

RW_USER_TRACEABLE_INLINE_FUNCTION("functionTag")

RW_USER_TRACEABLE_TEMPLATE_FUNCTION("functionTag")

RW_USER_TRACEABLE_INLINE_TEMPLATE_FUNCTION("functionTag")

6.4.3.2 Macros for Member Functions

RW_USER_TRACEABLE_MEMBER("functionTag", className)

RW_USER_TRACEABLE_INLINE_MEMBER("functionTag", className)

RW_USER_TRACEABLE_TEMPLATE_MEMBER("functionTag", className)

RW_USER_TRACEABLE_INLINE_TEMPLATE_MEMBER("functionTag", className)

6.4.3.3 Macros for Static Member Functions

RW_USER_TRACEABLE_STATIC_MEMBER("functionTag", className)

RW_USER_TRACEABLE_INLINE_STATIC_MEMBER("functionTag", className)

RW_USER_TRACEABLE_TEMPLATE_STATIC_MEMBER("functionTag", className)

RW_USER_TRACEABLE_INLINE_TEMPLATE_STATIC_MEMBER
("
functionTag", className)

6.4.3.4 Macros for Friend Functions

RW_USER_TRACEABLE_FRIEND("functionTag", className)

RW_USER_TRACEABLE_INLINE_FRIEND("functionTag", className)

RW_USER_TRACEABLE_TEMPLATE_FRIEND("functionTag", className)

RW_USER_TRACEABLE_INLINE_TEMPLATE_FRIEND("functionTag", className)


NOTE: Each function in an application may be traceable as a friend to only one class. Friend functions can also be traced as global functions.

6.4.3.5 Implications for Template Classes

Because you can place only one function declaration macro in each template function, you get only one environment variable, which controls the trace output from every instantiation of that particular template function. It is not trivial to determine which instantiation of a template function produced a particular trace message. If this information is required, you need to get it yourself, using a mechanism such as RTTI, and include it in the trace macro call. This is a known limitation of the Execution Tracing package.

6.4.3.6 Assigning functionTag Names

The function declaration macros take a functionTag parameter (in quotes) to uniquely identify every traceable function. The tag appears in the trace output, so you can quickly find the function that generated a particular message.

Function names with special characters. The functionTag parameter must be a valid C++ identifier, so you need some convention to handle functions with characters that are invalid in C++ identifiers. Table  shows the convention used throughout Threads.h++. You are not required to follow this convention in your code.

Table 7 -- Conventions for functionTag parameters

 
Function NameSuggested Trace functionTag
ClassName::ClassName() (constructors)
"ClassName_ctor"
ClassName::~ClassName() (destructor)
"ClassName_dtor"
ClassName::operator==()
"ClassName_opEQ"
ClassName::operator!=()
"ClassName_opNE"
ClassName::operator<()
"ClassName_opLT"
ClassName::operator<=()
"ClassName_opLE"
ClassName::operator>()
"ClassName_opGT"
ClassName::operator>=()
"ClassName_opGE"
ClassName::operator=()
"ClassName_opAssign"
ClassName::operator>>()
"ClassName_opExtract"
ClassName::operator<<()
"ClassName_opInsert"
ClassName::operator()()
"ClassName_opFunctionCall"
ClassName::operator Type()
"ClassName_opType"

The limitation of functionTags to be valid C++ identifiers stems from the fact that some shells (ksh in particular) do not permit the creation of environment variables that do not follow C++ identifier conventions.

Overloaded functions. This functionTag convention overloads tags. For example, all constructors for a class have the same functionTag. If multiple functions have the same functionTag, the single environment variable controls every version of the function. For distinguishing among overloaded functions, extra characters indicating the signature of the function can be included in the tag name. For example, "ClassName_ctor_ic" could be used for ClassName::ClassName(int, char). Because Trace outputs the filename and line number of the location of each trace event, the function that generated a trace event can be determined.

6.4.4 Setting Environment Variables for Event Sets

Before you run your program, you need some system-level environment variables to control the trace event sets (as explained in Section 6.4). Use variable names identical to the functionTags, classNames, and packageNames in your set declaration macros. You do not have to define a variable for every set you declared. If you don't need to control every function separately, you can define variables for just the classNames. You can define variables for a few interesting functions and throw away the output from everything else. In fact, you can generate trace output from an entire program by setting just the rw_user environment variable to ON (assuming that you have not used package declaration macros).

See your operating system documentation for instructions on setting environment variables on your system.


NOTE: To display the value of your environment variables on DOS, use "set myVariable" instead of the echo command. If the variable is turned off, "echo %myVariable%" turns echo itself off.

Previous fileTop of DocumentContentsIndexNext file

©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.