Ошибка сегментации при использовании libsqora.so.19.1 несколькими потоками на Linux (CentOS 7) - PullRequest
0 голосов
/ 14 апреля 2020

Я разрабатываю приложение, которое использует API ODB C напрямую, используя драйвер Oracel DB. Все работало нормально, пока я работал однопоточным. Но когда я использую несколько потоков, то почти каждая функция SQL ... завершает процесс. Все, что я обнаружил, похоже, что я все делаю правильно, например, сначала я устанавливаю sh среду, а после этого все потоки просто используют эту среду для создания своего собственного соединения. Вызов SQLAllo c для получения дескриптора соединения все еще работает, но вызов SQLDriverConnectW приводит к ошибке сегментации.

Затем я создал очень простую тестовую программу и получил тот же результат (я перестал обрабатывать код возврата для коротко):

SQLHANDLE environmentHandle = SQL_NULL_HENV;

void testConnect() {
    SQLHANDLE connectionHandle = SQL_NULL_HDBC;

    SQLAllocHandle(SQL_HANDLE_DBC, environmentHandle, &connectionHandle);
    SQLSetConnectAttrW(connectionHandle, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_NTS);
    // ...
    SQLDriverConnectW(connectionHandle, NULL, szConnectionString, cbConnectionString, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
    // ...
}

void runMain() {
    SQLRETURN rc;

    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &environmentHandle);

    // switch to ODBC 3.0
    SQLSetEnvAttr(environmentHandle, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);

    // This works:
    // testConnect();

    // This works NOT!
    std::thread threadObj(testConnect);
    threadObj.join();

    // ...
}

int main() {
    try {
        runMain();
    }
    catch(...) {
        std::cout << "error\n";
    }
    return 0;
}

Если я запускаю эту программу, она вызывает сбой при вызове SQLSetConnectAttrW. Затем я понял, что он взломает sh уже тогда, когда я установлю sh среду, если runMain не вызывается в основном потоке. Если я изменю основную функцию на эту, тогда я получу ошибку, уже вызвав SQLSetEnvAttr.

int main() {
    try {
        std::thread threadObj(runMain);
        threadObj.join();
    }
    catch(...) {
        std::cout << "error\n";
    }
    return 0;
}

Я не могу себе представить, есть ли ошибка в библиотеке драйверов oracle db. Но я также не могу найти ошибку в моем коде. Кто-нибудь сталкивался с этой проблемой раньше? Может кто-нибудь помочь?

Спасибо!

С уважением, Свен

...