4 Replies Latest reply: Apr 9, 2012 6:54 AM by user633362 RSS

    OCIEnvCreate() segfaults in a threaded application on AIX.


      We are in the process of migrating our applications to Oracle 11g. The applications have worked flawlessly with Oracle 9i for several years. With Oracle 11g ( on AIX ( some applications segfault in OCIEnvCreate(). I've manage to reduce the code to the following minimal testcase:
      #include <stdio.h>
      #include <pthread.h>
      #include <oci.h>
      void* thread_main(void*)
          OCIEnv* pEnv;
          OCIEnvCreate(&pEnv, OCI_THREADED, 0, 0, 0, 0, 0, 0);
          return 0;
      int main(void)
          pthread_attr_t attr;
          pthread_t thread;
          pthread_create(&thread, &attr, thread_main, 0);
          pthread_join(thread, 0);
          return 0;
      Changing the mode from OCI_THREADED to OCI_DEFAULT does not make any difference.

      dbx shows the following stack trace:
      $ dbx ./oci_thread_test core
      Type 'help' for help.
      [using memory image in core]
      reading symbolic information ...
      Segmentation fault in skgfsio at 0x900000008345c98 ($t2)
      0x900000008345c98 (skgfsio+0x78) 7c21616a       stdux   r1,r1,r12
      (dbx) where
      skgfsio(??, ??, ??) at 0x900000008345c98
      sdbgrfbibf_io_block_file(??, ??, ??, ??, ??, ??, ??) at 0x90000000833f8a0
      dbgrfrbf_read_block_file(??, ??, ??, ??, ??, ??) at 0x9000000082bc578
      dbgrmflrp_read_page(0x11003b4e8, 0x7, 0x0, 0x400000004, 0x1100bca00, 0x400000004000) at 0x90000000845f034
      dbgrmblgmp_get_many_pages(??, ??, ??, ??) at 0x90000000842b9a8
      dbgrmmdrrmd_read_relation_meta_data(??, ??, ??, ??, ??) at 0x900000008467c90
      dbgrmmdora_open_record_access_full(0x11008df50, 0x900000009bf54f0, 0x11003b4e8, 0x100000001, 0x11003b960, 0x11003b820, 0x0, 0x1000000000001) at 0x90000000847226c
      dbgriporc_openrel_wcreate(??, ??) at 0x9000000083e9eac
      dbgrip_open_relation_access(??, ??) at 0x9000000083ea198
      dbgrip_start_iterator(??, ??, ??, ??, ??, ??, ??, ??) at 0x9000000083eecc0
      dbgrip_relation_iterator(??, ??, ??, ??, ??, ??, ??) at 0x9000000083f00c4
      dbgruprac_read_adrctl(??, ??) at 0x9000000083dfec0
      dbgrsc_set_createid(??, ??) at 0x90000000823d90c
      dbgrcas_create_adr_schema(??, ??) at 0x90000000823eff8
      dbgraid_adr_init_disk(??, ??) at 0x90000000823ece0
      dbgrcaod_check_adr_ondisk(??) at 0x9000000082406f0
      dbgrlWriteAlertDetail_int(??, ??) at 0x90000000832ec04
      dbgrlWriteAlertDetail(??, ??) at 0x90000000832d338
      dbgrlWriteAlertText(??, ??, ??, ??) at 0x90000000832d018
      nlddwrtlog(??, ??, ??) at 0x900000008149ae8
      nldsadrvfp(??, ??, ??, ??) at 0x900000008974b2c
      nldsfprintf(0x30393132322f6469, 0x61672f636c69656e, 0x900000009c79668, 0x110042b80, 0x110043071, 0x900000009c7963c, 0x100d60f5, 0x0) at 0x900000008973230
      kpeDbgInitError(??, ??, ??) at 0x90000000872675c
      kpeDbgGetNPDGlobal(??, ??, ??) at 0x900000008726670
      kpeDbgTLSInit(??, ??) at 0x900000008726500
      kpummTLSGET1(??, ??) at 0x90000000872b1f0
      kpeDbgProcessInit(??, ??) at 0x9000000087256e0
      kpummpin(??, ??, ??, ??, ??, ??, ??, ??) at 0x9000000087288f4
      kpuenvcr(0x0, 0x2100000021, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) at 0x900000008777448
      OCIEnvCreate(??, ??, ??, ??, ??, ??, ??, ??) at 0x900000008ed89fc
      thread_main(void*)( = (nil)), line 10 in "oci_thread_test.cpp"
      Any suggestions on how this could be solved/worked around?

        • 1. Re: OCIEnvCreate() segfaults in a threaded application on AIX.
          We had a similar-seeming problem on AIX a while back. What worked then (though I don't know why) was calling OCIEnvCreate earlier... I think it's probably best to call this function just once in your main thread, instead of once within each sub-thread...
          • 2. Re: OCIEnvCreate() segfaults in a threaded application on AIX.
            Yep, I have already found a similar workaround (connecting to the database on the application startup, and hence calling OCIEnvCreate() from within the main thread first, so subsequent calls to OCIEnvCreate succeed no matter from what thread it is being called).

            Anyway, I have escalated the problem, and received a report that the bug was submitted to the Metalink, so will wait to see what Oracle says.
            • 3. Re: OCIEnvCreate() segfaults in a threaded application on AIX.
              OCIEnv* pEnv;

              using uninitialized pointer variables is a sure way of getting segment violations. unfortunately, the manuals on OCIEnvCreate suggest that it is not needed to initialize this value, but when i check a few multithreaded OCI programs i've written, i always set it to zero before giving it to OCIEnvCreate. It could very well be that in your old environment, this variable was 'automagically' zeroed without you being aware of it. It could very well be that the new compiler/toolchain doesn't do this automatically, and it doesn't have to. The programmer should initialize variables.

              I vaguely remember that i've hit this problem long ago, and just set the variable to zero instead of following Oracle example. Besides, there are other OCI calls that expect the memory to be preallocated when you pass it a not-null pointer. I assume that could be the case here - that Oracle expects the memory you are pointing to is actually there, resulting in the segment violation.

              Besides, writing

              OCIEnv* pEnv = 0;

              is better coding anyway.
              • 4. Re: OCIEnvCreate() segfaults in a threaded application on AIX.
                I met the same problem, but i had only one thread and OCIEnvCreate() was called once.

                How to fix this?