[fpc-pascal] TIniFile crash

James Richters james.richters at productionautomation.net
Sat Jul 26 23:05:58 CEST 2025


I'm having an issue with TIniFile, 
I have a pretty simple procedure,  It deletes the old .ini file, waits for
it to be gone,  creates a new one, writes a bunch of variables to it, then
frees it.  It works 99% of the time, but 1% of the time it crashes right in
the middle of writing the file.  The previous one was really deleted because
there is nothing left of the original after the crash, it contains only
lines up to the failure.  I just don't see what I am doing wrong and I am
hoping someone can help me figure out how to fix this.
This is a single thread console application created with FreePascal with out
Lazarus, and this file is not used by anything else.  I just happened to
catch it this time and I was sitting right here and nothing else was
accessing Location.ini when the crash happened.
This happens on multiple difference computers.  Most of which have no
purpose other than to run this one program, so there is never anything else
even open in the system at all.

Anyone have any idea why this is happening and how I might be able to
prevent it?
Below is the crash and related source code.

James



Saving Location
An unhandled exception occurred at $00603277:
EFCreateError: Unable to create file
"I:\Programming\Gcode\Mill\Location.ini": The process cannot access the file
because it is being used by another process.
  $00603277
  $0060314F
  $00608338
  $00602148
  $006021F2
  $004675D7  INI_WRITESTRING,  line 7204 of
I:/Programming/Gcode/Mill/PaStep.pas
  $004AFC88  SAVEPOSITION,  line 23835 of
I:/Programming/Gcode/Mill/PaStep.pas
  $004AF8D6  SAVEBIT,  line 23803 of I:/Programming/Gcode/Mill/PaStep.pas
  $004BF211  ENDPROGRAM,  line 27228 of I:/Programming/Gcode/Mill/PaStep.pas
  $00408099  CTRL_X_EXIT,  line 1355 of
I:/Programming/Gcode/Mill/Promill.pas
  $00429825  main,  line 7858 of I:/Programming/Gcode/Mill/Promill.pas

Line 7204 is Ini.WriteString(Ini_Sec,Ini_Tag,Ini_Val); from this procedure


Procedure Ini_WriteString(Const Ini_Sec,ini_Tag: AnsiString; Const Ini_Val:
AnsiString);
Begin
   Ini.WriteString(Ini_Sec,Ini_Tag,Ini_Val);
End;


Line 23835 is    Ini_WriteString    ('#### Tap File ####'                ,
'Tap_Path'                         , Tap_Path                   );
>From the SavePosition procedure below

Here is the SavePostition Procedure


Procedure SavePosition;
Var
  fileSource, fileDest: AnsiString;
  Resultsofit : Boolean;
Begin
   Writeln('Saving Location');
   DeleteFileAndWaitForItToBeGone(Prog_dir+'Location.ini');
   If Ini_Save_Location_On_C Then
 
DeleteFileAndWaitForItToBeGone(Promill_C+Program_Path+'\Location.ini');
   Ini := TIniFile.Create(Prog_dir+'Location.ini');
   Ini_WriteString ('#### Location ####'                   , 'Postition.X'
, Sav[X_Axis]                );
   Ini_WriteString ('#### Location ####'                   , 'Postition.Y'
, Sav[Y_Axis]                );
   Ini_WriteString ('#### Location ####'                   , 'Postition.Z'
, Sav[Z_Axis]                );
   Ini_WriteString ('#### Location ####'                   , 'Postition.W'
, Sav[W_Axis]                );
   Ini_WriteString ('#### Location ####'                   , 'Postition.L'
, Sav[L_Axis]                );
   Ini_WriteString ('#### Location ####'                   , 'Postition.R'
, Sav[R_Axis]                );
   Ini_WriteString ('#### Location ####'                   , 'Postition.A'
, Sav[A_Axis]                );
   Ini_WriteString ('#### Location ####'                   , 'Postition.B'
, Sav[B_Axis]                );
   Ini_WriteString ('#### Location ####'                   , 'Postition.C'
, Sav[C_Axis]                );
   Ini_WriteString    ('#### Location ####'                , 'Swap_Current'
, SWAPCURRENT                );
   Ini_WriteDouble    ('#### Location ####'                ,
'Current_Value_At_Home.Z'          , Current_Value_At_Home.Z    );
   Ini_WriteDouble    ('#### Location ####'                ,
'Current_Value_At_Home.W'          , Current_Value_At_Home.W    );
   Ini_WriteString    ('#### Location ####'                , 'Tool'
, P_Value[P_Head_Tool]       );
   Ini_WriteString    ('#### Location ####'                , 'Zone'
, P_Value[P_Zone]            );
   Ini_WriteString    ('#### Location ####'                , 'MultiSpeed'
, P_Value[MultiSpeed]        );
   Ini_WriteBoolean   ('#### Tap File ####'                ,
'Use_Default_Tap_Drive'            , Use_Default_Tap_Drive      );
   Ini_WriteBoolean   ('#### Tap File ####'                ,
'Use_Default_Tap_Directory'        , Use_Default_Tap_Directory  );
   Ini_WriteBoolean   ('#### Tap File ####'                ,
'Tap_Files_Only'                   , Tap_Files_Only             );
   Ini_WriteString    ('#### Tap File ####'                , 'Tap_Drive'
, Tap_Drive                  );
   Ini_WriteString    ('#### Tap File ####'                , 'Tap_Path'
, Tap_Path                   );
   Ini_WriteString    ('#### Tap File ####'                ,
'Tap_SubDirectory'                 , Tap_SubDirectory           );
   Ini_WriteString    ('#### Tap File ####'                , 'File'
, P_Value[P_File]            );
   Ini_WriteString    ('#### Tap File ####'                ,
'File_Extension'                   , PvalueP_Fileext            );
   Ini_WriteString    ('#### Tap File ####'                , 'Load_Filename'
, Load_Filename              );
   Ini_WriteString    ('#### Tap File ####'                , 'Loaded_File'
, Loaded_File                );
 
. a bunch of other things .
 
   Ini_WriteFormated ('#### Timers ####'               ,
'Laser_Fan_Off_Time'                  , floattostr(Laser_Fan_Off_Time) ,45,
'Off' ,0 , '');
   Ini.Free;
   If Ini_Save_Location_On_C Then
      Begin
         fileSource := Prog_dir+'Location.ini';
         fileDest := Promill_C+Program_Path+'\Location.ini';
         Resultsofit := CopyFile(PChar(fileSource), PChar(fileDest), False);
      End;
   //Writeln('Position Saved');
   //readln;
End;
 
DeleteFileAndWaitForItToBeGone is this

Procedure DeleteFileAndWaitForItToBeGone(Const TargetFileName: String);
Var
   Elapsedmilliseconds       : Integer;
   Sleepintervalmilliseconds : Integer;
   Timeoutmilliseconds       : Integer;
Begin
   TimeoutMilliseconds := 1000;
   SleepIntervalMilliseconds := 10;
   ElapsedMilliseconds := 0;
   If FileExists(TargetFileName) Then
      Begin
         DeleteFile(TargetFileName);
         While (FileExists(TargetFileName)) And (ElapsedMilliseconds <
TimeoutMilliseconds) Do
            Begin
               Sleep(SleepIntervalMilliseconds);
               Inc(ElapsedMilliseconds, SleepIntervalMilliseconds);
            End;
         If FileExists(TargetFileName) Then
            Begin
               TextColor(CC_Red);
               Writeln('Error: File still exists after attempted deletion:
', TargetFileName);
            End;
      End;
End;


Immediately after the crash Location.ini contains:

[#### Location ####]
Postition.X=0
Postition.Y=*
Postition.Z=19.6856
Postition.W=5.735
Postition.L=
Postition.R=
Postition.A=0
Postition.B=0
Postition.C=0
Swap_Current=Z
Current_Value_At_Home.Z=6.766
Current_Value_At_Home.W=5.08
Tool=17
Zone=
MultiSpeed=
 
[#### Tap File ####]
Use_Default_Tap_Drive=False
Use_Default_Tap_Directory=True
Tap_Files_Only=True
Tap_Drive=M:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20250726/bf34e2ae/attachment-0001.htm>


More information about the fpc-pascal mailing list