FreeOCI call does not unload Oracle dll's

Discussion of open issues, suggestions and bugs regarding ODAC (Oracle Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
dados
Posts: 82
Joined: Thu 18 Aug 2005 14:06

FreeOCI call does not unload Oracle dll's

Post by dados » Tue 06 Dec 2011 11:05

Hi,

I'm using:
Win7 32bit
Delphi XE2 Update 2
ODAC PRO 8.1.3 for Delphi XE2

Steps to reproduce:
1. Delphi -> New VCL Form Application
2. put "oracall" in uses clause;
3. in FormCreate put these two line:
InitOCI;
FreeOCI;
4. Run program...

If you use Process Explorer from Sysinternal and monitor the process while you step through the two lines you can see that oci.dll and many other oracle dll's are loaded with the InitOCI call but only oci.dll is unloaded when FreeOCI is called, leaving bunch of Oracle dll loaded.

I'm trying to change the oracle HOME property and load the correct dll's and I want to be able to do this without having to close my program and start another. Because once I've called InitOCI and connected to my session I'm stuck with the selected Oracle Home.

I've seen that SQL Navigator from Quest does load/unload Oracle DLL's perfectly :)

Reg,
Arni Thor

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Post by AlexP » Wed 07 Dec 2011 11:15

Hello,

Thank you for the information.
We know about this problem, we are working on it.

dados
Posts: 82
Joined: Thu 18 Aug 2005 14:06

Post by dados » Thu 08 Dec 2011 00:03

Excellent

Thanks.

dados
Posts: 82
Joined: Thu 18 Aug 2005 14:06

Post by dados » Wed 29 Feb 2012 11:52

Hi,

Do you have any development news on this issue?

Reg,
Arni Thor

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Post by AlexP » Fri 02 Mar 2012 14:16

Hello,

We continue to study this problem. However, more probably, the problem is due to Oci.dll that doesn't free the libraries that it uses.
We have checked this behaviour not using our components. We just used Api methods for downloading and uploading libraries, the library's methods (Delphi), and also the Oci.h and Oci.Lib files (C++) distributed together with Oracle. In both cases, the additionally downloaded libraries remain not uploaded till the end of the application work. There is a code of these projects.

Code: Select all

program ConsolApplication;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

type
_OCIEnvCreate = function (var envhpp: pointer; mode: cardinal; const ctxp: pointer;
const malocfp: pointer; const ralocfp: pointer;
const mfreefp: pointer; xtramemsz: Cardinal; usrmempp: pointer): integer; cdecl;

_OCIHandleFree = function (hndlp: pointer; htype: Cardinal): integer;  cdecl;

_OCITerminate  = function (mode: Cardinal): integer; cdecl;
var
  hOraLib: HMODULE;
  hOCIEnv: pointer;
  hOCIError: pointer;
  OCIEnvCreate: _OCIEnvCreate;
  OCIHandleFree: _OCIHandleFree;
  OCITerminate: _OCITerminate;
begin
    hOraLib := LoadLibraryEx('Path to oci.dll',0, LOAD_WITH_ALTERED_SEARCH_PATH);
    OCIEnvCreate := GetProcAddress(hOraLib, 'OCIEnvCreate');
    OCIEnvCreate(hOCIEnv,7,nil, nil, nil, nil, 0, nil);
    OCIHandleFree := GetProcAddress(hOraLib, 'OCIHandleFree');
    OCIHandleFree(hOCIEnv,1);
    OCITerminate := GetProcAddress(hOraLib, 'OCITerminate');
    OCITerminate(0);
    FreeLibrary(hOraLib);
    ReadLn;
end.

Code: Select all

#include 
#include 
#include 

using namespace std;

void checkerr(OCIError* err, sword status) {
  text errbuf[512];
  ub4 buflen;
  sb4 errcode;

  switch (status) {
  case OCI_SUCCESS:
    break;
  case OCI_SUCCESS_WITH_INFO:
    printf("Error - OCI_SUCCESS_WITH_INFO\n");
    break;
  case OCI_NEED_DATA:
    printf("Error - OCI_NEED_DATA\n");
    break;
  case OCI_NO_DATA:
    printf("Error - OCI_NO_DATA\n");
    break;
  case OCI_ERROR:
    OCIErrorGet ( err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), (ub4) OCI_HTYPE_ERROR);
    printf("Error - %s\n", errbuf);
    break;
  case OCI_INVALID_HANDLE:
    printf("Error - OCI_INVALID_HANDLE\n");
    break;
  case OCI_STILL_EXECUTING:
    printf("Error - OCI_STILL_EXECUTE\n");
    break;
  case OCI_CONTINUE:
    printf("Error - OCI_CONTINUE\n");
    break;
  default:
    break;
  }
}


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

  OCIEnv*       env;

  OCIError*     err;

  OCIServer*    srv;
  OCISvcCtx*    svc;
  OCISession*   ses;
  OCISvcCtx*     svchp;

  sword         r;

  text         bufp;

  env           =       0;
  err           =       0;
  srv           =       0;
  svc           =       0;
  ses           =       0;

  r=OCIEnvCreate( &env, OCI_DEFAULT, 0, 0, 0, 0, 0, 0); 

  if (r != OCI_SUCCESS)  {
    printf("OCIEnvCreate failed!\n");
    goto clean_up;
  }

  OCIHandleAlloc(env, (dvoid**)&err, OCI_HTYPE_ERROR,   0, 0);
  OCIHandleAlloc(env, (dvoid**)&srv, OCI_HTYPE_SERVER,  0, 0);
  OCIHandleAlloc(env, (dvoid**)&svc, OCI_HTYPE_SVCCTX,  0, 0);
  OCIHandleAlloc(env, (dvoid**)&ses, OCI_HTYPE_SESSION, 0, 0);

  r=OCIServerAttach(srv, err,  (text* )"orcl1020", strlen("orcl1020"), (ub4) OCI_DEFAULT);
  if (r != OCI_SUCCESS) {
    checkerr(err, r);
    goto clean_up;
  }

  OCIAttrSet(svc, OCI_HTYPE_SVCCTX, srv, 0, OCI_ATTR_SERVER,  err);

  OCIAttrSet(ses, OCI_HTYPE_SESSION, (text* )"scott", strlen("scott"), OCI_ATTR_USERNAME, err); 
  OCIAttrSet(ses, OCI_HTYPE_SESSION, (text* )"tiger", strlen("tiger"), OCI_ATTR_PASSWORD, err); 

  r=OCISessionBegin (svc, err, ses, OCI_CRED_RDBMS, OCI_DEFAULT);
  checkerr(err, r);
  
clean_up:
  if (env) OCIHandleFree(env, OCI_HTYPE_ENV   );
  if (err) OCIHandleFree(err, OCI_HTYPE_ERROR );
  if (srv) OCIHandleFree(srv, OCI_HTYPE_SERVER);
  if (svc) OCIHandleFree(svc, OCI_HTYPE_SVCCTX);
  OCITerminate(OCI_DEFAULT);

    system("PAUSE");
    return EXIT_SUCCESS;
}
Try ask this question at the Oracle developers forum

dados
Posts: 82
Joined: Thu 18 Aug 2005 14:06

Post by dados » Fri 02 Mar 2012 15:21

Ok, thanks.

But if it is an Oracle issue then it's kinda weird thank Quest's SQL Navigator is able to do it.

Reg,
Arni Thor

AlexP
Devart Team
Posts: 5530
Joined: Tue 10 Aug 2010 11:35

Post by AlexP » Sat 03 Mar 2012 14:22

Hello,

We have checked the Quest's SQL Navigator 6.5.0.2090 behaviour, and the downloaded Oracle libraries don't unload when changing the client version. I have sent you a Process Explorer screenshot showing that libraries from all the clients remain in memory.

Post Reply