c ++ linux двойное уничтожение статической переменной. перекрываются символы компоновки

Среда: linux x64, компилятор gcc 4.x

Проект имеет следующую структуру:

static library "slib"
-- inside this library, there is static object "sobj"

dynamic library "dlib"
-- links statically "slib"

executable "exe":
-- links "slib" statically
-- links "dlib" dynamically

в конце программы" sobj "уничтожается дважды. Такое поведение ожидается, НО он разрушается дважды по одному и тому же адресу памяти, т.е. одно и то же "this" в деструкторе - в результате возникает проблема двойного уничтожения. Я думаю, это связано с некоторым перекрытием символов.

Какое решение этого конфликта? Может быть, какой-нибудь вариант связывания?


Вот тестовый пример:


main_exe.cpp

#include <cstdlib>

#include "static_lib.h"
#include "dynamic_lib.h"

int main(int argc, char *argv[])
{
    stat_useStatic();
    din_useStatic();
    return EXIT_SUCCESS;
}

static_lib.h

#ifndef STATIC_LIB_H
#define STATIC_LIB_H

#include <cstdio>

void stat_useStatic();
struct CTest
{
    CTest(): status(isAlive)
    {
        printf("CTest() this=%d\n",this);
    }
    ~CTest()
    {
        printf("~CTest() this=%d, %s\n",this,status==isAlive?"is Alive":"is Dead");
        status=isDead;
    }
    void use()
    {
        printf("use\n");
    }
    static const int isAlive=12385423;
    static const int isDead=6543421;
    int status;

    static CTest test;
};

#endif

static_lib.cpp

#include "static_lib.h"

CTest CTest::test;

void stat_useStatic()
{
    CTest::test.use();
}

dynamic_lib.h

#ifndef DYNAMIC_LIB_H
#define DYNAMIC_LIB_H

#include "static_lib.h"

#ifdef WIN32
#define DLLExport __declspec(dllexport)
#else
#define DLLExport 
#endif
DLLExport void din_useStatic();


#endif

dynamic_lib.cpp

#include "dynamic_lib.h"

DLLExport void din_useStatic()
{
    CTest::test.use();
}

CMakeLists.txt

project( StaticProblem )
cmake_minimum_required(VERSION 2.6)
if(WIN32)
else(WIN32)
    ADD_DEFINITIONS(-fPIC)
endif(WIN32)

ADD_LIBRARY( static_lib  STATIC static_lib.cpp static_lib.h)

ADD_LIBRARY( dynamic_lib SHARED dynamic_lib.cpp dynamic_lib.h)
TARGET_LINK_LIBRARIES( dynamic_lib static_lib )

ADD_EXECUTABLE( main_exe main_exe.cpp )
TARGET_LINK_LIBRARIES( main_exe static_lib dynamic_lib )

Этот пример работает нормально в Windows, но в Linux - проблема. Поскольку это нормально работает в Windows, решение должно быть похоже на изменение некоторой опции связывания или что-то в этом роде, но не изменение структуры проекта или не использование статических переменных.

Вывод:

Windows

CTest() this=268472624
CTest() this=4231488
use
use
~CTest() this=4231488, is Alive
~CTest() this=268472624, is Alive

Linux

CTest() this=6296204
CTest() this=6296204
use
use
~CTest() this=6296204, is Alive
~CTest() this=6296204, is Dead
17
задан Matthieu M. 13 May 2017 в 15:12
поделиться