oracle / odpi

ODPI-C: Oracle Database Programming Interface for Drivers and Applications
https://oracle.github.io/odpi/
Other
264 stars 75 forks source link

Getting segmentation fault in a multi threaded c application #145

Closed brajncst123 closed 3 years ago

brajncst123 commented 4 years ago

--> I am creating multiple threads for reading oracle tables in my C application using pthread. i created connection pool using dpiPool_create() and giving each thread connection by using dpiPool_acquireConnection() in a loop ( size 300 ) of thread creation.once the table read is done by any thread i am invoking dpiConn_release() in the thread function to release the session.

But when a thread creation/connection acquire reached up to 200+ i am getting segmentation fault.

sharing snip of DPI_DEBUG_LEVEL=4 ./application

ODPI [1646287] 2020-08-02 19:45:00.220: ODPI-C 4.0.1 ODPI [1646287] 2020-08-02 19:45:00.220: debugging messages initialized at level 4 ODPI [1646287] 2020-08-02 19:45:00.896: fn start dpiContext_createWithParams ODPI [1646287] 2020-08-02 19:45:00.911: fn end dpiContext_createWithParams -> 0 ODPI [1646287] 2020-08-02 19:45:00.911: fn start dpiContext_initCommonCreateParams(0x5579d6279890) ODPI [1646287] 2020-08-02 19:45:00.911: fn end dpiContext_initCommonCreateParams(0x5579d6279890) -> 0 ODPI [1646287] 2020-08-02 19:45:00.911: fn start dpiContext_initPoolCreateParams(0x5579d6279890) ODPI [1646287] 2020-08-02 19:45:00.911: fn end dpiContext_initPoolCreateParams(0x5579d6279890) -> 0 ODPI [1646287] 2020-08-02 19:45:00.911: fn start dpiPool_create(0x5579d6279890) ODPI [1646287] 2020-08-02 19:45:01.464: fn end dpiPool_create(0x5579d6279890) -> 0 Segmentation fault (core dumped)

-->

cjbj commented 4 years ago

We'll need a runnable testcase. Thanks!

brajncst123 commented 4 years ago

I can't share entire application as its confidential project work, but i am sharing the ODPI APIS what i am using in my application

/* Wrapper function for creating one time connection pool */
void oraclePoolCreation( dpiPool **pool, dpiContext **context, ConnectionSrc conninfoSrc, int *error_code )
{
    const char              *charSet_encoding = "AL32UTF8";
    const char              *charSet_nencoding = "AL16UTF16";
    dpiCommonCreateParams   commonParams;
    static  dpiErrorInfo    gErrorInfo;

    // create context
    if ( dpiContext_createWithParams( DPI_MAJOR_VERSION, DPI_MINOR_VERSION, NULL,
                 context, &gErrorInfo) < 0 )
    {
        *error_code = 1;
        printError( context );
    }

    if (dpiContext_initCommonCreateParams(*context, &commonParams) < 0)
    {
        *error_code = 1;
        printError( context );
    }

    commonParams.encoding    =  charSet_encoding;
    commonParams.nencoding   =  charSet_nencoding;
    commonParams.createMode  =  DPI_MODE_CREATE_THREADED;

    dpiPoolCreateParams  PoolParams;
    dpiContext_initPoolCreateParams(*gContext,&PoolParams);
    PoolParams.minSessions = 10;
    PoolParams.maxSessions =500;
    PoolParams.sessionIncrement = 10;
    PoolParams.getMode = DPI_MODE_POOL_GET_WAIT;

    // create session pool 
    if ( dpiPool_create(*context, conninfoSrc.user, strlen(conninfoSrc.user),
                conninfoSrc.password , strlen(conninfoSrc.password),  conninfoSrc.connectionString,
                strlen(conninfoSrc.connectionString),  &commonParams, &PoolParams, pool) < 0)
    {
        *error_code = 1;
        printError( context );
    }
}

/* Wrapper function for acquiring connection for each thread from the pool */
void oracleConnectionAcquire(dpiContext *context, dpiPool *Opool, dpiConn **conn, int *error_code)
{

    if( dpiPool_acquireConnection( Opool, NULL, 0,
                NULL, 0, NULL, conn) < 0 )
    {
        printf("Something was wrong inside oracleConnAcquire! ");
        printError( context );
         *error_code = 1;
    }
}

void thread_func(void *struct)
{ 
    /* Once oracle table read by thread is done release the connection and terminate the thread */
dpiConn_release(srtuct->Conn)
dpiConn_release(struct->Conn)
pthread_exit(0); 

}    

/* main function for crating multiple threads to query with Oracle DB */
int Main()
{
dpiContext *context;
    dpiConn             *Conn[500];
    dpiStmt             *stmt[500];
    dpiVar              *refCursorVar[500];
    pthread_t          tid[500];

   oraclePoolCraetion( &pool, &context, conninfo, &error_code );

  for(int i = 0;i < 500; i++)
   {
        oracleConnectionAcuire( Context, pool, &Conn[i], &error_code );
         prepareSelectStatement( Context, Conn[i], &stmt[i], refCursorVar[i],
                                table[i], &Columns, &error_code);
      struct[i].Conn[i];
     struct[i].stmt[i];

      pthread_create(&tid[i],NULL,(void *)thread_func,(void *)&struct[i])
   }

   for(int j=0;j<500;j++)
      pthread_join(tid[j],NULL);

 dpiContext_destroy(gContext);
}
brajncst123 commented 4 years ago

We'll need a runnable testcase. Thanks!

@cjbj I am not sure the reason of segmentation fault

anthony-tuininga commented 4 years ago

@brajncst123, you don't need to share the entire application. In fact we'd prefer you didn't! What we're looking for is a runnable test case that demonstrates the problem. We already have complex scenarios that use many hundreds of threads and aren't experiencing a segfault as you are -- so we need to know what makes your case different! Please build such a runnable test case. The simplest approach is often to take your application and start cutting out pieces and manufacturing the data needed to run it. Frequently this results in determining the source of the issue fairly quickly. We are not going to do this work for you! You can also share the stack trace showing the segfault. This can sometimes be helpful all by itself, too.

anthony-tuininga commented 4 years ago

I did notice in your thread_func that this line is duplicated:

dpiConn_release(srtuct->Conn)

What is the reason for that?

brajncst123 commented 4 years ago

@anthony-tuininga sorry, thats dpiConn_close()

anthony-tuininga commented 4 years ago

Ok! Well, let us know when you have a runnable test case that we can use to track down the source of the issue. And share the statck trace when you can as well. Thanks!

anthony-tuininga commented 3 years ago

Closing due to lack of activity. Feel free to re-open when you have a runnable test case!