Sometimes we need to call a function and make sure that no user- or system-originated exceptions are being thrown by it. Uniform exception reporting is also convenient. That's the purpose of the Boost.Test's Execution Monitor.
The Execution Monitor is a lower-level component of the Boost Test Library. It is the base for implementing all other Boost.Test components but also can be used standalone to get controlled execution of error-prone functions with a uniform error notification. The Execution Monitor calls a user-supplied function in a controlled environment, relieving users from messy error detection.
All symbols in the Execution Monitor implementation are located in the namespace boost. To use the Execution Monitor you need to:
To start the monitored function, call the method execution_monitor::execute( function_to_monitor, catch_system_exception, timeout ). If the call succeeds, it returns the integer value returned by the monitored function. If any of the following events occurs:
then the method execution_monitor::execute( ... ) throws the boost::execution_exception. The method execution_monitor::execute( ... ) has two optional parameters allowing you to modify its behavior. The second parameter is a boolean flag catch_system_errors (default true) specifying whether or not execution monitor should trap system level exceptions (second category in above list). Set this value to false, for example, if you wish to force coredump file creation. High-level Boost.Test components provide a runtime parameter --catch_system_errors=yes for managing this behavior in monitored unit tests. For some operating systems (not yet Microsoft Windows) a third parameter is an integer timeout (in seconds) for monitored function execution. Use this parameter to monitor code with possible deadlocks or indefinite loops. For more detailed see execution monitor specification.
In majority of the cases the monitored function doesn't need to throw the boost::execution_exception to report an error in the Execution Monitor. If you want a custom error message to be included into the execution_exception's error message, use one of the following C++ types as an exception:
If you need to abort the monitored function without the Execution Monitor reporting any errors, you could throw the boost::execution_aborted. In case if you prefer or are forced to use your own exception types and don't like "unknown exception caught" message, the Execution Monitor allows you to register the translator for any exception types. You could register as many independent translators as you like. See execution monitor specification for requirements on translator function. Also see below for usage example.
The Execution Monitor facility provides a limited ability to detect memory leaks during program execution, and to break program execution on specific memory allocation order-number (1 - first allocation of memory in program, 2 - second and so on). Unfortunately this feature is, at the moment, implemented only for the Microsoft family of compilers (and Intel, if it employs Microsoft C Runtime Library). Also it could not be tuned per instance of the monitor and is only triggered globally and reported after the whole program execution is done. In a future this ought to be improved. An interface is composed from two free functions residing in namespace boost:
void detect_memory_leak( bool on_off ); void break_memory_alloc( long mem_alloc_order_num );
Use function detect_memory_leaks to switch memory leaks detection on/off. Use break_memory_alloc to break a program execution at allocation specified by mem_alloc_order_num argument. High level Boost.Test components provide a runtime parameter (--detect_memory_leak=yes or no) allowing one to manage this feature during monitored unit tests.
The Execution Monitor is implemented in two modules: one header file and one source file.
provides execution monitor implementation for all supported configurations, including Microsoft structured exception based, UNIX signals. Note that when testing requirements or user wishes preclude use of this file as a separate compilation unit, it may be included as a header file.
Check compilation instruction to see how to build a standalone library for this component.
While designing we were aware that it can be used when no (or almost no) memory available. The Execution Monitor is intended to be portable to as many platforms as possible.