Welcome, Guest
Guest Settings
Help

Thread: Access Violation when calling FreeLibrary


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 28 - Last Post: Jan 13, 2015 4:30 PM Last Post By: Craig Burke Threads: [ Previous | Next ]
Robert Liebeskind

Posts: 5
Registered: 9/4/11
Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 12, 2012 7:18 AM
I receive an Access Violation when calling FreeLibrary using the DLL Code below built on a WindowsXP Machine using Delphi 2007 and called by a Host app (code also shown below) that is built on a Windows 7 machine using Delphi XE2.

If I build the DLL using Win7 and XE2 I do not get an access violation.

Unfortunately, I must use Delphi 2007 to build my DLL. Does anyone have an idea as to why this code fails on FreeLibrary given this scenario?

The code below has been stripped down to its essence in order to simplify debugging this problem. It is not the full code that I must use but the issue can be reproduced using the example code below.

Thank you for your assistance.

DLL Code:

library MockXE2;

uses
System.SysUtils,
System.Classes;

{$R *.res}

function Mock:Integer; stdcall;
begin
result := 8;
end;

exports Mock;

begin
end.


Host app code:


unit Mock1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
TForm1 = class(TForm)
Load: TButton;
Call: TButton;
Unload: TButton;
Edit1: TEdit;
procedure LoadClick(Sender: TObject);
procedure CallClick(Sender: TObject);
procedure UnloadClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TGetDLLMock = function : Integer; stdcall;

var
Form1: TForm1;
dllHandle: Cardinal;
getDLLMock : TGetDLLMock;
result: Integer;

implementation

{$R *.dfm}

procedure TForm1.CallClick(Sender: TObject);
begin
if Assigned (getDLLMock) then
begin
result := getDLLMock;
Edit1.Text := IntToStr(result);
end;
end;

procedure TForm1.LoadClick(Sender: TObject);

begin
dllHandle := LoadLibrary('MockXE2.dll') ;
@getDLLMock := GetProcAddress(dllHandle, 'Mock') ;
end;

procedure TForm1.UnloadClick(Sender: TObject);
begin
FreeLibrary(dllHandle);
end;

end.
procedure TForm1.UnloadClick(Sender: TObject);
begin
FreeLibrary(dllHandle);
end;

end.

Robert Liebeskind

Posts: 5
Registered: 9/4/11
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 12, 2012 7:26 AM   in response to: Robert Liebeskind in response to: Robert Liebeskind
Here is the DFM file associated with the Host app:



object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 44
ClientWidth = 416
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Load: TButton
Left = 24
Top = 8
Width = 75
Height = 25
Caption = 'Load'
TabOrder = 0
OnClick = LoadClick
end
object Call: TButton
Left = 105
Top = 8
Width = 75
Height = 25
Caption = 'Call'
TabOrder = 1
OnClick = CallClick
end
object Unload: TButton
Left = 186
Top = 8
Width = 75
Height = 25
Caption = 'Unload'
TabOrder = 2
OnClick = UnloadClick
end
object Edit1: TEdit
Left = 280
Top = 8
Width = 121
Height = 21
TabOrder = 3
Text = 'I should say 8.'
end
end


Ken White

Posts: 1
Registered: 9/5/15
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 12, 2012 9:44 AM   in response to: Robert Liebeskind in response to: Robert Liebeskind
Robert Liebeskind wrote:
I receive an Access Violation when calling FreeLibrary using the DLL Code below built on a WindowsXP Machine using Delphi 2007 and called by a Host app (code also shown below) that is built on a Windows 7 machine using Delphi XE2.

First, you have two UnloadClick procedures defined in your test application, which makes it uncompileable.

Second, you've given no information on what access violation you receive. Specific error messages (including any memory address information) is really important when asking people to help you solve a problem.

Third, your code that calls FreeLibrary (whichever one is actually being used) should set dllHandle to 0 and getDLLMock to nil after calling FreeLibrary; FreeLibrary does not magically set the dllHandle and any loaded procedure pointers to nil, and so a test of Assigned after the library has unloaded will show that the values are still "assigned".
Robert Liebeskind

Posts: 5
Registered: 9/4/11
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 13, 2012 1:32 AM   in response to: Ken White in response to: Ken White
Ken White wrote:
Robert Liebeskind wrote:
I receive an Access Violation when calling FreeLibrary using the DLL Code below built on a WindowsXP Machine using Delphi 2007 and called by a Host app (code also shown below) that is built on a Windows 7 machine using Delphi XE2.

First, you have two UnloadClick procedures defined in your test application, which makes it uncompileable.

Second, you've given no information on what access violation you receive. Specific error messages (including any memory address information) is really important when asking people to help you solve a problem.

Third, your code that calls FreeLibrary (whichever one is actually being used) should set dllHandle to 0 and getDLLMock to nil after calling FreeLibrary; FreeLibrary does not magically set the dllHandle and any loaded procedure pointers to nil, and so a test of Assigned after the library has unloaded will show that the values are still "assigned".

Thank you for your reply Ken. I'm not sure how the two unload procedures got in the post.. must have been a paste error. I've reposted the code below without the duplicate method.

As far as the cleaning up of the variables... I only created this mock program to demonstrate the problem and am not at all concerned about setting things to 0 or nil after unloading. As I mentioned, the access violation occurs on the call to FreeLibrary, not after it. The access violation I receive is "Project Mock.exe raised exception class $C0000005 with message 'access violation at 0x00000000: read of address 0x00000000'.


unit Mock1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
TForm1 = class(TForm)
Load: TButton;
Call: TButton;
Unload: TButton;
Edit1: TEdit;
procedure LoadClick(Sender: TObject);
procedure CallClick(Sender: TObject);
procedure UnloadClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TGetDLLMock = function : Integer; stdcall;

var
Form1: TForm1;
dllHandle: Cardinal;
getDLLMock : TGetDLLMock;
result: Integer;

implementation

{$R *.dfm}

procedure TForm1.CallClick(Sender: TObject);
begin
if Assigned (getDLLMock) then
begin
result := getDLLMock;
Edit1.Text := IntToStr(result); //call the function
end;
end;

procedure TForm1.LoadClick(Sender: TObject);

begin
// load dll
dllHandle := LoadLibrary('MockXE2.dll') ;
@getDLLMock := GetProcAddress(dllHandle, 'Mock') ;
end;

procedure TForm1.UnloadClick(Sender: TObject);
begin
FreeLibrary(dllHandle);
end;

end.


Arno Garrels

Posts: 11
Registered: 5/24/04
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2012 8:41 AM   in response to: Robert Liebeskind in response to: Robert Liebeskind
Robert Liebeskind wrote:
As I mentioned,
the access violation occurs on the call to FreeLibrary, not after it.
The access violation I receive is "Project Mock.exe raised exception
class $C0000005 with message 'access violation at 0x00000000: read of
address 0x00000000'.

Perhaps LoadLibrary already failed, you do not check whether or not it
succeeded.

procedure TForm1.LoadClick(Sender: TObject);

begin
// load dll
dllHandle := LoadLibrary('MockXE2.dll') ;

{Add an error check }
if dllHandle = 0 then
RaiseLastOSError;

@getDLLMock := GetProcAddress(dllHandle, 'Mock') ;
end;

procedure TForm1.UnloadClick(Sender: TObject);
begin

{ Check for a null handle }
if dllHandle <> 0 then
FreeLibrary(dllHandle);
end;

Did that help?

--
Arno Garrels
Robert Liebeskind

Posts: 5
Registered: 9/4/11
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 16, 2012 12:59 AM   in response to: Arno Garrels in response to: Arno Garrels
Arno Garrels wrote:
Robert Liebeskind wrote:
As I mentioned,
the access violation occurs on the call to FreeLibrary, not after it.
The access violation I receive is "Project Mock.exe raised exception
class $C0000005 with message 'access violation at 0x00000000: read of
address 0x00000000'.

Perhaps LoadLibrary already failed, you do not check whether or not it
succeeded.

procedure TForm1.LoadClick(Sender: TObject);

begin
// load dll
dllHandle := LoadLibrary('MockXE2.dll') ;

{Add an error check }
if dllHandle = 0 then
RaiseLastOSError;

@getDLLMock := GetProcAddress(dllHandle, 'Mock') ;
end;

procedure TForm1.UnloadClick(Sender: TObject);
begin

{ Check for a null handle }
if dllHandle <> 0 then
FreeLibrary(dllHandle);
end;

Did that help?

--
Arno Garrels

Thanks for the feedback Arno. Unfortunately that is not the problem. The whole app that I posted is a test. When I run it I first click the button that triggers the DLL to load and get a handle to my function. I know this worked because (I have verified it in debug mode and) when I click the button to evoke the function, the text in the edit control is updated as expected, to the value '8'. This can only happen if the DLL loaded properly. Thanks again for the suggestion though.
Robert Liebeskind

Posts: 5
Registered: 9/4/11
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 14, 2012 6:41 AM   in response to: Ken White in response to: Ken White
Ken White wrote:
Robert Liebeskind wrote:
I receive an Access Violation when calling FreeLibrary using the DLL Code below built on a WindowsXP Machine using Delphi 2007 and called by a Host app (code also shown below) that is built on a Windows 7 machine using Delphi XE2.

First, you have two UnloadClick procedures defined in your test application, which makes it uncompileable.

Second, you've given no information on what access violation you receive. Specific error messages (including any memory address information) is really important when asking people to help you solve a problem.

Third, your code that calls FreeLibrary (whichever one is actually being used) should set dllHandle to 0 and getDLLMock to nil after calling FreeLibrary; FreeLibrary does not magically set the dllHandle and any loaded procedure pointers to nil, and so a test of Assigned after the library has unloaded will show that the values are still "assigned".

Okay, well I only got this one comment so far. I'm hoping someone can still provide me with some helpful guidance.

BTW, Ken, while confusing, I admit, the fault you noted in my original post of the mock code to demonstrate the problem very very simply, that of the duplicate UnloadClick functions -- you'll note that the second UnloadClick comes after an 'end.' statement and thus is ignored. So, the original code, while confusing, is indeed compilable.

I also have some additional information: If the DLL is built using Delphi 2007 and WinXP, and is called by a Host app also built with Delphi 2007 and WinXP, FreeLibrary is executed without error as well.
Adam Wu

Posts: 1
Registered: 1/17/02
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 21, 2012 2:49 PM   in response to: Robert Liebeskind in response to: Robert Liebeskind
Robert Liebeskind wrote:
Okay, well I only got this one comment so far. I'm hoping someone can still provide me with some helpful guidance.

BTW, Ken, while confusing, I admit, the fault you noted in my original post of the mock code to demonstrate the problem very very simply, that of the duplicate UnloadClick functions -- you'll note that the second UnloadClick comes after an 'end.' statement and thus is ignored. So, the original code, while confusing, is indeed compilable.

I also have some additional information: If the DLL is built using Delphi 2007 and WinXP, and is called by a Host app also built with Delphi 2007 and WinXP, FreeLibrary is executed without error as well.

I suspect FastMM. It has changed its way of sharing memory manager since 2007.
Try download and use the latest FastMM on D2007 and see what happens.
richard fritz

Posts: 3
Registered: 5/21/00
Re: Access Violation when calling FreeLibrary in Delphi 2007  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 31, 2012 11:26 PM   in response to: Robert Liebeskind in response to: Robert Liebeskind
Robert Liebeskind wrote:
I receive an Access Violation when calling FreeLibrary using the DLL Code below built on a WindowsXP Machine using Delphi 2007 and called by a Host app (code also shown below) that is built on a Windows 7 machine using Delphi XE2.

I have a similar problem. Several DLLs which compiled for many years with Delphi 5, Delphi 7, and Delphi 2006, all on XP, when compiled with Delphi 2007 on Windows 7 give an AV whenever freelibrary is called.

These DLL worked for over 10 years on large numbers of machines. They do not use strings, only PChars, thus no memory manager is in use. In fact, to make sure I wasn't missing something, I just restored the complete image of my project from my XP machine to my Windows 7 machine (yes, a laptop), and compiled with Delphi 2007. Boink!
David Heffernan

Posts: 6
Registered: 9/28/98
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 2, 2012 9:16 AM   in response to: Robert Liebeskind in response to: Robert Liebeskind
Submit a QC report

On 12/01/2012 15:18, Robert Liebeskind wrote:
I receive an Access Violation when calling FreeLibrary using the DLL Code below built on a WindowsXP Machine using Delphi 2007 and called by a Host app (code also shown below) that is built on a Windows 7 machine using Delphi XE2.

If I build the DLL using Win7 and XE2 I do not get an access violation.

Unfortunately, I must use Delphi 2007 to build my DLL. Does anyone have an idea as to why this code fails on FreeLibrary given this scenario?

The code below has been stripped down to its essence in order to simplify debugging this problem. It is not the full code that I must use but the issue can be reproduced using the example code below.

Thank you for your assistance.

DLL Code:

library MockXE2;

uses
System.SysUtils,
System.Classes;

{$R *.res}

function Mock:Integer; stdcall;
begin
result := 8;
end;

exports Mock;

begin
end.


Host app code:


unit Mock1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
TForm1 = class(TForm)
Load: TButton;
Call: TButton;
Unload: TButton;
Edit1: TEdit;
procedure LoadClick(Sender: TObject);
procedure CallClick(Sender: TObject);
procedure UnloadClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TGetDLLMock = function : Integer; stdcall;

var
Form1: TForm1;
dllHandle: Cardinal;
getDLLMock : TGetDLLMock;
result: Integer;

implementation

{$R *.dfm}

procedure TForm1.CallClick(Sender: TObject);
begin
if Assigned (getDLLMock) then
begin
result := getDLLMock;
Edit1.Text := IntToStr(result);
end;
end;

procedure TForm1.LoadClick(Sender: TObject);

begin
dllHandle := LoadLibrary('MockXE2.dll') ;
@getDLLMock := GetProcAddress(dllHandle, 'Mock') ;
end;

procedure TForm1.UnloadClick(Sender: TObject);
begin
FreeLibrary(dllHandle);
end;

end.
procedure TForm1.UnloadClick(Sender: TObject);
begin
FreeLibrary(dllHandle);
end;

end.

mustapha wang

Posts: 1
Registered: 6/17/02
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 8, 2013 2:37 AM   in response to: Robert Liebeskind in response to: Robert Liebeskind
I also appear this bug.
I use delphi7 compile bpl on win7 64bit.
When I unloadpackage, raise av at "freelibrary".

My delphi7 itself always crash every time when closing.

Edited by: mustapha wang on Jan 8, 2013 2:38 AM
Roland Kossow

Posts: 28
Registered: 9/23/99
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 9, 2014 9:15 AM   in response to: mustapha wang in response to: mustapha wang
Even though this is a rather old thread.
I have had the same problem in a project where the DLL was build with Delphi 2007 and loading and freeing process was an EXE build with XE6.
I figured out that the AV is not happening, when I build the DLL in Delphi 2007 using RELEASE options.
Adriano Macome

Posts: 14
Registered: 9/26/11
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 28, 2014 3:45 AM   in response to: Robert Liebeskind in response to: Robert Liebeskind
Hello;

I am fighting with the same problem since years and never found a solution. All the library funcionalities works fine (longly and hardly tested for years), but when it comes the time to unload, I get an exception error. This is the same from Delphi XE2 to XE7 (at least).

The very rare thing is the exception pass out form my try-except-end block.

function LoadSVRDLL: string;
var
sFile: string;
begin
try
sFile := 'MYLIB.DLL';
SVRDLLHandle := LoadLibrary(PChar(sFile)); if SVRDLLHandle <> 1 then raise Exception.Create('Error ...');
@Uno := GetProcAddress(SVRDLLHandle,'Uno');
@Dos := GetProcAddress(SVRDLLHandle,'Dos');
result := 'OK';
except
on E:Exception do result := E.Message;
end;
end;

function UnloadSVRDLL: string;
begin
try
@Uno := nil;
@Dos := nil;
if not FreeLibrary(SVRDLLHandle) then raise Exception.Create('Error ...');
result := 'OK';
except
on E:Exception do result := E.Message;
end;
end;

Both fuctions return OK, but the debugger always stop with an exception error exaclty after UnloadSVRDLL is called.

Very very rare case, any idea?

Best regards,

Adriano

Peter Below

Posts: 495
Registered: 12/16/99
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 29, 2014 12:59 AM   in response to: Adriano Macome in response to: Adriano Macome
Adriano Macome wrote:

Hello;

I am fighting with the same problem since years and never found a
solution. All the library funcionalities works fine (longly and
hardly tested for years), but when it comes the time to unload, I get
an exception error. This is the same from Delphi XE2 to XE7 (at
least).

The very rare thing is the exception pass out form my try-except-end
block.

function LoadSVRDLL: string;
var
sFile: string;
begin
try
sFile := 'MYLIB.DLL';
SVRDLLHandle := LoadLibrary(PChar(sFile)); if SVRDLLHandle <> 1
then raise Exception.Create('Error ...'); @Uno :=
GetProcAddress(SVRDLLHandle,'Uno'); @Dos :=
GetProcAddress(SVRDLLHandle,'Dos'); result := 'OK';
except
on E:Exception do result := E.Message;
end;
end;

function UnloadSVRDLL: string;
begin
try
@Uno := nil;
@Dos := nil;
if not FreeLibrary(SVRDLLHandle) then raise
Exception.Create('Error ...'); result := 'OK';
except
on E:Exception do result := E.Message;
end;
end;

Both fuctions return OK, but the debugger always stop with an
exception error exaclty after UnloadSVRDLL is called.

Very very rare case, any idea?


If your application has obtained a memory reference (string, object
reference, interface reference, basically anything that refers to
memory created by the DLL's memory manager) that reference would be
invalid after the DLL has been freed. The other way around is also a
problem: if you pass a memory reference created by the host
application's memory manager to the DLL, and the DLL stores it beyond
the scope of the called function, then the automatic cleanup done when
the DLL is unloaded may try to release the memory using the DLL's
memory manager.

It gets worse if both your host application and the DLL are build with
different Delphi versions, or even with different languages...

--
Peter Below (TeamB)
Rudy Velthuis (...


Posts: 3,103
Registered: 9/22/99
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 4, 2014 5:31 AM   in response to: Peter Below in response to: Peter Below
Peter Below wrote:

Adriano Macome wrote:

Hello;

I am fighting with the same problem since years and never found a
solution. All the library funcionalities works fine (longly and
hardly tested for years), but when it comes the time to unload, I
get an exception error. This is the same from Delphi XE2 to XE7 (at
least).

The very rare thing is the exception pass out form my try-except-end
block.

function LoadSVRDLL: string;
var
sFile: string;
begin
try
sFile := 'MYLIB.DLL';
SVRDLLHandle := LoadLibrary(PChar(sFile)); if SVRDLLHandle <> 1
then raise Exception.Create('Error ...'); @Uno :=
GetProcAddress(SVRDLLHandle,'Uno'); @Dos :=
GetProcAddress(SVRDLLHandle,'Dos'); result := 'OK';
except
on E:Exception do result := E.Message;
end;
end;

function UnloadSVRDLL: string;
begin
try
@Uno := nil;
@Dos := nil;
if not FreeLibrary(SVRDLLHandle) then raise
Exception.Create('Error ...'); result := 'OK';
except
on E:Exception do result := E.Message;
end;
end;

Both fuctions return OK, but the debugger always stop with an
exception error exaclty after UnloadSVRDLL is called.

Very very rare case, any idea?


If your application has obtained a memory reference (string, object
reference, interface reference, basically anything that refers to
memory created by the DLL's memory manager) that reference would be
invalid after the DLL has been freed. The other way around is also a
problem: if you pass a memory reference created by the host
application's memory manager to the DLL, and the DLL stores it beyond
the scope of the called function, then the automatic cleanup done when
the DLL is unloaded may try to release the memory using the DLL's
memory manager.

It gets worse if both your host application and the DLL are build with
different Delphi versions, or even with different languages...

Indeed, indeed. I see this very often, also as a question on Stack
Overflow.

That is why one should never pass (or require) types that are
Delphi-specific, like dynarrays, strings, etc. between applications and
DLLs. DLL functions should only require simple POD (plain old data)
types like integers, floats, POD structs, pointers, etc.

A well written DLL should never do the things you mention.

--
Rudy Velthuis http://www.rvelthuis.de

"No man's knowledge here can go beyond his experience."
-- John A. Locke
Craig Burke

Posts: 11
Registered: 4/28/07
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 7, 2015 7:15 PM   in response to: Rudy Velthuis (... in response to: Rudy Velthuis (...
Hello,

XE2, Win 7
32 bit app.

I just started in the last couple of weeks to see this issue. I have 4
different dll's all compiled in the same env. as the exe's. No changes to
code in over a year.
Is in use by hundreds of users and now I am getting calls with this issue.

To simplify the issue. I only need to call LoadLibrary and FreeLibrary:
I used the same test with all four dll's and all av'ed on the FreeLibrary
call

procedure Tdlgtest.buttonClick(Sender: TObject);
var
LibHandle: HModule;
begin

LibHandle := LoadLibrary('mydll.dll');
if (LibHandle <> 0) then
try
// do stuff here
finally
FreeLibrary('mydll.dll'); // av here!!!
end
else
ShowMessage(FmtLoadStr(319, ['mydll.dll']));
end;


I changed from using ShareMem to SimpleShareMem and was able to call the
dll's and Unload without issue on my Win 7 computer.
Sent the files to my client to test and it randomly crashes on the
FreeLibrary call. Client is running it on T/S.

Any ideas on what is going on.

TIA,

Craig

Peter Below

Posts: 495
Registered: 12/16/99
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 8, 2015 10:06 AM   in response to: Craig Burke in response to: Craig Burke
Craig Burke wrote:

Hello,

XE2, Win 7
32 bit app.

I just started in the last couple of weeks to see this issue. I have
4 different dll's all compiled in the same env. as the exe's. No
changes to code in over a year.
Is in use by hundreds of users and now I am getting calls with this
issue.

To simplify the issue. I only need to call LoadLibrary and
FreeLibrary: I used the same test with all four dll's and all av'ed
on the FreeLibrary call

Such stuff is difficult to track, and may even depend on software
running on the addected PCs that have nothing to do with your software
(e.g. virus scanners that inject code into every running process).

My advice would be to simply not call FreeLibrary. Instead of
LoadLibrary call GetModuleHandle with the DLL name first, to see if it
is already loaded. If not, load it (best using SafeLoadLibrary, not
LoadLibrary). Use it, forget it. The OS is perfectly able to unload the
DLL when the process ends. If you need some kind of cleanup inside the
DLL before it is unloaded, export a function for that and call it
before your application terminates.


--
Peter Below (TeamB)

Craig Burke

Posts: 11
Registered: 4/28/07
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 8, 2015 3:22 PM   in response to: Peter Below in response to: Peter Below
Hi Peter,

Thanks for the response!

Does leaving the DLL loaded use more memory or slow that app down at all? I
have four dlls.
Would this be similar to static loading?

TIA,

Craig

"Peter Below" <none@address.invalid> wrote in message
news:708526 at forums dot embarcadero dot com...
Craig Burke wrote:

Hello,

XE2, Win 7
32 bit app.

I just started in the last couple of weeks to see this issue. I have
4 different dll's all compiled in the same env. as the exe's. No
changes to code in over a year.
Is in use by hundreds of users and now I am getting calls with this
issue.

To simplify the issue. I only need to call LoadLibrary and
FreeLibrary: I used the same test with all four dll's and all av'ed
on the FreeLibrary call

Such stuff is difficult to track, and may even depend on software
running on the addected PCs that have nothing to do with your software
(e.g. virus scanners that inject code into every running process).

My advice would be to simply not call FreeLibrary. Instead of
LoadLibrary call GetModuleHandle with the DLL name first, to see if it
is already loaded. If not, load it (best using SafeLoadLibrary, not
LoadLibrary). Use it, forget it. The OS is perfectly able to unload the
DLL when the process ends. If you need some kind of cleanup inside the
DLL before it is unloaded, export a function for that and call it
before your application terminates.


--
Peter Below (TeamB)

Peter Below

Posts: 495
Registered: 12/16/99
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 9, 2015 9:48 AM   in response to: Craig Burke in response to: Craig Burke
Craig Burke wrote:

Hi Peter,

Thanks for the response!

Does leaving the DLL loaded use more memory or slow that app down at
all? I have four dlls.
Would this be similar to static loading?

Yes, it is similar to static loading as far as memory consumption is
concerned. Don't worry about that, the OS will page out the memory
occupied by the DLL code when it is not called for some time and more
of the physical RAM present is needed for other purposes. The DLL will
not consume any CPU resources if none of its code is called (unless it
has timers or such running).


--
Peter Below (TeamB)

Craig Burke

Posts: 11
Registered: 4/28/07
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 9, 2015 3:17 PM   in response to: Peter Below in response to: Peter Below
Thanks Peter.

I created a function to GetModuleHandle if 0 then SafeLoadLibrary.
commented out the FreeLibrary. No code is run after the SafeLoadLibrary and
still crashes on shutdown.

The trace breaks on :
unit Data.DBXClassRegistry;

procedure TClassRegistry.UnregisterClass(ClassName: UnicodeString);
var
ClassItem: TClassRegistryItem;
Index: Integer;
begin
FLock.LockList; // av's here!!!
try
if FClasses.Find(ClassName, Index) then
begin
ClassItem := FClasses.Objects[Index] as TClassRegistryItem;
ClassItem.Free;
FClasses.Delete(Index);
end;
finally
FLock.UnlockList;
end;
end;

TIA,
Craig

"Peter Below" <none@address.invalid> wrote in message
news:708738 at forums dot embarcadero dot com...

Craig Burke wrote:

Hi Peter,

Thanks for the response!

Does leaving the DLL loaded use more memory or slow that app down at
all? I have four dlls.
Would this be similar to static loading?

Yes, it is similar to static loading as far as memory consumption is
concerned. Don't worry about that, the OS will page out the memory
occupied by the DLL code when it is not called for some time and more
of the physical RAM present is needed for other purposes. The DLL will
not consume any CPU resources if none of its code is called (unless it
has timers or such running).


--
Peter Below (TeamB)

Peter Below

Posts: 495
Registered: 12/16/99
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 10, 2015 2:58 AM   in response to: Craig Burke in response to: Craig Burke
Craig Burke wrote:

Thanks Peter.

I created a function to GetModuleHandle if 0 then SafeLoadLibrary.
commented out the FreeLibrary. No code is run after the
SafeLoadLibrary and still crashes on shutdown.

The trace breaks on :
unit Data.DBXClassRegistry;

procedure TClassRegistry.UnregisterClass(ClassName: UnicodeString);
var
ClassItem: TClassRegistryItem;
Index: Integer;
begin
FLock.LockList; // av's here!!!
try
if FClasses.Find(ClassName, Index) then
begin
ClassItem := FClasses.Objects[Index] as TClassRegistryItem;
ClassItem.Free;
FClasses.Delete(Index);
end;
finally
FLock.UnlockList;
end;
end;


That looks as if some code calls the UnregisterClass method after the
Tclassregistry instance has already been destroyed.

This is probably a problem with the sequence in which unit Finalization
sections are called. Try this:

Open the DLL project's DPR file, add the Data.DBXClassRegistry unit to
the Uses clause there near the start. It should appear after
system.classes and system.sysutils, but before any other units from the
Data namespace, or form/frame/datamodule units that may contain
references to DBX components. This way the unit's finalization section
should be called late in the shutdown sequence and that will hopefully
solve the problem.


--
Peter Below (TeamB)

Craig Burke

Posts: 11
Registered: 4/28/07
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 10, 2015 8:47 AM   in response to: Peter Below in response to: Peter Below
Thanks Peter.

Ok, tried adding Data.DBXClassRegistry as you suggested and av is now in the
midas.dll.
I added the DBX files that call the UnregisterClass, swapped the order
around, tried about 50 different variations.
Nada. Even tested using the SampleShareMem demo calling my dll with just the
LoadLibrary and SafeLoadLibrary
nothing else. Close the app and crash. Just seems that the DBX / midas.dll
are not happy.

TIA,
Craig

"Peter Below" <none@address.invalid> wrote in message
news:708801 at forums dot embarcadero dot com...

Craig Burke wrote:

Thanks Peter.

I created a function to GetModuleHandle if 0 then SafeLoadLibrary.
commented out the FreeLibrary. No code is run after the
SafeLoadLibrary and still crashes on shutdown.

The trace breaks on :
unit Data.DBXClassRegistry;

procedure TClassRegistry.UnregisterClass(ClassName: UnicodeString);
var
ClassItem: TClassRegistryItem;
Index: Integer;
begin
FLock.LockList; // av's here!!!
try
if FClasses.Find(ClassName, Index) then
begin
ClassItem := FClasses.Objects[Index] as TClassRegistryItem;
ClassItem.Free;
FClasses.Delete(Index);
end;
finally
FLock.UnlockList;
end;
end;


That looks as if some code calls the UnregisterClass method after the
Tclassregistry instance has already been destroyed.

This is probably a problem with the sequence in which unit Finalization
sections are called. Try this:

Open the DLL project's DPR file, add the Data.DBXClassRegistry unit to
the Uses clause there near the start. It should appear after
system.classes and system.sysutils, but before any other units from the
Data namespace, or form/frame/datamodule units that may contain
references to DBX components. This way the unit's finalization section
should be called late in the shutdown sequence and that will hopefully
solve the problem.


--
Peter Below (TeamB)

Markus Humm

Posts: 1,921
Registered: 11/9/03
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 12, 2015 10:27 AM   in response to: Craig Burke in response to: Craig Burke
Am 10.01.2015 um 17:47 schrieb Craig Burke:
Thanks Peter.

Ok, tried adding Data.DBXClassRegistry as you suggested and av is now in the
midas.dll.
I added the DBX files that call the UnregisterClass, swapped the order
around, tried about 50 different variations.
Nada. Even tested using the SampleShareMem demo calling my dll with just the
LoadLibrary and SafeLoadLibrary
nothing else. Close the app and crash. Just seems that the DBX / midas.dll
are not happy.


Hello,

is it necessary to use midas in it's dll form?
Afaik it's available as a unit which can be linked in as well.
I think the name is midaslib.

Greetings

Markus
Craig Burke

Posts: 11
Registered: 4/28/07
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 13, 2015 4:30 PM   in response to: Markus Humm in response to: Markus Humm
Hello Markus,

I tried that also to no avail.

See next post from me.
It seems to be an issue with XE2.

- Craig

"Markus Humm" <markus dot humm at freenet dot de> wrote in message
news:709019 at forums dot embarcadero dot com...

Am 10.01.2015 um 17:47 schrieb Craig Burke:
Thanks Peter.

Ok, tried adding Data.DBXClassRegistry as you suggested and av is now in
the
midas.dll.
I added the DBX files that call the UnregisterClass, swapped the order
around, tried about 50 different variations.
Nada. Even tested using the SampleShareMem demo calling my dll with just
the
LoadLibrary and SafeLoadLibrary
nothing else. Close the app and crash. Just seems that the DBX /
midas.dll
are not happy.


Hello,

is it necessary to use midas in it's dll form?
Afaik it's available as a unit which can be linked in as well.
I think the name is midaslib.

Greetings

Markus
Craig Burke

Posts: 11
Registered: 4/28/07
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 12, 2015 8:19 AM   in response to: Peter Below in response to: Peter Below
Hello Peter,

Here is something interesting... Is this an issue with XE2 ?

Using only the SimpleShareMem demo it still crashes when closing the app.

Here is the code for the demo's TestDll: Note the ShowMessage never is
displayed.

<code>
library TestDLL;

uses
SimpleShareMem,
SysUtils,
Classes,
Vcl.Dialogs,
Vcl.Themes in 'Vcl.Themes.pas';

{$R *.res}

procedure ClearString(var AString: string);
begin
AString := '';
end;

exports ClearString;

begin
if IsMemoryManagerSet then
showmessage('TestDLL.dll loaded and sharing the main application''s
memory manager.');
end.
</code>

And the code that calls the TestDll: Simply removing FreeLibrary will cause
AV when shutting down.

<code>
procedure TfMainAppForm.bLoadDLLClick(Sender: TObject);
var
LDLLHandle: HModule;
ClearString: procedure(var AString: string);
LTempStr: string;
i: integer;
begin
LDLLHandle := LoadLibrary('TestDLL.dll');
if LDLLHandle <> 0 then
begin

ClearString := GetProcAddress(LDLLHandle, 'ClearString');
if Assigned(ClearString) then
begin
{Allocate lots of long strings and let the DLL free them}
for i := 1 to 10000 do
begin
LTempStr := IntToStr(i);
ClearString(LTempStr);
end;

ShowMessage('escdict.dll It works!');
end
else
ShowMessage('ClearString procedure not found in TestDLL.dll.');

{Free the library}
//FreeLibrary(LDLLHandle);
end
else
ShowMessage('TestDLL.dll not found.');
end;
</code>

"Peter Below" <none@address.invalid> wrote in message
news:708801 at forums dot embarcadero dot com...

Craig Burke wrote:

Thanks Peter.

I created a function to GetModuleHandle if 0 then SafeLoadLibrary.
commented out the FreeLibrary. No code is run after the
SafeLoadLibrary and still crashes on shutdown.

The trace breaks on :
unit Data.DBXClassRegistry;

procedure TClassRegistry.UnregisterClass(ClassName: UnicodeString);
var
ClassItem: TClassRegistryItem;
Index: Integer;
begin
FLock.LockList; // av's here!!!
try
if FClasses.Find(ClassName, Index) then
begin
ClassItem := FClasses.Objects[Index] as TClassRegistryItem;
ClassItem.Free;
FClasses.Delete(Index);
end;
finally
FLock.UnlockList;
end;
end;


That looks as if some code calls the UnregisterClass method after the
Tclassregistry instance has already been destroyed.

This is probably a problem with the sequence in which unit Finalization
sections are called. Try this:

Open the DLL project's DPR file, add the Data.DBXClassRegistry unit to
the Uses clause there near the start. It should appear after
system.classes and system.sysutils, but before any other units from the
Data namespace, or form/frame/datamodule units that may contain
references to DBX components. This way the unit's finalization section
should be called late in the shutdown sequence and that will hopefully
solve the problem.


--
Peter Below (TeamB)

Peter Below

Posts: 495
Registered: 12/16/99
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 12, 2015 10:34 AM   in response to: Craig Burke in response to: Craig Burke
Craig Burke wrote:

Hello Peter,

Here is something interesting... Is this an issue with XE2 ?

Using only the SimpleShareMem demo it still crashes when closing the
app.

Do you have any newer Delphi version installed you could use for a
test? I have never used XE2 in production myself and cannot test using
it since I don't have it installed anymore. I went directly from XE to
XE5.


Here is the code for the demo's TestDll: Note the ShowMessage never
is displayed.

snip

--
Peter Below (TeamB)
Craig Burke

Posts: 11
Registered: 4/28/07
Re: Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 12, 2015 1:47 PM   in response to: Peter Below in response to: Peter Below
Hey Peter,

I went from D2007 to XE2.
I do have XE7 though, I don't know what other issues this might cause with
trying to compile our apps.
Or if all of our third party source is XE7 compatible yet.

- Craig

"Peter Below" <none@address.invalid> wrote in message
news:709028 at forums dot embarcadero dot com...
Craig Burke wrote:

Hello Peter,

Here is something interesting... Is this an issue with XE2 ?

Using only the SimpleShareMem demo it still crashes when closing the
app.

Do you have any newer Delphi version installed you could use for a
test? I have never used XE2 in production myself and cannot test using
it since I don't have it installed anymore. I went directly from XE to
XE5.


Here is the code for the demo's TestDll: Note the ShowMessage never
is displayed.

snip

--
Peter Below (TeamB)
Craig Burke

Posts: 11
Registered: 4/28/07
Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 8, 2015 12:04 PM   in response to: Craig Burke in response to: Craig Burke
Hello,

XE2, Win 7
32 bit app.

I just started in the last couple of weeks to see this issue. I have 4
different dll's all compiled in the same env. as the exe's. No changes to
code in over a year.
Is in use by hundreds of users and now I am getting calls with this issue.

To simplify the issue. I only need to call LoadLibrary and FreeLibrary:
I used the same test with all four dll's and all av'ed on the FreeLibrary
call

procedure Tdlgtest.buttonClick(Sender: TObject);
var
LibHandle: HModule;
begin

LibHandle := LoadLibrary('mydll.dll');
if (LibHandle <> 0) then
try
; // do stuff here
finally
FreeLibrary(LibHandle); // av here!!!
end
else
ShowMessage(FmtLoadStr(319, ['mydll.dll']));
end;

I changed from using ShareMem to SimpleShareMem and was able to call the
dll's and Unload without issue on my Win 7 computer. Sent the files to my
client to test and it randomly crashes on the
FreeLibrary call. Client is running it on Server 2008 RS2 T/S.

Any ideas on what is going on.

TIA,

Craig

Craig Burke

Posts: 11
Registered: 4/28/07
Access Violation when calling FreeLibrary  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 8, 2015 12:39 PM   in response to: Craig Burke in response to: Craig Burke
Hello,

XE2, Win 7
32 bit app.

I just started in the last couple of weeks to see this issue. I have 4
different dll's all compiled in the same env. as the exe's. No changes to
code in over a year.
Is in use by hundreds of users and now I am getting calls with this issue.

To simplify the issue. I only need to call LoadLibrary and FreeLibrary:
I used the same test with all four dll's and all av'ed on the FreeLibrary
call

procedure Tdlgtest.buttonClick(Sender: TObject);
var
LibHandle: HModule;
begin

LibHandle := LoadLibrary('mydll.dll');
if (LibHandle <> 0) then
try
; // do stuff here
finally
FreeLibrary(LibHandle); // av here!!!
end
else
ShowMessage(FmtLoadStr(319, ['mydll.dll']));
end;

I changed from using ShareMem to SimpleShareMem and was able to call the
dll's and Unload without issue on my Win 7 computer. Sent the files to my
client to test and it randomly crashes on the
FreeLibrary call. Client is running it on Server 2008 RS2 T/S.

Any ideas on what is going on.

TIA,

Craig

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02