Control of execution report generation

By default, the CoverageScanner library produces an execution report when the instrumented application exits. This might not be enough for unit test suites (where it is preferable to generate a report after each single test) or for applications like daemons which never terminate.

For these purposes, the CoverageScanner library also lets you:

  • embed C code into the instrumented application to control the report generation (see Unit testing).
  • generate a coverage report when a Microsoft® Windows event or a UNIX® signal has been received.

This section describes the second method.

Execution report generation with UNIX signals

To enable execution report generation with UNIX signals, use the option --cs-dump-on-signal=<sig>, where <sig> is the number of a signal or its common name, such as SIGUSR1.

With the UNIX kill command it is possible to trigger the report generation. (ex: kill -SIGUSR1 <pid>)

Execution report generation with Microsoft Windows events

To enable execution report generation with Microsoft Windows events, use the option --cs-dump-on-event=<event>, where <event> is a string which identifies the event.

Since there is no standard Windows equivalent to the UNIX kill command, Coco offers a replacement which is described in the following sections.

A program to send events to applications

Coco contains a tool to send events to Windows applications, for use with --cs-dump-on-event. It is not needed very often, and therefore you need to compile it yourself.

The program can be found in the directory <Windows Coco>\dump_on_event. It exists in two versions, one in C++ and one in C#. They are called dump_on_event and dump_on_event_cs, respectively.

To compile the program and see how it works, follow the instructions below. They refer to the C++ case. The C# version is quite similar, with the differences listed at the end.

  1. Copy the folder <Windows \COCO>\dump_on_event to some other place, such as C:\dump_on_event, since the original version is write protected.
  2. Double-click the file build_cpp to start the compilation of dump_on_event.cpp and of the example application event_sample_cpp.cpp. When the file event_sample_cpp.cpp is compiled, it is instrumented with the option --cs-dump-on-event=COVERAGE.
  3. After the programs have been compiled, three windows become visible.
    1. The window of the CoverageBrowser, with the contents of the file event_sample_cpp.exe.csmes loaded. It contains the source of the program event_sample_cpp, but not yet any coverage data.
    2. A window with a command prompt from which the program dump_on_event can be run later.
    3. A command window in which event_sample_cpp runs. Every second it prints a dot, and it will do so for five minutes.
  4. Now you can send the event COVERAGE to event_sample_cpp. Enter in the command prompt window:
    C:\dump_on_event>dump_on_event COVERAGE

    When the program event_sample_cpp receives the event, it creates a file event_sample_cpp.exe.csexe, which contains the coverage data that were generated so far.

    Send the command a second time. The file event_sample_cpp.exe.csexe then grows, since the new coverage data are appended to it. There is no danger that the same data are written twice.

  5. You can import the execution report from the CoverageBrowser with File > Load Execution Report. Each data dump appears as a separate execution, so if you have sent the event twice, you will see two executions in the Executions window.

The same recipe also works with the C# versions of the programs. You only need to replace build_cpp with build_cs, dump_on_event with dump_on_event_cs and event_sample_cpp with event_sample_cs.

Global events

In general, Windows events are created for a specific account and are therefore not accessible from other accounts on the same machine. But Windows also supports system-wide events. They have names that begin with Global\.

So to generate a code coverage report with Windows events from an application on a different account, system-wide events are needed.

In the following example, we use the program dump_on_event to generate the event:

  1. Compile your application with the argument --cs-dump-on-event=Global\COVERAGE.
  2. Start your application.
  3. On another account, execute the command:
    C:\dump_on_event>dump_on_event Global\COVERAGE

    The application then writes its coverage report to the disk.

Write your own program

You can also use dump_on_event as an example for sending events from your test setup. It is in fact only a wrapper for the Microsoft Windows function SetEvent():

#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
#include <iostream>

void DisplayError( LPTSTR lpszMessage )
{
    // Retrieve the system error message for the last-error code

    LPSTR lpMsgBuf;
    DWORD dw = GetLastError();

    FormatMessageA(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            dw,
            MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
            ( LPSTR ) &lpMsgBuf,
            0, NULL );

    // Display the error message and exit the process
    std::cerr << lpszMessage << " (error " << dw << "): " << lpMsgBuf << '\n';

    LocalFree( lpMsgBuf );
}

int main( int argc, char *argv[] )
{
    if ( argc != 2 )
    {
        std::cerr << "Usage: " <<  argv[0] << " <event_name>" << '\n';
        return 1;
    }

    const char * eventName = argv[1] ;

    HANDLE ghEvent = OpenEventA(
            EVENT_MODIFY_STATE,
            FALSE,
            eventName
            );

    if ( ghEvent == NULL )
    {
        DisplayError( "Opening event failed" );
        return 1;
    }

    if ( ! SetEvent( ghEvent ) )
    {
        DisplayError( "Raising event failed" );
        CloseHandle( ghEvent );
        return 1;
    }

    CloseHandle( ghEvent );
    return 0;
}