Page 1 of 1

Problem with unload sqlncli.dll

Posted: Sat 01 Aug 2009 16:59
by Saupg
Hello.

I want to unload unused sqlncli.dll.

Code like this:

Code: Select all

procedure TForm1.Button1Click(Sender: TObject);
begin
  MSConnection1.Open;
  MSConnection1.Close;

  CoFreeUnusedLibrariesEx(200, 0);
  Sleep(300);
  CoFreeUnusedLibrariesEx(200, 0);
end;
I know that sqlncli.dll has global reference count. It is checked in DllCanUnloadNow function. I know address of this global variable and can watch it's value in "Watch list".
I have version of sqlncli.dll = 2005.90.4035.0. Address of global var is $33999480. You can see it in first instuction of DllCanUnloadNow in CPU window like this:

Code: Select all

sqlncli.DllCanUnloadNow:
338C10F2 833D8094993300   cmp dword ptr [$33999480],$00
....
After call MSConnection1.Open RefCount = 4. But after call MSConnection1.Close = 1.

I found that ref count increment on call Uninitialize method of IDBInitialize in this code:

Code: Select all

procedure TOLEDBConnection.Disconnect;
begin
  if FConnected then begin
    if FNativeConnection then begin
      if FIDBInitialize  nil then
        FIDBInitialize.Uninitialize;// check not need
       
      ReleaseInterfaces;
    end;

    FConnected := False;
    FreeAndNil(FColumnsMetaInfo);
    FreeAndNil(FColumnsRowsetFieldDescs);
  end;
end;
Need urgent help. My developer license number is CRSDA-02437.
Thanks.

Posted: Mon 03 Aug 2009 12:07
by Dimon
Thank you for information. We have reproduced this problem and fixed it. This fix will be included in the next SDAC build.

Posted: Thu 01 Oct 2009 16:40
by Saupg
Hello again.

Last fix doesn't help.
May be it's bug in IDBInitialize.Uninitialize?

Posted: Fri 02 Oct 2009 10:21
by Dimon
I can not reproduce the problem.
In the last build the reference count to sqlncli.dll is cleared after all interfaces are disposed. In code it is done after executing the following line:
FIDBCreateSession := nil;

Posted: Fri 02 Oct 2009 13:44
by Saupg
Yes, now it doesn't reproduce in my example code.
But in my COM+ server i see the same problem.

I don't know why but i see such situation:

Code: Select all

  // RefCount = 4
  FISessionProperties := nil;
  if FIDBInitialize  nil then
    FIDBInitialize.Uninitialize;// check not need
  // RefCount = 5
  FIDBInitialize := nil;
  FIDBProperties := nil;
  FIDBCreateSession := nil;
  // RefCount = 5
  TOLEDBTransaction(GetInternalTransaction).ReleaseInterfaces;
  // RefCount = 1
But if i move last row:

Code: Select all

  // RefCount = 4
  TOLEDBTransaction(GetInternalTransaction).ReleaseInterfaces;
  // RefCount = 3

  FISessionProperties := nil;
  if FIDBInitialize  nil then
    FIDBInitialize.Uninitialize;// check not need
  // RefCount = 1
  FIDBInitialize := nil;
  FIDBProperties := nil;
  FIDBCreateSession := nil;
  // RefCount = 0
Any ideas?

Posted: Fri 02 Oct 2009 13:51
by Saupg
New example:

Code: Select all

procedure TForm1.Button1Click(Sender: TObject);
begin
  MSConnection1.Open;
  MSConnection1.StartTransaction;
  MSConnection1.Commit;
  MSConnection1.Close;

  CoFreeUnusedLibrariesEx(200, 0);
  Sleep(300);
  CoFreeUnusedLibrariesEx(200, 0);
end;

Posted: Mon 05 Oct 2009 08:35
by Dimon
Thank you for information. We have reproduced this problem and fixed it. This fix will be included in the next SDAC build.

Posted: Thu 12 Nov 2009 18:19
by Saupg
Don't fix again. :twisted:
v4.8.52, Delphi 2010.

Posted: Fri 13 Nov 2009 11:07
by Dimon
We are sorry for the delay. This fix will be included in the next SDAC build.