Segmentation fault when using static SQL



  • I'm going to convert a GUI program using IBM's DB2 with static SQL
    from IBM's VisualAge to Qt. Depending on whether I compile the static
    SQL program along with the test routine or not I receive a segmentation
    fault when calling sqlestar() (the DB2 routine to start the database
    manager). Does anybody know what's going wrong?

    ==== main.cpp ========================================================
    @
    #include <Q..>
    #include <sqlenv.h>
    #include <qistring.h>
    #include "testdb.hpp"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);

    int rc = sqlestar(); // <== point of error

    QIString txt("0");
    short key = 1 ,seq = 1;

    if ( rc != 0 && rc != -1026 )
    txt = QIString::number(rc);
    else
    {
    //new TestDB("TESTDB");
    //psDB->getText(key ,seq ,txt);
    }

    QFile file;
    if ( file.open(stdout ,QIODevice::WriteOnly | QIODevice::Text) )
    {
    QTextStream out(&file);
    out << "txt: " << txt.toAscii().data() << "\n";
    file.close();
    }
    return 0;
    }
    @

    QtCreator profiles...

    @
    no segmentation fault |segmentation fault
    ---------------------------------------+-----------------------------
    TARGET = testdbstr |TARGET = testdbnp
    SOURCES += main.cpp |SOURCES += main.cpp
    | testdb.cxx
    |
    QT += core |do.
    QT -= gui |do.
    CONFIG += console |do.
    CONFIG -= app_bundle |do.
    TEMPLATE = app |do.
    HEADERS += testdb.hpp |do.
    INCLUDEPATH += d:\sqllib\include \ |do.
    f:\qtExt\include |do.
    LIBS += -L"D:\SQLLIB\lib" \ |do.
    -ldb2api \ |do.
    -L"F:\QtExt\lib" \ |do.
    -lqistring |do.
    @

    === testdb.hpp ===

    @
    #include <sqlca.h>
    #include <QDate>
    #include <qistring.h>

    #define psDB TestDB::psCurrent

    class TestDB
    {
    public:
    TestDB (const QIString &dbname);
    ~TestDB();
    QIString& name()
    { return ivDBName; }
    long getText(short key ,short seq ,QIString &text);
    static TestDB *psCurrent;
    private:
    void throwExc(const QIString &errPos = "" );
    int chkSQL(struct sqlca *pSQLCA ,const QIString &errPos);
    QIString ivDBName;
    char dbDBName[9];
    short dbTextKey;
    short dbTextSeq;
    char dbTextText[81];
    #endif
    };
    @

    === testdb.cxx =========================================================

    @
    static char sqla_program_id[162] =
    {
    42,...
    };

    #include "sqladef.h"

    static struct sqla_runtime_info sqla_rtinfo =
    {{'S','Q','L','A','R','T','I','N'}, sizeof(wchar_t), 0, {' ',' ',' ',' '}};
    static const short sqlIsLiteral = SQL_IS_LITERAL;
    static const short sqlIsInputHvar = SQL_IS_INPUT_HVAR;

    #line 1
    #ifdef SQL_PRE_PROCESSING // do not define it!
    /* EXEC SQL BEGIN DECLARE SECTION; /
    #line 2 "..."
    //EXEC SQL INCLUDE '..\testdb.hv';
    char dbDBName[9];
    short dbTextKey;
    short dbTextSeq;
    char dbTextText[81];
    /
    EXEC SQL END DECLARE SECTION; */
    #line 10 "..."
    #endif

    #include <QByteArray>
    #include <QtCore>
    #include <sql.h>
    #include <sqlenv.h>
    #include <sqlda.h>
    #include <sqlca.h>

    #define CHKSQL(ACTION ,POS)
    if ( 0 != this->chkSQL(&sqlca ,POS) )
    { ACTION; }

    #define TESTDB_HV
    #include "testdb.hpp"
    /* EXEC SQL INCLUDE SQLCA; */
    #include "sqlca.h"
    struct sqlca sqlca;
    #line 30 "..."
    TestDB *TestDB::psCurrent = 0;

    TestDB::TestDB (const QIString &dbname)
    :ivDBName(dbname)
    {
    int rc = sqlestar();
    if ( SQL_RC_OK == rc )
    psDB = this;
    else if ( SQLE_RC_INVSTRT == rc ) // -1026 (already started)
    psDB = this;
    else
    this->throwExc("DB2START RC=" + QIString(rc));
    QByteArray tmp = dbname.toAscii();
    strncpy(&dbDBName[0] ,tmp ,sizeof(dbDBName));
    /* EXEC SQL CONNECT TO :dbDBName; */
    {
    #line 54 "..."
    sqlastrt(sqla_program_id, &sqla_rtinfo, &sqlca);
    sqlaaloc(2,1,1,0L);
    {
    struct sqla_setdata_list sql_setdlist[1];
    ...
    sqlasetdata(2,0,1,sql_setdlist,NULL,0L);
    }
    sqlacall((unsigned short)29,4,2,0,0L);
    sqlastop(0L);
    }
    CHKSQL(rc = -1 ,"Ctor CONNECT TO " + dbname);
    if ( -1 == rc )
    this->throwExc();
    psCurrent = this;
    }

    TestDB::~TestDB()
    {
    /* EXEC SQL CONNECT RESET; */
    {
    #line 71 "..."
    sqlastrt(sqla_program_id, &sqla_rtinfo, &sqlca);
    sqlacall((unsigned short)29,3,0,0,0L);
    sqlastop(0L);
    }
    CHKSQL(psCurrent = 0 ,"Dtor DISCONNECT");
    psCurrent = 0;
    }

    void TestDB::throwExc(const QIString &txt)
    {
    ...
    }

    int TestDB::chkSQL(struct sqlca *pSQLCA ,const QIString &errPos)
    {
    ...
    }

    long TestDB::getText(short key ,short seq ,QIString &text)
    {
    const QIString method = "getText";
    dbTextKey = key;
    dbTextSeq = seq;
    /*
    EXEC SQL DECLARE c32 CURSOR FOR SELECT text FROM np.npgttext
    WHERE key = :dbTextKey AND seq = :dbTextSeq;
    /
    #line 169 "..."
    long rc = 0;
    /
    EXEC SQL OPEN c32; /
    {
    #line 173 "..."
    sqlastrt(sqla_program_id, &sqla_rtinfo, &sqlca);
    sqlaaloc(2,2,2,0L);
    {
    struct sqla_setdata_list sql_setdlist[2];
    ...
    sqlasetdata(2,0,2,sql_setdlist,NULL,0L);
    }
    sqlacall((unsigned short)26,1,2,0,0L);
    sqlastop(0L);
    }
    CHKSQL(return -1 ,method + " OPEN");
    /
    EXEC SQL FETCH c32 INTO :dbTextText; /
    {
    #line 179 "..."
    sqlastrt(sqla_program_id, &sqla_rtinfo, &sqlca);
    sqlaaloc(3,1,3,0L);
    {
    struct sqla_setdata_list sql_setdlist[1];
    ...
    sqlasetdata(3,0,1,sql_setdlist,NULL,0L);
    }
    sqlacall((unsigned short)25,1,0,3,0L);
    sqlastop(0L);
    }
    switch ( SQLCODE )
    {
    case 0:
    text = QIString(dbTextText);
    break;
    case 100:
    text = "";
    break;
    default:
    CHKSQL(rc = -1 ,method + " FETCH");
    break;
    } // switch
    /
    EXEC SQL CLOSE c32; */
    {
    #line 199 "..."
    sqlastrt(sqla_program_id, &sqla_rtinfo, &sqlca);
    sqlacall((unsigned short)20,1,0,0,0L);
    sqlastop(0L);
    }
    CHKSQL(rc = -1 ,method + " CLOSE");
    return rc;
    }
    @



  • I just hit exactly the same problem: Calling sqlastrt in embedded SQL segfaults.
    Environment: WinXP 32bit, compiler is mingw32, DB2 is v7.2

    But: On the same platform, compiling and linking my code against the libs in BD2 v 9.1 works fine!

    So my current thinking is that mingw+DB2 v7 libs somehow don't match. Also, I don't think that it's a simple stipped/non-stripped issue (which apparently could be solved by reimp) because the DB2 libs appear to be stripped already.

    I'm going to try to build with MSVC 2008 Express next.



  • Meanwhile I converted the static SQL to CLI and I'm happy with QSqlDatabase and QSqlQuery. To make the connection to a local DB2 database easier, that is just specifying the database name, I changed the QDB2Driver code (qsql_db2.cpp):
    @bool QDB2Driver::open(const QString& db,....
    :
    QString connQStr;
    // connQStr = protocol + QLatin1String(";DSN=") + db + QLatin1String(";HOSTNAME=") + host
    // + QLatin1String(";PORT=") + QString::number(port) + QLatin1String(";UID=") + user
    // + QLatin1String(";PWD=") + password;
    connQStr = QLatin1String("UID=") + user
    + QLatin1String(";PWD=") + password;
    if ( host.length() == 0 )
    connQStr += QLatin1String(";DSN=") + db; // local DB name
    else
    connQStr += QLatin1String(";DATABASE=") + db // remote DB name
    + QLatin1String(";") + protocol
    + QLatin1String(";HOSTNAME=") + host
    + QLatin1String(";PORT=") + QString::number(port);

    SQLTCHAR connOut[SQL_MAX_OPTION_STRING_LENGTH];
    SQLSMALLINT cb;
    
    r = SQLDriverConnect(d->hDbc,...
    

    :
    @



  • For what it's worth, my code compiles and runs with MSVC 2008 and DB2 v7.

    Unfortunately I cannot switch to CLI, I'm using 3rd/4th-level dynamic SQL, and something like
    @EXEC SQL PREPARE stat1 FROM :stmt; @
    will get expanded to
    @sqlastrt(sqla_program_id, &sqla_rtinfo, &sqlca); @
    which in turn crashes.

    To summarize:

    • DB2 v9 + mingw works fine
    • DB2 v7 + mingw crashes
    • DB2 v7 + MSVC works


  • I have a similar problem, I believe its compiler issue, I get segmentation fault if I try to connect signals of member declared as static, but if they are non-static works fine.
    I'm in pain because a want to port a really BIG code to Linux.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.