-
-
Notifications
You must be signed in to change notification settings - Fork 41
How to solve EAccessViolation error in Pascal
EAccessViolation
is a Pascal exception name for what is often known as SEGFAULT
, i.e. it's a general error when one accesses a memory one shouldn't. Like accessing a nil
pointer, or accessing an instance that was already freed, or generally passing wrong pointer somewhere.
Since many things can cause this error, there is no simple answer "how to solve this". Admittedly, the title of this page is somewhat a click-bait :) I don't have a ready solution. You need to debug it to know what is causing it.
Run your application in a debugger. Like from Lazarus IDE ( https://www.lazarus-ide.org/ ), or from VS Code (see https://castle-engine.io/vscode ), or from Delphi. Or even from command-line GDB, if you know your way with GDB already. These will give you hopefully a "stack trace", a line that crashes -- which may be enough information to know what's wrong.
In some cases, it's enough to rely on built-in FPC stack printing. Just recompile program with "debug info" and "line info". For command-line FPC it means using -g -gl
command-line options.
E.g. consider this program:
{$mode ObjFPC}{$H+}
type
TMyClass = class
A: Integer;
end;
var
C: TMyClass;
begin
C := nil; // this is actually default value of global variable anyway
C.A := 123; // this should crash!
end.
Compile it using fpc -g -gl a.dpr
. Then if you run it, the stack trace already tells you it crashes at line 12. Here's a snapshot of my console:
$ fpc -g -gl a.dpr
Free Pascal Compiler version 3.2.2-r0d122c49 [2023/07/22] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling a.dpr
Linking a
12 lines compiled, 0.0 sec
$ ./a
Runtime error 216 at $00000000004010AF
$00000000004010AF main, line 12 of a.dpr
Since EAccessViolation
implies you access an invalid pointer, debugging it is often connected with making sure you allocate and deallocate memory properly, in particular that you free all the class instances you create. Making sure that memory allocation / deallocation is doing what you think it is doing is a key piece to avoid EAccessViolation
bugs.
To this end, we recommend using automatic detection of memory leaks and make sure that your application has no memory leaks. Both FPC (HeapTrc
) and Delphi (ReportMemoryLeaksOnShutdown
) offer great built-in mechanisms to check that everything is correct in this regard.
When debugging EAccessViolation
it is often helpful to make sure that your application has no dangling pointers, which are pointers that are not nil
(zero) but are not a valid address of any data in memory.
To this end, we advise to Always use FreeAndNil to free your objects.
To clean the pointers in more complicated cases, see also "Free notification" section of the "Modern Object Pascal Introduction for Programmers".
Happy debugging :) If you get stuck, just ask for help. For example on Castle Game Engine forum or Discord: https://castle-engine.io/talk.php .