Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component balst_stacktraceframe
[Package balst]

Provide an attribute class describing an execution stack frame. More...

Namespaces

namespace  balst

Detailed Description

Outline
Purpose:
Provide an attribute class describing an execution stack frame.
Classes:
balst::StackTraceFrame a description of one frame of an execution stack
See also:
Component balst_stacktrace
Description:
This component provides a single, simply-constrained (value-semantic) attribute class, balst::StackTraceFrame, that describes a stack frame from the execution stack of a function call. Additional methods are provided to indicate whether a given attribute is considered "unknown".
Attributes:
  Name               Type          Default     Constraint
  -----------------  -----------   ----------  ----------
  address            const void *  0           none
  libraryFileName    bsl::string   ""          none
  lineNumber         int           -1          'lineNumber >= -1'
  mangledSymbolName  bsl::string   ""          none
  offsetFromSymbol   bsl::size_t   (size_t)-1  none
  sourceFileName     bsl::string   ""          none
  symbolName         bsl::string   ""          none
  • address: the return address in the parent (calling) function on return from the child (called) function.
  • libraryFileName: the executable or shared-library file name containing the parent function.
  • lineNumber: the source line number in the parent function corresponding, corresponding to a call to the child function.
  • mangledSymbolName: mangled symbol name of the parent function (in C code, the "mangled" name matches the symbol name.)
  • offsetFromSymbol: offset from the start of the parent function to the call to the child function.
  • sourceFileName: Name of the source file of the parent function.
  • symbolName: unmangled symbol name of the parent function (in C, code symbol name matches the mangled symbol name.)
Unknown Values:
For each attribute, a particular value is reserved to designate that the attribute value is "unknown". Default constructed objects are created with the designated "unknown" value for each attribute.
Supplementary Methods:
In addition to the usual setters and getters, the balst::StackTraceFrame attribute class provides also provides a suite of non-'static', (boolean-valued) predicate methods, of the form is<attributeName>Known. Each of these return true if the object attribute named by the method does not contain the designated "unknown" value for that attribute, and false otherwise.
Usage:
In this example, we create two balst::StackTraceFrame objects, modify their properties, and compare them. First, we create the objects a and b:
  balst::StackTraceFrame a, b;
  assert(a == b);
Then, we verify all values are initialized by the constructor to "unknown" values:
  assert(false == a.isAddressKnown());
  assert(false == a.isLibraryFileNameKnown());
  assert(false == a.isLineNumberKnown());
  assert(false == a.isMangledSymbolNameKnown());
  assert(false == a.isOffsetFromSymbolKnown());
  assert(false == a.isSourceFileNameKnown());
  assert(false == a.isSymbolNameKnown());
Next, we assign a value to the lineNumber attribute of a and verify:
  a.setLineNumber(5);
  assert(true == a.isLineNumberKnown());
  assert(5    == a.lineNumber());
  assert(a    != b);
Next, make the same change to b and thereby restore it's equality to a:
  b.setLineNumber(5);
  assert(true == b.isLineNumberKnown());
  assert(5    == b.lineNumber());
  assert(a    == b);
Next, we update the address attribute of a and use the address accessor method to obtain the new value for the update of b:
  a.setAddress((char *) 0x12345678);
  assert(a != b);

  b.setAddress(a.address());
  assert(true                == a.isAddressKnown());
  assert(true                == b.isAddressKnown());
  assert((char *) 0x12345678 == a.address());
  assert((char *) 0x12345678 == b.address());
  assert(a.address()         == b.address());
  assert(a                   == b);
Finally, we exercise this sequence of operations for two other attributes, symbolName and sourceFileName:
  a.setSymbolName("woof");
  assert(a    != b);

  b.setSymbolName(a.symbolName());
  assert(true == a.isSymbolNameKnown());
  assert(true == b.isSymbolNameKnown());
  assert(0    == bsl::strcmp("woof", a.symbolName().c_str()));
  assert(0    == bsl::strcmp("woof", b.symbolName().c_str()));
  assert(a    == b);

  a.setSourceFileName("woof.cpp");
  assert(a != b);
  b.setSourceFileName(a.sourceFileName());
  assert(a.isSourceFileNameKnown());
  assert(b.isSourceFileNameKnown());
  assert(0 == bsl::strcmp("woof.cpp", a.sourceFileName().c_str()));
  assert(0 == bsl::strcmp("woof.cpp", b.sourceFileName().c_str()));
  assert(a == b);