Почему происходит сбой программы на C ++, когда код связан с exe, но работает нормально, когда код компилируется в exe? - PullRequest
2 голосов
/ 05 июня 2019

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

Мой подход (проиллюстрирован псевдо CMake):

  • настроить среду разработки, используя набор инструментов для конкретной платформы, чтобы убедиться в правильности выбранной платформы
  • вычленяет всю основную бизнес-логику в объект приложения и создает из нее библиотеку (одна библиотека для каждой платформы из одного и того же исходного кода):

    add_library(appLib STATIC app.cpp)
    target_link_libraries(appLib utilLib networkLib dbLib ${boostLibs})
  • имеет один main_a.cpp и другой main_b.cpp, которые выполняют специфичную для платформы инициализацию для платформ a и b соответственно и позволяют основной функции в них создавать экземпляр объекта приложения.

    int main()
    {
        auto result = initAndDoPlatformStuff();
        App app(result);
        app.run();
    }
  • поручить компилятору и компоновщику собрать исполняемый файл:

    if (Platform_A)
    add_executable(appExe main_a.cpp)
    else()
    add_executable(appExe main_b.cpp)
    endif()
    target_link_libraries(appExe appLib)

В принципе, это совершенно правильный подход, я думаю. Но на самом деле это не работает. В течение второй программы происходит сбой, и сбои различаются почти каждый раз; проверка дампов ядра указывает на то, что когда-то происходит сбой в стандартной библиотеке, иногда в boost-библиотеке, а также в моем коде, но я полагаю, что это чепуха. Программа, кажется, работает 1 из 10 раз, но в конечном итоге вылетает.

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

int main()
{
    auto result = initAndDoStuff();
    processForever(result); // Business logic
}
add_executable(appExe main.cpp)
target_link_libraries(appExe utilLib networkLib dbLib ${boostLibs})

тогда это работает!

Я озадачен и смущен. Я подозреваю, что это как-то связано с разметкой кода, поэтому я поиграл с разными вариантами PIC и PIE, но не добился успеха. Существуют ли инструменты, позволяющие получить исчерпывающий обзор макета двоичного кода? Я знаю о nm, od, objdump, но они низкоуровневые, и я не знаю, что искать ... Возможно, я все же на неправильном пути, может быть, проблема связана с чем-то совершенно другим. Кто-нибудь догадывается, что может вызвать такое поведение? Как еще я могу подойти к этой проблеме?

1 Ответ

0 голосов
/ 10 июня 2019

На самом деле, вина была моя.Конечно ... Я действительно пытался исправить все детали, когда я преобразовал код в библиотеку, но, очевидно, я был недостаточно осторожен и слеп, когда искал проблему.
Проблема, которую я наконец нашел, былачто я все еще оставил одну переменную в качестве локальной переменной после рефакторинга, который затем вышел из области видимости, вызвав обращение к освобожденной памяти, что привело к разного рода неопределенному поведению.

...