View Issue Details

IDProjectCategoryView StatusLast Update
0036754FPCCompilerpublic2020-03-08 15:49
ReporterMarcin Wiazowski Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Product Version3.3.1 
Summary0036754: Unit's finalization section is not always called
Description"Finalization" section of the unit is NOT called, when execution of the "Initialization" section is terminated prematurely - like due to calling Halt() or raising an exception. Please see the attached Reproduce demo.


When compiled with Delphi, output is:
  Initialization section called in Unit1
  Initialization section called in Unit2
  Finalization section called in Unit2
  Finalization section called in Unit1

When compiled with FPC, output is:
  Initialization section called in Unit1
  Initialization section called in Unit2
  Finalization section called in Unit1


When object's constructor is terminated prematurely, object's destructor is called to finalize the partially created object. Similarly, when unit's initialization section is terminated prematurely, unit's finalization section should be called - just to clean up global objects, already created in the initialization section (like semaphores, mutexes or temporary files).

Current implementation is neither Delphi compatible, nor deinitializes the unit properly.

Adding the "-Mdelphi" compilation command does not change anything. Tested on Win32 platform, with FPC 3.0.4, 3.2.0 (r44257) and 3.3.1 (r44257).
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files

Activities

Marcin Wiazowski

2020-03-03 23:19

reporter  

Reproduce.zip (595 bytes)

Marcin Wiazowski

2020-03-07 20:25

reporter   ~0121442

I'm attaching a patch.
patch.diff (604 bytes)   
Index: system.inc
===================================================================
--- system.inc	(revision 44282)
+++ system.inc	(working copy)
@@ -1021,9 +1021,12 @@
    begin
      for i:=1 to ALUUInt(TableCount) do
       begin
+        // we've to increment the count before calling the initialization
+        // code, so finalization code will be called in case of a halt call
+        // in the initialization code
+        InitCount:=i;
         if assigned(Procs[i].InitProc) then
          Procs[i].InitProc();
-        InitCount:=i;
       end;
    end;
   if assigned(InitProc) then
patch.diff (604 bytes)   

Thaddy de Koning

2020-03-08 09:56

reporter   ~0121451

This behavior is documented: https://www.freepascal.org/docs-html/rtl/system/halt.html
The behavior with exceptions is like that if the exception is not properly handled. If the exception is raised *and* handled, the finalization section is handled too.

Marcin Wiazowski

2020-03-08 14:57

reporter   ~0121459

Please note, that the problem described here is related to calling Halt(), not to to exceptions. And the Halt() documentation says: "Finalization sections of units will be executed". There is no requirement of executing the *whole* initialization section before executing the corresponding finalization section.

Bart Broersma

2020-03-08 15:49

reporter   ~0121461

Delphi (D7) executes finalization of unit 2 also in case of an unhandled exception in the initialization section of unit 2.

Issue History

Date Modified Username Field Change
2020-03-03 23:19 Marcin Wiazowski New Issue
2020-03-03 23:19 Marcin Wiazowski File Added: Reproduce.zip
2020-03-07 20:25 Marcin Wiazowski File Added: patch.diff
2020-03-07 20:25 Marcin Wiazowski Note Added: 0121442
2020-03-08 09:56 Thaddy de Koning Note Added: 0121451
2020-03-08 14:57 Marcin Wiazowski Note Added: 0121459
2020-03-08 15:49 Bart Broersma Note Added: 0121461