Boost logo

Boost :

Subject: [boost] [contract] "Duplicated globals" problem
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2012-08-25 16:52:40


Hi Lorenzo,
I think that installing broken contract handlers will not work correctly
when a program is linking with DLLs on Windows. I do not know how dynamic
linking works on Linux. Here is a sketch of a sample program that fails to
work as expected. The program consists of two projects: one builds a DLL,
the other builds an executable that links with the DLL:

DLL:
====================================
# include <contract.hpp>
# include "testdll.h"

CONTRACT_FUNCTION
(
    int (give1) ()
    postcondition(auto result = return, result == 1)
)
{
    return 2; // obviously wrong
}

DLL_MODE void test_contracts()
{
    int i = give1();
}
====================================

EXE:
====================================
# include <contract.hpp>
# include "../testdll/testdll.h"

void PostconditionHandler( contract::from const& context )
{
    std::cerr << "ERROR!!!" << std::endl;
}

int main()
{
    contract::set_postcondition_broken(&PostconditionHandler);
    test_contracts();
}
====================================

I expect that the program would use the broken postcondition handler I
installed, but it still uses the default one. The cause is that Contract is
using some global object to store the installed handler, but when a program
is linked with a DLL both the program and the DLL store their own copy of
the global. The global is duplicated. THe one in the EXE registers my
callback, but the global in the DLL still keeps the default handler.

The only way to solve this issue is to -- at least in the cases when users'
programs link with DLLs -- ship Contract with a small DLL that stores the
unique copy of the globals. This is how Boost.Log handles this problem.
Quoting the documentation (
http://boost-log.sourceforge.net/libs/log/doc/html/log/installation.html):

*"If your application consists of more than one module (e.g. an exe and one
or several dll's) that use Boost.Log, the library must be built as a shared
object. If you have a single executable, you may build the library as a
static library."

*
Regards,
&rzej*
*


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk