Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Segmentation fault when using static SQL
Qt 6.11 is out! See what's new in the release blog

Segmentation fault when using static SQL

Scheduled Pinned Locked Moved General and Desktop
5 Posts 3 Posters 4.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    axhir
    wrote on last edited by
    #1

    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;
    }
    @

    1 Reply Last reply
    0
    • N Offline
      N Offline
      nickless
      wrote on last edited by
      #2

      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.

      1 Reply Last reply
      0
      • A Offline
        A Offline
        axhir
        wrote on last edited by
        #3

        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,...
        

        :
        @

        1 Reply Last reply
        0
        • N Offline
          N Offline
          nickless
          wrote on last edited by
          #4

          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
          1 Reply Last reply
          0
          • U Offline
            U Offline
            ulesQt
            wrote on last edited by
            #5

            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.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved