Определение указателя случайным образом приводит к сбою программы - PullRequest
0 голосов
/ 03 июля 2019

Определение переменной в классе вызывает случайный сбой во время выполнения приложения.

Сбой не появляется в режиме отладки, это происходит только в сборке выпуска.

Это такжебывает в различной точке исполнения.Я время от времени выдаю журналы во время выполнения, и они время от времени будут различаться.

Рассматриваемый класс является средним в цепочке наследования:

class Base
{
public:
    virtual ~BaseClass() { }

    // Quite a few virtual methods declared here.
};

class Middle : public Base
{
public:
    virtual ~Middle() { }

protected:
    Middle(const std::string& name)
        : _name(name)
        , _db(Context::DbInstance())
    {
    }

    /**
     * Commenting out any of the following crashes or does not.
     */
    // CareTaker* _careTaker;   // 4 bytes, crashes.
    // void* dummy;             // 4 bytes, crashes.
    // int dummy;               // 4 bytes, crashes.
    // short dummy;             // 2 bytes, crashes.
    // class Dummy {};          // 1 bytes, does not crash.
    //                          // 0 bytes, member removed, does not crash.
    std::string _name;
    // Crash also happens/does not if a variable described above put here.
    Database& _db;
    // But not if it is here. Variable of any size is OK here.
};

class Derived : public Middle
{
public:
    Derived() : Middle("Foo") { }
    virtual ~Derived() { }

    // Some virtual methods from Base overriden here.
};

В двух словах, если переменная размера 2 или более предшествует определению Database& _db, произойдет сбой.Если это произойдет впоследствии, они не будут.

Как я собираюсь попытаться решить проблему с отказом, не имея доступа к отладчику в этом сценарии?

РЕДАКТИРОВАТЬ:

Класс используется в методе инициализатора, запускаемом после загрузки DLL.К сожалению, я не могу дать больше подробностей, чем это.

int DllInitializer()
{
    // Complex code.

    DbPlugger::instance().addPlug(new Derived());

    // Complex code.
}

Ответы [ 2 ]

1 голос
/ 03 июля 2019

Вы не предоставили mcve , так что это основано на некоторых предположениях, но я предполагаю, что в какой-то момент вы делаете копию неявно или явно.

Всетри участника, вызывающих столкновение, тривиально конструктивны.Так как вы не инициализируете их в конструкторе, они остаются с неопределенным значением (при условии нестатического хранения).

Когда вы копируете такой объект, значения членов читаются.Поведение чтения неопределенного значения (из этих типов) не определено.Когда поведение не определено, программа может произойти сбой.

0 голосов
/ 09 июля 2019

Проблема заключалась в том, что было два отдельных набора файлов Derived.h / Derived.cpp. Один из них устарел и остался навеки забытым.

Набор, над которым я работал, был включен в сам проект C ++, но исходный файл, который включал фактический заголовочный файл, использовал старый путь.

Это привело к расхождению между файлами h и cpp, что привело к повреждению кучи из-за различных сигнатур памяти заголовочного файла, включенного в проект, и заголовочного файла, фактически включенного одним из файлов cpp в проекте.

Довольно много отладок и головной боли, решаемых с помощью однострочного #include изменения пути.

...