Back to Arangodb

The Tracing Facility

3rdParty/boost/1.78.0/libs/wave/doc/tracing_facility.html

3.12.9.15.0 KB
Original Source

|

| The Tracing Facility | |

| | | | |

If you ever had the need to debug a macro expansion you had to discover, that your tools provide only little or no support for this task. For this reason the Wave library has a tracing facility, which allows to get selectively some information about the expansion of a certain macro or several macros.

The tracing of macro expansions generates a possibly huge amount of information, so it is recommended, that you explicitly enable/disable the tracing for the macro in question only. This may be done with the help of a special, Wave specific #pragma:

#pragmawave trace(enable)// enable the tracing// the macro expansions here will be traced// ... #pragmawave trace(disable)// disable the tracing

In C99 mode or when specifying the --variadics command line option you may additionally use the operator _Pragma() variant to enable/disable the tracing output:

#defineCONCAT(x, y) \\_Pragma("wave trace(enable)") \
        x \\_Pragma("wave trace(disable)") \##y

This way you have the possibility to enable the tracing during the expansion of a part of a macro only. In the sample shown there is traced the expansion of the macro argument 'x' only. Note, that the operator _Pragma() directives expand to nothing inside the macro expansion result.

To see, what the Wave driver generates while expanding a simple macro, let's have a look at the tracing output for the following example:

// test.cpp #defineX(x) x
 #defineY() 2
 #defineCONCAT_(x, y) x##y #defineCONCAT(x, y) CONCAT_(x, y) #pragmawave trace(enable) // this macro expansion is to be tracedCONCAT(X(1), Y())// should expand to 12 #pragmawave trace(disable)

When preprocessed with 'wave -t test.trace test.cpp' the Wave driver generates a file test.trace, which contains (without the line numbers in front of the lines):

1: test.cpp:8:1: CONCAT(X(1), Y())
  2: test.cpp:5:9: see macro definition: CONCAT(x, y)
  3: invoked with
  4: [
  5: x = X(1)
  6: y = Y()
  7: ]
  8: [
  9: test.cpp:2:9: see macro definition: X(x)
 10: invoked with
 11: [
 12: x = 1
 13: ]
 14: [
 15: 1
 16: rescanning
 17: [
 18: 1
 19: ]
 20: ]
 21: test.cpp:3:9: see macro definition: Y()
 22: [
 23: 2
 24: rescanning
 25: [
 26: 2
 27: ]
 28: ]
 29: CONCAT_(1, 2)
 30: rescanning
 31: [
 32: test.cpp:4:9: see macro definition: CONCAT_(x, y)
 33: invoked with
 34: [
 35: x = 1
 36: y = 2
 37: ]
 38: [
 39: 12
 40: rescanning
 41: [
 42: 12
 43: ]
 44: ]
 45: 12
 46: ]
 47: ]

The generated trace output is very verbose, but allows to follow every step of the actual macro expansion process. The first line in this tracing example contains the reference to the position, from where the macro expansion was initiated. Additionally the following information is contained for every single macro expansion:

  • The reference to the position (line and column numbers), where the macro to expand was defined first (see lines 2, 9, 21 and 32).
  • The real parameters supplied for this macro expansion (see lines 3, 10 and 33), this information is traced inside the invoked with block, where the corresponding formal and actual parameters are listed.
  • The expansion of the given arguments (if any and if these are defined as macros). This repeats the full tracing information for the argument macro expansion, only indented by one level. Note though, that the macro expansion of the actual arguments is traced, regardless of the fact, whether this argument is really to be inserted into the replacement list after its expansion or as it was initially supplied (see C++ Standard [16.3.1.1]: "A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token, is replaced by the corresponding argument after all macros contained therein have been expanded" [1]).
  • The result of the argument substitution (see lines 15, 23, 29 and 39), i.e. the substituted replacement list.
  • The rescanning process, which again includes the full subsequent macro expansion process of all found macros (see C++ Standard [16.3.4.1]: "After all parameters in the replacement list have been substituted, the resulting preprocessing token sequence is rescanned with all subsequent preprocessing tokens of the source file for more macro names to replace." [1]).
  • The result of the actual macro expansion (this is the last line inside the corresponding rescanning block - see lines 18, 26, 42 and 45).

Every found macro to expand will add an additional indentation level inside the trace output.

| | | | |


Copyright © 2003-2011 Hartmut Kaiser

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE\_1\_0.txt)

Last updated: Tuesday, March 21, 2006 9:25