Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access violation in delphi

In a delphi Application, When I move mouse to a component that has Hint I see this error : " Access violation at address 00484F3B in module 'Plibrary.exe'. Read of address 0000026C" Why this happen?

Call Stack:

:758e9617 KERNELBASE.RaiseException + 0x54 
:458bf456 System.@UStrCmp 
:00407558 @UStrCmp + $2C 
Forms.TApplication.SetHint(???) 
Forms.TApplication.Idle(???) 
Forms.TApplication.HandleMessage 
Forms.TApplication.Run Plibrary.Plibrary 
:75ca1194 kernel32.BaseThreadInitThunk + 0x12 
:7752b3f5 ntdll.RtlInitializeExceptionChain + 0x63 
:7752b3c8 ntdll.RtlInitializeExceptionChain + 0x36" 

And failing code is in System.pas file at line 17732 : "MOV ESI,[ESP]"

Edit (from comment):

In the remain.pas file at this procedure :

procedure TMainForm.ShowHint(Sender: TObject); 
begin 
  if Length(Application.Hint) > 0 then begin 
    StatusBar.SimplePanel := True; 
    StatusBar.SimpleText := Application.Hint; //this line gives error 
  end else    
    StatusBar.SimplePanel := False; 
end;
like image 693
user1073024 Avatar asked Nov 30 '11 09:11

user1073024


2 Answers

Read of address 0000026C

This very low address is indicative of an offset to a member field of a nil object reference. Run under the debugger and make sure the debugger is set to break on exceptions. When it does, you should be able to work out which object reference is nil.

Quite possibly the AV happens in VCL code although it will almost certainly be due to an error in your code. If the debugger doesn't break at a very helpful location, enable Debug DCUs in the project options in order to see the VCL source code at the point where the exception is raised.

The stack trace you provide suggests that the error is in TApplication.SetHint, whilst performing a string comparison. The first line of TApplication.SetHint reads:

if FHint <> Value then

I bet the offset to the FHint of TApplication is $026C and that, somehow, your Application variable is set to nil. That said, I don't understand why the error would not have been raised earlier at Length(Application.Hint). It's quite hard to debug this remotely!

Having looked at the layout of TApplication, I think we can rule out Application being nil. Perhaps FHint itself has somehow been corrupted, or perhaps even Value. I think it's going to take access to the actual code and a debugging environment to track this down.

like image 169
David Heffernan Avatar answered Nov 11 '22 07:11

David Heffernan


Based on the information provided in the stacktrace:

TApplication.Idle:

Control := DoMouseIdle;
if FShowHint and (FMouseControl = nil) then
  CancelHint;
Application.Hint := GetLongHint(GetHint(Control)); // SetHint is called next:

TApplication.SetHint:

if FHint <> Value then // This is the UStrCmp which fails with a Int overflow

String + IntOverflow -> non terminating string. So the most probable cause is a string without a terminator.

So where does the string come from...

  • GetHint(Control) searches the control (which is at the places you clicked with the cursor) and its parent for a hint that is not empty.

  • GetLongHint searches the string for a | and if found, uses the part following the | else it uses the complete string.

  • UStrCmp, is a long pieces of assembler code, that calls other pieces of assembler code. Some of them can raise the EIntegerOverflow error.

Advise

Use the debugger (with debug dcu's on) to see which string has no terminator (0 character at the end). And if you find it, try to solve it or expand the question if you want some more help from us.

like image 35
Toon Krijthe Avatar answered Nov 11 '22 07:11

Toon Krijthe