Menu

OCI_Fetchnext crash on linux

2011-01-14
2012-09-26
  • Nobody/Anonymous

    Hi Vincent,

    My code work on window, but on linux "ubuntu 6.06 LTS".
    It crash with below debug log .

    Please Advice,
    Alvin

    Note: OCILIB 3.81 with WIDE char option

    My source:
    st = OCI_StatementCreate(Connection->cn);
    OCI_SetFetchSize(st,500);
    OCI_SetLongMaxSize(st, 1000000); // Long raw
    if ( params.empty()) {
    if (!OCI_Prepare(st,m_sql)) {
    Connection->Lock.Post();
    ThrowException();
    }
    } else {
    if (!OCI_Prepare(st,OtlSqlToOciSQL(m_sql))) {
    Connection->Lock.Post();
    ThrowException();
    }
    bindParms(m_sql,params);

    }
    if (!OCI_Execute(st)) {
    Connection->Lock.Post();
    ThrowException();
    }

    m_stType = OCI_GetStatementType(st);
    if ( m_stType == OCI_CST_SELECT {

    rs = OCI_GetResultset(st);
    if (!rs) {
    Connection->Lock.Post();
    ThrowException();
    }
    m_first_fetch = true;
    m_first_fetch_eof = OCI_FetchNext(rs) == 0 ? true:false; // <========= crash
    at here ..
    }

    Program received signal SIGSEGV, Segmentation fault.
    0xb77418a0 in free () from /lib/tls/i686/cmov/libc.so.6
    (gdb) info thread
    * 1 Thread -1235036480 (LWP 3916) 0xb77418a0 in free () from /lib/tls/i686/cmov/libc.so.6
    (gdb) backtrace

    0 0xb77418a0 in free () from /lib/tls/i686/cmov/libc.so.6

    1 0xb7743411 in malloc () from /lib/tls/i686/cmov/libc.so.6

    2 0xb7949565 in OCI_MemAlloc (ptr_type=0, block_size=36, block_count=0,

    zero_fill=1) at memory.c:56

    3 0xb7942a8f in OCI_LongInit (stmt=0x0, plg=0x92bb2c0, def=0x91c3400, type=0)

    at long.c:59

    4 0xb7937cee in OCI_FetchPieces (rs=0x8fcd2a8) at resultset.c:238

    5 0xb793803f in OCI_FetchData (rs=0x8fcd2a8, mode=2, offset=0,

    err=0xbfba4838) at resultset.c:471

    6 0xb7938a5d in OCI_FetchNext (rs=0x8fcd2a8) at resultset.c:1077

    7 0x080937c8 in caQuery::Create (this=0xbfba499c, params=@0xbfba4a10) at

    /home/tehbc/devl/oneora/src/caconnection.cpp:487

    8 0x08093d7a in caQuery (this=0xbfba499c, conn=@0x8ff1080, sql=0x8a09308

    "SELECT /+RULE/ v1.owner,v1.table_name,v1.column_id,v1.column_name,v1.data_t
    ype,v1.data_precision,v1.data_scale,v1.data_length,v1.nullable,v1.data_default
    ,v2.comments, v1.character_set_name,v1.char_l"..., params=@0xbfba4a10) at
    /home/tehbc/devl/oneora/src/caconnection.cpp:416

     
  • Nobody/Anonymous

    Hi Vincent,

    After test for few case, I found that the wchar_t* pointer for OCI_BindString
    is main cause for crash on linux.
    The below code work on window, by crash with invalid pointer for linux. ( some
    time after a few time run the same code)

    *** glic detected ** malloc(): memory corruption: 0x08f52928**

    Please Help.
    Alvin.

    void test_bind_bug(void)
    {
    
        OCI_Statement *st1  = OCI_StatementCreate(Connection()->cn);
        OCI_Resultset  *rs1;
        //OCI_SetFetchSize(st1,500);
        //OCI_SetLongMaxSize(st1, 1000000);  // Long raw    
    /* execute query in three steps */
        bool result = OCI_Prepare(st1,MT("select owner,index_name from sys.all_indexes ")
                  MT("where table_owner = :owner AND table_name = :name"));;
            wxString owner = wxT("HR");
            wxString name = wxT("DEPARTMENTS");
            wchar_t* wowner = new wchar_t[31]; // = (wchar_t*)owner.c_str();
            wchar_t* wname =  new wchar_t[31];  //(wchar_t*)name.c_str();
            wcscpy(wowner,owner.c_str());
            wcscpy(wname,name.c_str());
            result = OCI_BindString(st1,MT(":owner"),wowner,31);
            OCI_BindString(st1,MT(":name"),wname,31);
            int ret1 = OCI_Execute(st1);
            if (ret1 != 1) {
                wxLogDebug(wxT("Error Execute"));
            }
            rs1 = OCI_GetResultset(st1);
            int ret = OCI_FetchNext(rs1);
            while (ret ==1 )
            {
            ret = OCI_FetchNext(rs1);
            }
    //      delete [] wowner;     --> can delete the pointer on window, crash on linux if uncomment it
    //      delete [] wname;
    //  OCI_StatementFree(st1);
    
    }
    
     
  • Vincent Rogier

    Vincent Rogier - 2011-01-16

    Hi,

    It's normal. A bind pointer must stay valid until the statement is re prepared
    or freed.

    vincent

     
  • Vincent Rogier

    Vincent Rogier - 2011-01-16

    because on linux, the binded pointer is accessed in OCI_CHARSET_WIDE after
    execution to perform conversion if needed between internal oracle Unicode
    encoding and wchar_t

     
  • Nobody/Anonymous

    Hi Vincent,

    From the above code,
    How to modify it to prevent crash on *** glic detected ** malloc(): memory
    corruption: 0x08f52928** ?
    I try for so many time but still can't find the way . please help

    Regards
    Teh

     
  • Nobody/Anonymous

    Hi Vincent,

    Should I report this as bug ?
    Or
    The version of gcc i use is too old ?

    gcc (GCC) 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
    Copyright (C) 2006 Free Software Foundation, Inc.

    Regards
    Alvin Teh

     
  • Vincent Rogier

    Vincent Rogier - 2011-01-19

    I'll run your piece of code on my linux box and try to investigate any issues
    before the end of the week.

     
  • Nobody/Anonymous

    Hi vincent,

    Thank for investigate.

    That is addition info discovered.
    If move the OCI_Statement *st1 = OCI_StatementCreate(Connection()->cn);
    for procedure. ( Create one time and reuse it ), The program will not crash
    for above code.

    But when run whole my application. it also crash randomly .

    After i change all SQL to not using String Binding (OCI_BindString) , It work
    without any problem.

    For my existing program, the part of program use PL/SQL code. For PL/SQL code,
    i didn't have an idea to change
    it without use OCI_BindString.

    Hope u can reproduce it and solve my trouble :(
    Thank
    Alvin

     
  • Nobody/Anonymous

    Hi Vencent,

    Any new about this issue ? Do you able to get this error ?

    Recently, Test on Mac Os, The source code "test_bind_bug" work correctly.
    But it also crash randomly by running my application.
    After took out OCI_BindString, the program work without problem.

    Regards
    Alvin

     
  • Nobody/Anonymous

    Hi Vincent,

    After try on error for few days, Now i am able to call PL/SQL code and sql
    binding from string for linux and mac.
    For output bind :
    wchar_t f2;
    f2 = '\0'; // add this.
    CHECK_ERR(OCI_BindString(m_conn->st,MT(":f2"),(wchar_t)f2,201));
    For input bind:
    CHECK_ERR(OCI_BindString(m_conn->st,MT(":name"),(wchar_t
    )name.c_str(),0)); //
    Change the len to zero.

    For sql, change the len to 0.

    Regards
    Alvin

     
  • Vincent Rogier

    Vincent Rogier - 2011-02-13

    string binds must always initialized a.nd valid before being passed to Oracle.

    But the len parameter mustn't set to zero. It's not imposed by OCI nor OCILIB.

     
  • Nobody/Anonymous

    Hi Vincent,

    "Len parameter mustn't set to zero"

    That is a bit strange on linux/mac , if i put in a len > 0 same as Ms Window.
    My application on linux/mac will crash.

    I use wxWidget, with below syntax,

    wxString value = wxT("TEST");
    OCI_BindString(st,name,(wchar_t*)value.c_str(), 31);

    Do you have idea, what is going on ?

    Regards
    Alvin