Recent

Author Topic: [SOLVED] Detect if a memory is valid  (Read 3010 times)

440bx

  • Hero Member
  • *****
  • Posts: 4014
Re: Detect if a memory is valid
« Reply #15 on: November 02, 2022, 01:05:59 am »
Thank you very much for clarifying this!
You're welcome.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Okoba

  • Hero Member
  • *****
  • Posts: 533
Re: [SOLVED] Detect if a memory is valid
« Reply #16 on: November 02, 2022, 03:32:14 pm »
Does anyone knows what SysUtils set to handle such system exceptions? I tried setting ErrorProc and AssertErrorProc but the program still crashes. I want to get it just like SysUtils does it.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • FPC developer.
Re: [SOLVED] Detect if a memory is valid
« Reply #17 on: November 02, 2022, 04:01:31 pm »
Does anyone knows what SysUtils set to handle such system exceptions? I tried setting ErrorProc and AssertErrorProc but the program still crashes. I want to get it just like SysUtils does it.

Sysutils sets a errorproc to RunErrorToExcept  that converts runtimerrors to exceptions. It also defines the exception class. You probably would have to copy all that.

But in general sysutils is a core unit, and it is not smart to avoid it.

Okoba

  • Hero Member
  • *****
  • Posts: 533
Re: [SOLVED] Detect if a memory is valid
« Reply #18 on: November 02, 2022, 04:03:12 pm »
I set all of them but still program crashes silently. Yes but my use case is small program without any unit needs, and I hope to learn something too.

440bx

  • Hero Member
  • *****
  • Posts: 4014
Re: [SOLVED] Detect if a memory is valid
« Reply #19 on: November 02, 2022, 04:38:38 pm »
Yes but my use case is small program without any unit needs, and I hope to learn something too.
if you don't mind a Windows-only solution, you can use IsBadReadPtr or IsBadWritePtr depending on whether you need read or read-write.

Using those API's, you can find out if a pointer is bad without using sysutils.

Another way, likely more portable, would be using (Read/Write)ProcessMemory which likely have equivalents in other O/Ss.

HTH.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Okoba

  • Hero Member
  • *****
  • Posts: 533
Re: [SOLVED] Detect if a memory is valid
« Reply #20 on: November 02, 2022, 04:41:19 pm »
A better way I found is VirtualQuery.
Code: Pascal  [Select][+][-]
  1.  function Check(AValue: Pointer): Boolean;
  2.   var
  3.     MBI: TMemoryBasicInformation;
  4.   begin
  5.     Result := (VirtualQuery(AValue, MBI{%H-}, SizeOf(MBI)) = SizeOf(MBI))
  6.       and (MBI.AllocationProtect <> 0) and (MBI.Protect <> 0)
  7.       and ((MBI.Protect and PAGE_NOACCESS) <> 1)
  8.       and ((MBI.Protect and PAGE_GUARD) <> 1);
  9.   end;

 But using it is a little bit slow comparing to exception, and I am curious to find out how Sysutils handle system exception.
I appreciate any suggestion or code.

440bx

  • Hero Member
  • *****
  • Posts: 4014
Re: [SOLVED] Detect if a memory is valid
« Reply #21 on: November 02, 2022, 05:00:30 pm »
But using it is a little bit slow comparing to exception, and I am curious to find out how Sysutils handle system exception.
I haven't benchmarked the various ways of determining the invalidity of a pointer but, generally speaking, using exceptions will likely be the slowest method because in addition to requiring a ring transition, it also requires going through a list of handlers to find the one, if any, that is willing to deal with the exception.

Personally, I'd use IsBad(Read/Write)Ptr and let the O/S handle the exception internally and return a simple boolean indicating the validity of the pointer.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Okoba

  • Hero Member
  • *****
  • Posts: 533
Re: [SOLVED] Detect if a memory is valid
« Reply #22 on: November 02, 2022, 05:02:29 pm »
You are right about exception being slower, but only if the pointer is invalid and error is rare. Windows API, is slow even on checking valid ones.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5464
  • Compiler Developer
Re: Detect if a memory is valid
« Reply #23 on: November 03, 2022, 07:32:23 am »
Isn't the exception an internal feature of FPC? An that is why the errorProc is available to be set and set by the SysUtils?

Since the switch from SetJump/LongJmp-based exception handling to SEH-based on Windows it is no longer possible to use try-blocks without also using the SysUtils unit. It is on my ToDo list to fix this, but considering that there are few people using it that way it's not a high priority to fix.

Okoba

  • Hero Member
  • *****
  • Posts: 533
Re: [SOLVED] Detect if a memory is valid
« Reply #24 on: November 03, 2022, 09:00:41 am »
@PascalDragon can you point me to the section of SysUtils that sets handling these exceptions? Maybe I can find my way with it for the time being.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5464
  • Compiler Developer
Re: [SOLVED] Detect if a memory is valid
« Reply #25 on: November 04, 2022, 07:43:25 am »
SysUtils isn't the important part here. The important part is the raw exception handling in the System unit that calls function pointers that the SysUtils unit hooks into (or more precisely that this code doesn't call compared to the generic exception handling). You can find it in rtl/win32/seh32.inc and rtl/win64/seh64.inc and the generic one in rtl/inc/except.inc.

Okoba

  • Hero Member
  • *****
  • Posts: 533
Re: [SOLVED] Detect if a memory is valid
« Reply #26 on: November 22, 2022, 03:28:31 pm »
Thank you.

I checked them and found I can have a custom exception handling like this:
Code: Pascal  [Select][+][-]
  1. uses
  2.   windows;
  3.  
  4. type
  5.   CustomException = class(TObject)
  6.     Code: Longint;
  7.   end;
  8.  
  9.   CustomExceptClass = class of CustomException;
  10.  
  11. implementation
  12.  
  13. function DoExceptObjProc(code: Longint; const rec: TExceptionRecord): CustomException;
  14. begin
  15.   WriteLn('DoExceptObjProc');
  16.   Result := CustomException.Create;
  17.   Result.Code := code;
  18. end;
  19.  
  20. function DoExceptClsProc(code: Longint): CustomExceptClass;
  21. begin
  22.   WriteLn('DoExceptClsProc');
  23.   Result := CustomException;
  24. end;
  25.  
  26. initialization
  27.   ExceptObjProc := @DoExceptObjProc;
  28.   ExceptClsProc := @DoExceptClsProc;
  29. end.                                                            


A question I have is that in debug mode, Lazarus uses exception handling that leads to the message box. Where was it set?

Okoba

  • Hero Member
  • *****
  • Posts: 533
Re: [SOLVED] Detect if a memory is valid
« Reply #27 on: November 22, 2022, 03:37:30 pm »
Here is a cleaner version of checking a memory is valid:
Code: Pascal  [Select][+][-]
  1.   function IsValid(AValue: Pointer): Boolean;
  2.   var
  3.     OldExceptObjProc, OldExceptClsProc: Pointer;
  4.   begin
  5.     OldExceptObjProc := ExceptObjProc;
  6.     OldExceptClsProc := ExceptClsProc;
  7.     ExceptObjProc := @DoExceptObjProc;
  8.     ExceptClsProc := @DoExceptClsProc;
  9.     try
  10.       try
  11.         Result := PBoolean(AValue)^;
  12.       except
  13.         on E: CustomException do
  14.         begin
  15.           Writeln(E.Code);
  16.           Exit(False);
  17.         end;
  18.       end;
  19.       Result := True;
  20.     finally
  21.       ExceptObjProc := @OldExceptObjProc;
  22.       ExceptClsProc := @OldExceptClsProc;
  23.     end;
  24.   end;
  25.            

Is it safe swapping exception handling functions in such manner?

Thaddy

  • Hero Member
  • *****
  • Posts: 14364
  • Sensorship about opinions does not belong here.
Re: [SOLVED] Detect if a memory is valid
« Reply #28 on: November 22, 2022, 04:26:32 pm »
No.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Okoba

  • Hero Member
  • *****
  • Posts: 533
Re: [SOLVED] Detect if a memory is valid
« Reply #29 on: November 22, 2022, 04:29:31 pm »
Thaddy you good man, can you elaborate?

 

TinyPortal © 2005-2018