Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2002-06

Another problem with fpc v1.1

6 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Sergey Korshunoff

Hi!

There is another problem with fpc v1.1
It is exposed (under Linux) when you add a cmem.pp into pp.pas ( Uses cmem, ...)

And you must add the following lines to parser.pas

              orgpattern:=oldorgpattern;
              token:=oldtoken;
              idtoken:=oldidtoken;
              akttokenpos:=oldtokenpos;
              block_type:=old_block_type;
              current_scanner:=oldcurrent_scanner;
+              if current_scanner.inputfile.name = nil then
+                WriteLn(StdErr,'AAAAAAAAAAAAAAAAAAa') else
+                WriteLn(StdErr,'AAA:',current_scanner.inputfile.name^);
              parser_current_file:=current_scanner.inputfile.name^;
              { restore cg }
              nextlabelnr:=oldnextlabelnr;
              parse_only:=oldparse_only;
              { restore asmlists }

Look for output. For me it is like this:
AAA:cpuasm.pas
AAA:assemble.pas
AAA:ag386att.pas
AAA:ag386att.pas
AAA:cpuasm.pas
AAA:symsym.pas
AAA:symdef.pas
AAA:symdef.pas
AAA:f─═/НW@ GETTYPEDEF╝°
AAA:browlog.pas
AAA:compiler.pas
AAA:compiler.pas
AAA:parser.pas

A strange names appears only when we use cmem. And not always in the same place. But definitely there is an error somewhere (I always get an error building fp with such compiler). Because fpc v1.0 do not have any problem with cmem then error is in fpc v1.1 (not in cmem).

Regards,
Sergey Korshunoff

PS: My version of cmem.pp is quite different from standard one (there is no FreeMem() function in the interface part in my version of cmem)

Reply by email

Sergey Korshunoff

About the story...

Sergey Korshunoff wrote 42 lines
There is another problem with fpc v1.1 It is exposed (under Linux) when you add a cmem.pp into pp.pas ( Uses cmem, ...) And you must add the following lines to parser.pas orgpattern:=oldorgpattern; token:=oldtoken; idtoken:=oldidtoken; akttokenpos:=oldtokenpos; block_type:=old_block_type; current_scanner:=oldcurrent_scanner; + if current_scanner.inputfile.name = nil then + WriteLn(StdErr,'AAAAAAAAAAAAAAAAAAa') else + WriteLn(StdErr,'AAA:',current_scanner.inputfile.name^); parser_current_file:=current_scanner.inputfile.name^; { restore cg } nextlabelnr:=oldnextlabelnr; parse_only:=oldparse_only; { restore asmlists } Look for output. For me it is like this: AAA:cpuasm.pas AAA:assemble.pas AAA:ag386att.pas AAA:ag386att.pas AAA:cpuasm.pas AAA:symsym.pas AAA:symdef.pas AAA:symdef.pas AAA:f─═/НW@ GETTYPEDEF╝° AAA:browlog.pas AAA:compiler.pas AAA:compiler.pas AAA:parser.pas A strange names appears only when we use cmem. And not always in the same place. But definitely there is an error somewhere (I always get an error building fp with such compiler). Because fpc v1.0 do not have any problem with cmem then error is in fpc v1.1 (not in cmem).

I found (after testing) that the same problem go out when You change 512 to 352 (and below) in maxblocksize definition (rtl/inc/heap.inc). In such case You can not build fpc v1.1 too.

There is defenitely some wrong memory reference which destroys sometimes tinputfile.name and tinputfile.path. But You can not catch it with heaptrc. And I did not catch bounds overrides even with ElectroFence library (I uses cmem with reference to libefence.so insteed of libc.so). So this override is only inside valid memory block (and not outside).

Currendtly I do not work under Win32 -> I can not use TurboDebugger to catch a change of tinputfile.name when we compile a pp.pas. Can someone (who work under Win32) to try this? Can a gdb to use i386 hardware to catch memory change?

Regards,
Sergey Korshunoff

Reply by email

Jonas Maebe
to Sergey Korshunoff
Sergey Korshunoff wrote
Currendtly I do not work under Win32 -> I can not use TurboDebugger to catch a change of tinputfile.name when we compile a pp.pas. Can someone (who work under Win32) to try this? Can a gdb to use i386 hardware to catch memory change?

Yes. First you need to get the address of the (max 4 bytes large) value you want to watch:

p @<expression>

Next, add a watchpoint:

watch plongint(0x<address from previous command>)^

If you use the expression directly, you get all sorts of trouble when some part of it goes out of scope. Use "awatch" instead of "watch" if you also want to break on reads.

Jonas

Reply by email

Sergey Korshunoff

I found only one answer for the problem.
About the story again...

Show quoted text 47 lines
20 June 2002 04:14, Sergey Korshunoff wrote: > There is another problem with fpc v1.1 > It is exposed (under Linux) when you add a cmem.pp into pp.pas > ( Uses cmem, ...) > > And you must add the following lines to parser.pas > > orgpattern:=oldorgpattern; > token:=oldtoken; > idtoken:=oldidtoken; > akttokenpos:=oldtokenpos; > block_type:=old_block_type; > current_scanner:=oldcurrent_scanner; > + if current_scanner.inputfile.name = nil then > + WriteLn(StdErr,'AAAAAAAAAAAAAAAAAAa') else > + WriteLn(StdErr,'AAA:',current_scanner.inputfile.name^); > > parser_current_file:=current_scanner.inputfile.name^; > { restore cg } > nextlabelnr:=oldnextlabelnr; > parse_only:=oldparse_only; > { restore asmlists } > > Look for output. For me it is like this: > AAA:cpuasm.pas > AAA:assemble.pas > AAA:ag386att.pas > AAA:ag386att.pas > AAA:cpuasm.pas > AAA:symsym.pas > AAA:symdef.pas > AAA:symdef.pas > AAA:f─═/НW@ GETTYPEDEF╝° > AAA:browlog.pas > AAA:compiler.pas > AAA:compiler.pas > AAA:parser.pas > > A strange names appears only when we use cmem. And not > always in the same place. But definitely there is an error > somewhere (I always get an error building fp with such compiler). Because > fpc v1.0 do not have any problem with cmem then error is in fpc v1.1 (not > in cmem). I found (after testing) that the same problem go out when You change 512 to 352 (and below) in maxblocksize definition (rtl/inc/heap.inc). In such case You can not build fpc v1.1 too.

My answer: fpc v1.1 use a stack of modules which must be compiled (may be as a local variables in parser.pas). Sometimes this dynamic variable is destoryed ( aTInputFileVar.Free is executed), but it is keept in stack and fpc v1.1 go to use this already invalid reference.

Why we can not see a problem in standard configuration? there is a _big_ chance (for a standard heap.inc realization) that a freed block is used again for the same type of variable

I think we can raise this error too by increasing a blocksize value in heap.inc

What I found with fpc v1.1 made with

     maxblocksize := 304 + blocksize;

in rtl/inc/heap.inc.

I use the following commands:
rm *.o *.ppu # it is important !!!
gdb ./ppc1

set args -Fui386 -Futargtes b main b finput.pas:174 r

...

For me ppc1 go out in modified parser.pas when it
is executing

  WriteLn(StdErr, "AAA: ", current_scanner.inputfile.name^);

for inpufile "symtable.pas". But this instance of
tinputfile was destoryed before. After this
there was created a new instance of
the tinputfile('symtable.pas'), but
fpc go to use an old one too.

Here is a backtrace for point where
a first instance of tinputfile("symtable.pas")
was destoryed:

(www is a static var in fpinput.pas,
which holds an adress of tinputfile.name='symtable.pas')

Hardware watchpoint 7: WWW^

Old value = 1078932964
New value = 0
STRINGDISPOSE (P=$0) at cutils.pas:620
620 end;
(gdb) bt
#0 STRINGDISPOSE (P=$0) at cutils.pas:620
#1 $0810d3bb in TINPUTFILE__DESTROY (this=$40580254) at finput.pas:210 #2 $08126b8f in TOBJECT__FREE (this=$40580254) at objpas.inc:128 #3 $0810da92 in TINPUTFILEMANAGER__DESTROY (this=$401ace94) at finput.pas:525 #4 $08126b8f in TOBJECT__FREE (this=$401ace94) at objpas.inc:128 #5 $0810a689 in TMODULE__RESET (this=$40580184) at fmodule.pas:498 #6 $080d24e5 in TPPUMODULE__RESET (this=$40580184) at fppu.pas:123 #7 $080d47e3 in LOADUNIT (S='symtable', FN='') at fppu.pas:1110 #8 $080971dd in LOADUNITS () at pmodules.pas:454
#9 $080976b7 in PARSE_IMPLEMENTATION_USES (SYMT=$40659434) at pmodules.pas:582
#10 $0809806d in PROC_UNIT () at pmodules.pas:881
#11 $080d50cd in COMPILE (FILENAME='symsym.pas') at parser.pas:453 #12 $080d4587 in TPPUMODULE__LOADPPU (this=$4067e2b4) at fppu.pas:1012 #13 $080d4886 in LOADUNIT (S='symsym', FN='') at fppu.pas:1138 #14 $080971dd in LOADUNITS () at pmodules.pas:454
#15 $080976b7 in PARSE_IMPLEMENTATION_USES (SYMT=$4057a6c4) at pmodules.pas:582
#16 $0809806d in PROC_UNIT () at pmodules.pas:881
#17 $080d50cd in COMPILE (FILENAME='symdef.pas') at parser.pas:453 #18 $080d4587 in TPPUMODULE__LOADPPU (this=$4060dda4) at fppu.pas:1012 #19 $080d4886 in LOADUNIT (S='symdef', FN='') at fppu.pas:1138 #20 $080971dd in LOADUNITS () at pmodules.pas:454
#21 $08097ee6 in PROC_UNIT () at pmodules.pas:804
#22 $080d50cd in COMPILE (FILENAME='symtable.pas') at parser.pas:453 #23 $080d4587 in TPPUMODULE__LOADPPU (this=$40580184) at fppu.pas:1012 #24 $080d4886 in LOADUNIT (S='symtable', FN='') at fppu.pas:1138 #25 $080971dd in LOADUNITS () at pmodules.pas:454
#26 $080976b7 in PARSE_IMPLEMENTATION_USES (SYMT=$405df684) at pmodules.pas:582
#27 $0809806d in PROC_UNIT () at pmodules.pas:881
#28 $080d50cd in COMPILE (FILENAME='parser.pas') at parser.pas:453 #29 $080d4587 in TPPUMODULE__LOADPPU (this=$40586694) at fppu.pas:1012 #30 $080d4886 in LOADUNIT (S='parser', FN='') at fppu.pas:1138 #31 $080971dd in LOADUNITS () at pmodules.pas:454
#32 $08097ee6 in PROC_UNIT () at pmodules.pas:804
#33 $080d50cd in COMPILE (FILENAME='compiler.pas') at parser.pas:453 #34 $080d4587 in TPPUMODULE__LOADPPU (this=$817e144) at fppu.pas:1012 #35 $080d4886 in LOADUNIT (S='compiler', FN='') at fppu.pas:1138 #36 $080971dd in LOADUNITS () at pmodules.pas:454
#37 $08098b43 in PROC_PROGRAM (ISLIBRARY=false) at pmodules.pas:1218 #38 $080d50df in COMPILE (FILENAME='pp.pas') at parser.pas:456 #39 $0810c048 in COMPILE (CMD='') at compiler.pas:295 #40 $0812e218 in main () at pp.pas:172
(gdb) q

Sorry, but I can not fix this error because I do not understand a PPU-loading scheme.

Regards,
Sergey Korshunoff

Reply by email

Jonas Maebe
to Sergey Korshunoff
Sergey Korshunoff wrote 16 lines
My answer: fpc v1.1 use a stack of modules which must be compiled (may be as a local variables in parser.pas). Sometimes this dynamic variable is destoryed ( aTInputFileVar.Free is executed), but it is keept in stack and fpc v1.1 go to use this already invalid reference. Why we can not see a problem in standard configuration? there is a _big_ chance (for a standard heap.inc realization) that a freed block is used again for the same type of variable I think we can raise this error too by increasing a blocksize value in heap.inc What I found with fpc v1.1 made with maxblocksize := 304 + blocksize; in rtl/inc/heap.inc.

With this change, I can also reproduce it easily. The problem is that the tinputfile of a unit is both stored in the tppumodule and in the tscannerfile of a unit. So in the function loadunit in fppu.pas line 1109-1111 are wrong:

                scanner:=tscannerfile(hp.scanner);
                hp.reset;
                hp.scanner:=scanner;

The reset destroys the tinputfile of the tppumodule (it's in the sourcefiles list of tmodule, which is reset by tmodule.reset, which is called by tppumodule.reset), but this same tinputfile is still assigned to the inputfile field of the scanner and reused! Peter, can you have a look at this?

Jonas

Reply by email

Peter Vreman
Show quoted text 34 lines
On zaterdag, juni 29, 2002, at 02:02 , Sergey Korshunoff wrote: > My answer: fpc v1.1 use a stack of modules which must be compiled > (may be as a local variables in parser.pas). Sometimes > this dynamic variable is destoryed ( aTInputFileVar.Free is executed), > but it is keept in stack and fpc v1.1 go to use this already invalid > reference. > > Why we can not see a problem in standard configuration? > there is a _big_ chance (for a standard heap.inc realization) that > a freed block is used again for the same type of variable > > I think we can raise this error too by increasing a blocksize value in > heap.inc > > What I found with fpc v1.1 made with > maxblocksize := 304 + blocksize; > in rtl/inc/heap.inc. With this change, I can also reproduce it easily. The problem is that the tinputfile of a unit is both stored in the tppumodule and in the tscannerfile of a unit. So in the function loadunit in fppu.pas line 1109-1111 are wrong: scanner:=tscannerfile(hp.scanner); hp.reset; hp.scanner:=scanner; The reset destroys the tinputfile of the tppumodule (it's in the sourcefiles list of tmodule, which is reset by tmodule.reset, which is called by tppumodule.reset), but this same tinputfile is still assigned to the inputfile field of the scanner and reused! Peter, can you have a look at this?

Not soon. I just heard that i've to leave for work to Ireland tomorrow, so i've to pack and arrange things.

Reply by email