The Program Execution Monitor

Boost.Test > Components > The Program Execution Monitor

# Boost Test Library: The Program Execution Monitor

## Introduction

The components of a C++ program may report user-detected errors in several ways, such as via a return value or throwing an exception. System-detected errors such as dereferencing an invalid pointer are reported in other ways, totally operating system and compiler dependent.

Yet many C++ programs, both production and test, must run in an environment where uniform reporting of errors is necessary. For example, converting otherwise uncaught exceptions to non-zero program return codes allows many command line, script, or batch environments to continue processing in a controlled manner. Even some GUI environments benefit from the unification of errors into program return codes.

The Boost Test Library's Program Execution Monitor relieves users from messy error detection and reporting duties by providing a replacement function main() which calls a user-supplied cpp_main() function within a monitored environment. The supplied main() then uniformly detects and reports the occurrence of several types of errors, reducing them to a uniform return code which is returned to the host environment.

Uniform error reporting is particularly useful for programs running unattended under control of scripts or batch files. Some operating systems pop up message boxes if an uncaught exception occurs, and this requires operator intervention. By converting such exceptions to non-zero program return codes, the library makes the program a better citizen. More uniform reporting of errors isn't a benefit to some programs, particularly programs always run by hand by a knowledgeable person. So the Program Execution Monitor wouldn't be worth using in that environment.

Uniform error reporting could be also useful in test environments such as the boost regression tests. Be aware though in such case it might be preferable to use the Test Execution Monitor or the Unit Test Framework, cause they allows one to use Test Tools and generate more detailed errors information.

## Usage

Using the Program Execution Monitor, the traditional Hello World program becomes:

    #include <iostream>

    int cpp_main( int, char* [] ) // note name
    {
        std::cout << "Hello, world\n";

        return 0;
    }

It really is that simple - just change the name of your initial function from main() to cpp_main(). Do make sure the argc and argv parameters are specified (although you don't have to name them if you don't use them). Now you can compile it and link with the Program Execution Monitor library.

When the above program executes, the output will be:

Hello, world
no errors detected

But what if some lower-level function had thrown a runtime_error with the message "big trouble"? Then the output would look something like this:

**** exception(205): std::runtime_error: big trouble
******** errors detected; see standard output for details ********

And if a function cpp_main() had bubbled up a return code of 5, the output would look something like this:

**** error return code: 5
******** errors detected; see standard output for details ********

Note that the primary error messages appear on standard output stream, while the final errors notification message appears on standard error stream. This increases the visibility of error notification if standard output and error streams are directed to different devices or files.

## Configuration

There are two aspects of the Program Execution Monitor behavior that you can customize at runtime. Customization performed using environment variables.

BOOST_TEST_CATCH_SYSTEM_ERRORS - allows to customize behavior of the Execution Monitor in regards of catching system errors. For more details about the meaning of this option see the Execution Monitor documentation. If you want to prevent the Program Execution Monitor from catching system exception, set the value of this variable to "no". The default value is "yes".

BOOST_PRG_MON_CONFIRM - allows to avoid success confirmation message. Some users prefer to see a confirmation message in case if program successfully executed. While others don't like the clutter or any output is prohibited by organization standards. To avoid the message set the value of this variable to "no". The default value is "yes".

## Implementation

To monitor execution of user supplied function cpp_main() the Program Execution Monitor relies on the Boost Test's Execution Monitor . Also the Program Execution Monitor supply function main() in <libs/test/src/cpp_main.cpp>. For the program to link successfully user is required to supply a function cpp_main() with same interface as the main(). The Program Execution Monitor treat as errors:

- Exceptions thrown from cpp_main().
- Non-zero return from cpp_main().

The Program Execution Monitor reports errors to both cout (with details) and cerr (summary). Detailed error reporting goes to cout so that it is properly interlaced with other output, thus aiding error analysis. Summary goes to cerr in case cout is redirected. The Program Execution Monitor's supplied main() will return following result codes:

- boost::exit_success - no errors
- boost::exit_failure - non-zero and non-boost::exit_success return code from cpp_main().
- boost::exit_exception_failure - cpp_main() throw an exception.

Check compilation instructions to see how to build standalone library for this component.

## Examples and tests

prg_exec_example
prg_exec_fail1
prg_exec_fail2
prg_exec_fail3
prg_exec_fail4