[fpc-devel] Re: FPC unit symbol checksum woes

Adriaan van Os fpc at microbizz.nl
Wed Sep 3 00:03:24 CEST 2008


This is a follow-up on a thread on the macpascal mailing list, where the problem at hand couldn't 
be solved.

Regards,

Adriaan van Os

-------

While compiling a large Macintosh Pascal project with FPC, I am running into a number of problems,
which I suspect are related:

1. After a clean, the full build succeeds
2. Ater a successive build (without a clean or source changes) several units are recompiled, until
the compiler crashes
3. After another build, the compiler (sometimes) endlessly keeps compiling a selected number of units.

This is with the latest FPC svn compiler, under Xcode 3.0 using a Makefile target. I am compiling
on an Intel MacBookPro under Mac OS X 10.5.4.


A b o u t  t h e  c r a s h

	error: Compilation aborted
	An unhandled exception occurred at $00128505 :
	EAccessViolation : Access violation
	  $00128505
	  $0010722E
	  $00108507
	  $00108868
	  $00108B92
	  $00104CFD
	  $00107F0C
	  $000E3D21
	  $000F4835
	  $000F0CC9
	  $000E3D21
	  $000F4835
	  $00100414
	  $00101138
	  $000E3D21
	  $000F4835
	  $00100414

	make: *** [compile_tool_compile] Error 217

When running ppc386 under GDB, I get

	Program received signal EXC_BAD_ACCESS, Could not access memory.
	Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
	0x00000000 in ?? ()

or

	Program received signal EXC_BAD_ACCESS, Could not access memory.
	Reason: KERN_PROTECTION_FAILURE at address: 0x00000030
	GEN_LOAD_RETURN_VALUE (LIST=0x59b9a60) at ncgutil.pas:1295
	1295	        if (ressym.refs>0) or (ressym.vardef.needs_inittable) then



A b o u t  r e c o m p i l i n g

When I add -va or -vv to the FPC argument list, I notice lines like

	[28.068] Recompiling MMyutils0, checksum changed for V7Stuff

upon a rebuild for units that haven't changed at all. So, I did the following:

a. clean and build, followed by a ppudump *.ppu > ppudump_clean.txt
b. build without a clean, followed by a ppudump *.ppu > ppudump_rebuild.txt
c. compare the ppudump files with diff -u ppudump_clean.txt ppudump_rebuild.txt > ppudump_diff.txt

Now, the ppudump_diff.txt file has lines like

	@@ -29,7 +29,7 @@
	 Uses unit: Sglobals (Crc: 207BA0FC, IntfcCrc: 207BA0FC)
	 Uses unit: MProutil (Crc: 2A51D9C7, IntfcCrc: 875453BF)
	 Uses unit: InterruptCode (Crc: C36B6157, IntfcCrc: 6D45DAC1)
	-Uses unit: V7Stuff (Crc: 942FBF47, IntfcCrc: D85A6EB1)
	+Uses unit: V7Stuff (Crc: 42F16682, IntfcCrc: 18B40446)
	 Uses unit: MMyutils (Crc: DD59B0C2, IntfcCrc: AFB920A0)
	 Uses unit: MMyutils2 (Crc: 181A1B43, IntfcCrc: ED58FC40)
	 Uses unit: MMyutils0 (Crc: BF00BD89, IntfcCrc: D4DEB0DA)

and even (for some global variables)

	@@ -389309,7 +389309,7 @@
	    SymOptions : Public
	          Spez : Value
	       Regable : None
	-   Addr Taken : TRUE
	+   Addr Taken : FALSE
	      Var Type : (1761) Unit 0, DefId 19
	       Options : TypedConst
	  DefaultConst : (1770) Nil


M y  g u e s s

So far the facts, the rest is what I am concluding and guessing, based on the above:

- there seems to be a unit symbol checksum calculation problem, which is causing unneeded
recompilations.
- the checksum problem may also produce the crash, or at least trigger some unusual state in the
compiler that wasn't foreseen in the code and then leads to the crash
- I get the impression that the checksum problem is related to the order of used units in unit
interface and/or implementation USES clauses
- this may (or may not) be related to mixing macpascal and delphi modes (the project is a mix from
an old CodeWarrior version and the PC Delphi version)
- this may (or may not) be related to using (or even redefining) types that are different in
macpascal and delphi modes, like INTEGER or STRING (any advice I give on coding habits is ignored)
- this may (or may not) be related to using delphi mode declared objects from macpascal mode and
the other way round.


I don't have a simple reproducible case. I welcome advice on how to get there, based on above
observations.

Regards,

Adriaan van Os

-------

On 02 Sep 2008, at 14:30, Adriaan van Os wrote:

 >     [28.068] Recompiling MMyutils0, checksum changed for V7Stuff
 >
 > upon a rebuild for units that haven't changed at all. So, I did the following:

The two main reasons I know of that currently can change the interface crc are
a) calls to inline functions of which only the interface was parsed when the function was called
b) calls to functions which are declared as regular functions in the interface of a unit, but as 
external functions in the implementation

The reason for a) is that the code for inline functions is stored in the unit interface (as it must 
be exported to other units), and for b) is that the assembler symbol name of the function changes 
(the compiler also inserts a code to redirect calls to the old name to the new name, so the first 
compilation will also work).

 > Now, the ppudump_diff.txt file has lines like
 >
 >     @@ -29,7 +29,7 @@
 >      Uses unit: Sglobals (Crc: 207BA0FC, IntfcCrc: 207BA0FC)
 >      Uses unit: MProutil (Crc: 2A51D9C7, IntfcCrc: 875453BF)
 >      Uses unit: InterruptCode (Crc: C36B6157, IntfcCrc: 6D45DAC1)
 >     -Uses unit: V7Stuff (Crc: 942FBF47, IntfcCrc: D85A6EB1)
 >     +Uses unit: V7Stuff (Crc: 42F16682, IntfcCrc: 18B40446)
 >      Uses unit: MMyutils (Crc: DD59B0C2, IntfcCrc: AFB920A0)
 >      Uses unit: MMyutils2 (Crc: 181A1B43, IntfcCrc: ED58FC40)
 >      Uses unit: MMyutils0 (Crc: BF00BD89, IntfcCrc: D4DEB0DA)
 >
 > and even (for some global variables)
 >
 >     @@ -389309,7 +389309,7 @@
 >         SymOptions : Public
 >               Spez : Value
 >            Regable : None
 >     -   Addr Taken : TRUE
 >     +   Addr Taken : FALSE
 >           Var Type : (1761) Unit 0, DefId 19
 >            Options : TypedConst
 >       DefaultConst : (1770) Nil

The addr_taken field is not used in the interface crc calculation, so this shouldn't trigger any 
recompilations or crc changes. I'm not entirely sure how it can change from true to false though 
(except in case of inlining).

 > - the checksum problem may also produce the crash, or at least trigger some unusual state in the 
compiler that wasn't foreseen in the code and then leads to the crash

Probably some kind of circular dependency, but I'm not sure how.

 > - I get the impression that the checksum problem is related to the order of used units in unit 
interface and/or implementation USES clauses

That's certainly possible, as it is possible that depending on the order more or fewer calls occur 
to inline functions whose body is not yet parsed.

 > - this may (or may not) be related to mixing macpascal and delphi modes (the project is a mix 
from an old CodeWarrior version and the PC Delphi version)

That should not have any effect.

 > - this may (or may not) be related to using (or even redefining) types that are different in 
macpascal and delphi modes, like INTEGER or STRING (any advice I give on coding habits is ignored)

That should not make any difference. Using type with the same name from different units can 
sometimes cause confusing compiler messages ("expected typename, but got typename", although it 
should prefix it with the unit name nowadays), but should not have any effects on interface crc's.

 > - this may (or may not) be related to using delphi mode declared objects from macpascal mode and 
the other way round.

Every macpas program that uses objects uses objects declared in delphi/objfpc mode, because the 
basic class (= macpas object) support is implemented using objfpc mode.

 > I don't have a simple reproducible case. I welcome advice on how to get there, based on above 
observations.

If you have inline functions, that would be a good place to start.


Jonas

-------

Jonas Maebe wrote:
 >
 > On 02 Sep 2008, at 14:30, Adriaan van Os wrote:
 >
 >>     [28.068] Recompiling MMyutils0, checksum changed for V7Stuff
 >>
 >> upon a rebuild for units that haven't changed at all. So, I did the following:
 >
 > The two main reasons I know of that currently can change the interface crc are
 > a) calls to inline functions of which only the interface was parsed when the function was called
 > b) calls to functions which are declared as regular functions in the interface of a unit, but as 
external functions in the implementation
 >
 > The reason for a) is that the code for inline functions is stored in the unit interface (as it 
must be exported to other units), and for b) is that the assembler symbol name of the function 
changes (the compiler also inserts a code to redirect calls to the old name to the new name, so the 
first compilation will also work).

Thanks for your reply.

I went so far as to remove all inline directives, as well as all external directives from 
implementation parts. Unfortunately, the compiler problems remain. So, I suspect it's a checksum 
calculation bug.

 >> I don't have a simple reproducible case. I welcome advice on how to get there, based on above 
observations.
 >
 > If you have inline functions, that would be a good place to start.

Any more ideas ?

Regards,

Adriaan van Os

-------

On 02 Sep 2008, at 18:02, Adriaan van Os wrote:

 > Jonas Maebe wrote:
 >> On 02 Sep 2008, at 14:30, Adriaan van Os wrote:
 >>>    [28.068] Recompiling MMyutils0, checksum changed for V7Stuff
 >>>
 >>> upon a rebuild for units that haven't changed at all. So, I did the following:
 >> The two main reasons I know of that currently can change the interface crc are
 >> a) calls to inline functions of which only the interface was parsed when the function was called
 >> b) calls to functions which are declared as regular functions in the interface of a unit, but 
as external functions in the implementation
 >> The reason for a) is that the code for inline functions is stored in the unit interface (as it 
must be exported to other units), and for b) is that the assembler symbol name of the function 
changes (the compiler also inserts a code to redirect calls to the old name to the new name, so the 
first compilation will also work).
 >
 > Thanks for your reply.
 >
 > I went so far as to remove all inline directives, as well as all external directives from 
implementation parts. Unfortunately, the compiler problems remain. So, I suspect it's a checksum 
calculation bug.

More likely is that there is at least yet one more way to change the interface checksum in the 
implementation. Unfortunately, I've never heard of any. I've also never before debugged this kind 
of problem (Peter Vreman has quite some experience with it, but he's not on this list; maybe 
Florian also?), so I can't give any specific pointers on how to tackle this either.

Sorry.


Jonas




More information about the fpc-devel mailing list