Hi !
I am using a Mac OS X 10.6.8. I have downloaded GNU Pascal for Mac Os fromhttp://www.microbizz.nl/gpc.html. I have been using GNU Pascal for writing very simple programs for an introductory programming course and it worked fine until I wrote the following program for which I got a "bus error" when writing a first record in the file (at line 128). Notice that the program executes without errors when compiled with free pascal compiler.
I should be happy if anyone can help me to solve this "problem".
Baudouin Le Charlier
Le 17/11/2012 16:13, Baudouin Le Charlier a écrit :
I am using a Mac OS X 10.6.8. I have downloaded GNU Pascal for Mac Os fromhttp://www.microbizz.nl/gpc.html. I have been using GNU Pascal for writing very simple programs for an introductory programming course and it worked fine until I wrote the following program for which I got a "bus error" when writing a first record in the file (at line 128). Notice that the program executes without errors when compiled with free pascal compiler.
It works also with old BP ! I find the same error (SIGSEGV) under DJGPP, MingW and Linux 64bits Seems to be a serious bug of GPC. Incidentally, when investigating with GDB, I found that the two variants of the record "personne" are consecutive instead of sharing the same placein memory, and the SizeOf(p) = 844 for a 32 bits system is consistent with that. It is indeed said in the docs that place sharing is not mandatory, but I have used this very frequently in the past !
Maurice
Le 17/11/2012 16:13, Baudouin Le Charlier a =E9crit :
I am using a Mac OS X 10.6.8. I have downloaded GNU Pascal for Mac Os f=
romhttp://www.microbizz.nl/gpc.html. I have been using GNU Pascal for writi= ng very simple programs for an introductory programming course and it worke= d fine until I wrote the following program for which I got a "bus error" wh= en writing a first record in the file (at line 128). Notice that the progra= m executes without errors when compiled with free pascal compiler.
It works also with old BP ! I find the same error (SIGSEGV) under DJGPP, MingW and Linux 64bits Seems to be a serious bug of GPC.
Hmm, quick test with Debian gpc did not produce a crash. It certainly would help to have example without a lot of interaction.
Here is a very simple example where the bus error occurs :
I executed the following commands :
Soeur-Sourire:Cours17 blc$ gp busError.pas Soeur-Sourire:Cours17 blc$ ./busError Bus error Soeur-Sourire:Cours17 blc$
After executing the program, the file toto.pers exists and is empty (Zero bytes).
Baudouin
Le 18 nov. 2012 à 02:44, Waldek Hebisch a écrit :
Le 17/11/2012 16:13, Baudouin Le Charlier a =E9crit :
I am using a Mac OS X 10.6.8. I have downloaded GNU Pascal for Mac Os f=
romhttp://www.microbizz.nl/gpc.html. I have been using GNU Pascal for writi= ng very simple programs for an introductory programming course and it worke= d fine until I wrote the following program for which I got a "bus error" wh= en writing a first record in the file (at line 128). Notice that the progra= m executes without errors when compiled with free pascal compiler.
It works also with old BP ! I find the same error (SIGSEGV) under DJGPP, MingW and Linux 64bits Seems to be a serious bug of GPC.
Hmm, quick test with Debian gpc did not produce a crash. It certainly would help to have example without a lot of interaction.
-- Waldek Hebisch hebisch@math.uni.wroc.pl
Gpc mailing list Gpc@gnu.de https://www.g-n-u.de/mailman/listinfo/gpc
Le 18/11/2012 10:16, Baudouin Le Charlier a écrit :
Here is a very simple example where the bus error occurs : Le 18 nov. 2012 à 02:44, Waldek Hebisch a écrit :
Hmm, quick test with Debian gpc did not produce a crash. It certainly
would help to have example without a lot of interaction.
with busError.pas ======================================================= On fedora core 6
[lombardi@lobelie ~/gpc/bugCharlier]$ gpc -v Reading specs from /usr/local/lib/gcc/x86_64-redhat-linux/3.4.4/specs Configured with: ../gcc-3.4.4-20050721/configure --disable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,pascal --enable-multilib --host=x86_64-redhat-linux Thread model: posix gpc version 20070904, based on gcc-3.4.4 20050721 (Red Hat 3.4.4-2) [lombardi@lobelie ~/gpc/bugCharlier]$ gp --version GP version 0.61 (GNU Pascal Make Utility) ... [lombardi@lobelie ~/gpc/bugCharlier]$ gp busError.pas [lombardi@lobelie ~/gpc/bugCharlier]$ ./busError Segmentation fault
========================================================= on MingW with DrMingw for JIT debug (understands only stabs)
Maurice@bouvardie ~/gpc/bugCharlier $ gpc -v Reading specs from C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/specs Configured with: ../gcc-3.4.5-20060117-2/configure --with-gcc --with-gnu-ld --wi th-gnu-as --host=mingw32 --target=mingw32 --prefix=/mingw --enable-threads --dis able-nls --enable-languages=c,pascal --disable-win32-registry --disable-shared - -enable-sjlj-exceptions --enable-libgcj --disable-java-awt --without-x --enable- java-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchron ization --enable-libstdcxx-debug Thread model: win32 gpc version 20070904, based on gcc-3.4.5 (mingw-vista special r3)
Maurice@bouvardie ~/gpc/bugCharlier $ gp --version GP version 0-61 (GNU Pascal Make Utility)
Maurice@bouvardie ~/gpc/bugCharlier $ gp busError -gstabs+
Maurice@bouvardie ~/gpc/bugCharlier $ busError
DrMingw pops up with message
............. busError.exe caused an Access Violation at location 0040139d in module busError.exe Reading from location 00000594.
Registers: eax=80000000 ebx=7ffdc000 ecx=00000000 edx=00000304 esi=00432009 edi=0023ff11 eip=0040139d esp=0023feb0 ebp=0023ff28 iopl=0 nv up ei pl zr na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
Call stack: AddrPC AddrReturn AddrFrame AddrStack Params 0040139D 004016C0 0023FF28 0023FEB0 00000001 00032C00 00032F20 00000000 0040139D busError.exe:0040139D _p__M0_main_program buserror.pas:28 Void _p__M0_main_program( ) ... begin assign(f, 'toto.pers') ;
rewrite(f) ;
write(f, p) ; close(f) ...
004016C0 004010FD 0023FF58 0023FEB0 00000001 00032C00 00032F20 00437000 004016C0 busError.exe:004016C0 main <implicit code>:31 int32 main( int32 argc = 1, Cstring * argv = &0x00032bb9, Cstring * envp = &0x00032ff0 ) 004010FD 00000000 0023FFF0 0023FEB0 00401280 00000000 78746341 00000020 004010FD busError.exe:004010FDc:\Lombardi\mingw\gpc\bugCharlier\busError.exe: No symbol found
.................
Maurice
On 18 Nov 2012 at 10:16, Baudouin Le Charlier wrote:
Here is a very simple example where the bus error occurs :
I executed the following commands :
Soeur-Sourire:Cours17 blc$ gp busError.pas Soeur-Sourire:Cours17 blc$ ./busError Bus error Soeur-Sourire:Cours17 blc$
After executing the program, the file toto.pers exists and is empty (Zero bytes).
Apart from the fact that nothing in the record is initialialised, this is the offending statement: case sexe : boolean of true : (nomDeJeuneFille : string80) ; false : (matricule : string10)
What I am about to say may simply expose my ignorance - but I will say it anyway. I am no compiler writer, and I don't use variant records myself - but, from where I am standing, I am at a loss to know what the size of the "personne" record is. "nomDeJeuneFille" and "matricule" are supposed to occupy the same location, but they are not the same size. So what data size is the "file of personne" expecting? Data that will vary in size depending on a value that is not known at compile time? Is this allowed?
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Le 18 nov. 2012 à 16:18, Prof A Olowofoyeku (The African Chief) a écrit :
On 18 Nov 2012 at 10:16, Baudouin Le Charlier wrote:
Here is a very simple example where the bus error occurs :
I executed the following commands :
Soeur-Sourire:Cours17 blc$ gp busError.pas Soeur-Sourire:Cours17 blc$ ./busError Bus error Soeur-Sourire:Cours17 blc$
After executing the program, the file toto.pers exists and is empty (Zero bytes).
Apart from the fact that nothing in the record is initialialised, this is the offending statement: case sexe : boolean of true : (nomDeJeuneFille : string80) ; false : (matricule : string10)
What I am about to say may simply expose my ignorance - but I will say it anyway. I am no compiler writer, and I don't use variant records myself - but, from where I am standing, I am at a loss to know what the size of the "personne" record is. "nomDeJeuneFille" and "matricule" are supposed to occupy the same location, but they are not the same size. So what data size is the "file of personne" expecting? Data that will vary in size depending on a value that is not known at compile time? Is this allowed?
Dear Chief,
It's a great joy to have a chance to discuss with you thanks to a "bus error". To my understanding the size of the "personne" record is completely implementation dependent. But this should not cause an error when writing the record into a file. Of course a "file of personne" created with gnu pascal is not supposed to be readable with any other pascal implementation. The reason why I did not bother to initialize the record is just to shorten the original program to simplify debugging.
Baudouin Le Charlier
Best regards, The Chief
Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
The following program is completely equivalent to the previous one but it executes without errors. (Thanks Chief !)
Baudouin Le Charlier
Le 18 nov. 2012 à 16:18, Prof A Olowofoyeku (The African Chief) a écrit :
On 18 Nov 2012 at 10:16, Baudouin Le Charlier wrote:
Here is a very simple example where the bus error occurs :
I executed the following commands :
Soeur-Sourire:Cours17 blc$ gp busError.pas Soeur-Sourire:Cours17 blc$ ./busError Bus error Soeur-Sourire:Cours17 blc$
After executing the program, the file toto.pers exists and is empty (Zero bytes).
Apart from the fact that nothing in the record is initialialised, this is the offending statement: case sexe : boolean of true : (nomDeJeuneFille : string80) ; false : (matricule : string10)
What I am about to say may simply expose my ignorance - but I will say it anyway. I am no compiler writer, and I don't use variant records myself - but, from where I am standing, I am at a loss to know what the size of the "personne" record is. "nomDeJeuneFille" and "matricule" are supposed to occupy the same location, but they are not the same size. So what data size is the "file of personne" expecting? Data that will vary in size depending on a value that is not known at compile time? Is this allowed?
Best regards, The Chief
Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Le 18/11/2012 16:40, Baudouin Le Charlier a écrit :
The following program is completely equivalent to the previous one but it executes without errors. (Thanks Chief !)
Baudouin Le Charlier
Yes, but this is a workaround, not a solution. The two syntaxes are equally valid in pascal. If I add the instructions
writeln(SizeOf(p)); writeln(SizeOf(f^));
between rewrite(f); and write(f,p)
noBugError answers
772 772
the result expected if the two variants are consecutive
BusError answers only
772
and launches the error. A little experimenting with commenting instructions out shows that the instruction writeln(SizeOf(f^)); alone is enough to launch the interrupt
Maurice
On 18 Nov 2012 at 17:39, Maurice Lombardi wrote:
Le 18/11/2012 16:40, Baudouin Le Charlier a écrit :
The following program is completely equivalent to the previous one but it executes without errors. (Thanks Chief !)
Baudouin Le Charlier
Yes, but this is a workaround, not a solution. The two syntaxes are equally valid in pascal. If I add the instructions
writeln(SizeOf(p)); writeln(SizeOf(f^));
between rewrite(f); and write(f,p)
noBugError answers
772 772
the result expected if the two variants are consecutive
BusError answers only
772
and launches the error. A little experimenting with commenting instructions out shows that the instruction writeln(SizeOf(f^)); alone is enough to launch the interrupt
Perhaps it's a bug in the compiler. The original code compiles and runs okay when compiled with Delphi 7 and Virtual Pascal.
It also runs okay if you declare "sexe" like this; case sexe : boolean of false : (nomDeJeuneFille : string80) ; true : (matricule : string10)
( i.e., false (0) *before* true (1) ). Should the order be significant? In this case it seems to be - which (depending on the answer to my question) is either a compiler bug, or programmer error. Over to those who know what the standards require ....
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Le 18 nov. 2012 à 19:00, Prof A Olowofoyeku (The African Chief) a écrit :
On 18 Nov 2012 at 17:39, Maurice Lombardi wrote:
Le 18/11/2012 16:40, Baudouin Le Charlier a écrit :
The following program is completely equivalent to the previous one but it executes without errors. (Thanks Chief !)
Baudouin Le Charlier
Yes, but this is a workaround, not a solution. The two syntaxes are equally valid in pascal. If I add the instructions
writeln(SizeOf(p)); writeln(SizeOf(f^));
between rewrite(f); and write(f,p)
noBugError answers
772 772
the result expected if the two variants are consecutive
BusError answers only
772
and launches the error. A little experimenting with commenting instructions out shows that the instruction writeln(SizeOf(f^)); alone is enough to launch the interrupt
Perhaps it's a bug in the compiler. The original code compiles and runs okay when compiled with Delphi 7 and Virtual Pascal.
It also runs okay if you declare "sexe" like this; case sexe : boolean of false : (nomDeJeuneFille : string80) ; true : (matricule : string10)
( i.e., false (0) *before* true (1) ). Should the order be significant?
To my knowledge, the constant false and true are pure comments in this construct and they should not be used in any way by the compiler to generate code. The compiler should (at best) only check that they are constant of boolean type and that no repetition of the same constant occurs.
Baudouin
In this case it seems to be - which (depending on the answer to my question) is either a compiler bug, or programmer error. Over to those who know what the standards require ....
Best regards, The Chief
Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Gpc mailing list Gpc@gnu.de https://www.g-n-u.de/mailman/listinfo/gpc
Hi everybody,
I am trying to understand how to use {$I-} , {$I+} , and ioResult to check IO errors with text files. Il do not understand the following points.
It seems that {$I-} is not enough to disable the automatic handling of IO errors. You also have to actually write a call to ioResult in the program. Seems to me that this is not a correct behaviour. Moreover I do not understand how it is simply possible to have such a behaviour without using a kind of static analysis of the code. I join some files to show the problem.
Thanks for your sharing your knowledge of {$I-} , {$I+} , and ioResult.
Baudouin
this program reads the file "toto.txt" without calling ioResult.
the same program with calls to ioResult
the file that is read by the program
execution of lireToto compiled with {$I-}
execution of lireToto compiled with {$I+}
execution of lireToto_ioResult compiled with {$I-}
execution of lireToto_ioResult compiled with {$I+}
On 25 Nov 2012 at 12:13, Baudouin Le Charlier wrote:
It seems that {$I-} is not enough to disable the automatic handling of IO errors.
I doesn't disable error checking. It just stops it from automatically terminating the program immediately it encounters an I/O error. But you must check IOResult, to see whether there is an error, and so handle the error yourself (or ignore the error), but, crucially, to clear the error flag.
You also have to actually write a call to ioResult in the program. Seems to me that this is not a correct behaviour.
It is the correct behaviour. What is the point of preventing I/O errors from terminating the program if you will not check to see whether there has been an error? Just allow the program to keep running and keep generating errors that no-one is interested in checking?
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Le 25 nov. 2012 à 15:13, Prof A Olowofoyeku (The African Chief) a écrit :
On 25 Nov 2012 at 12:13, Baudouin Le Charlier wrote:
It seems that {$I-} is not enough to disable the automatic handling of IO errors.
I doesn't disable error checking. It just stops it from automatically terminating the program immediately it encounters an I/O error.
That's what I finally guessed but not what was explained in the documentation I could find.
But you must check IOResult, to see whether there is an error, and so handle the error yourself (or ignore the error), but, crucially, to clear the error flag.
That also was not clearly stated in the documentation. It was said that ioResult checks what happened during the last IO operation not that you have to call ioResult to clear the error flag. Why not to update the error flag afresh each time an IO operation is performed ?
You also have to actually write a call to ioResult in the program. Seems to me that this is not a correct behaviour.
It is the correct behaviour. What is the point of preventing I/O errors from terminating the program if you will not check to see whether there has been an error? Just allow the program to keep running and keep generating errors that no-one is interested in checking?
Yes, this can be perfectly meaningful in cases where you cannot correct the error but you need to continue executing the program for more important or simply other purposes.
Anyway, more importantly, can you explain why the fact of calling ioResult *after* the erroneous IO operation prevents abnormal termination while not calling ioResult *with {$I-} enabled* does not prevent it ? I do not understand how that is possible unless some kind of static analysis of the program is done at compile time.
Thanks,
Baudouin
Le 25 nov. 2012 à 15:13, Prof A Olowofoyeku (The African Chief) a écrit :
On 25 Nov 2012 at 12:13, Baudouin Le Charlier wrote:
It seems that {$I-} is not enough to disable the automatic handling of IO errors.
I doesn't disable error checking. It just stops it from automatically terminating the program immediately it encounters an I/O error.
Well, in fact, it does not stop it : (compiled with {$I-})
$ gp lireToto.pas $ ./lireToto c = a ; ord(c) = 97 i = -12 s = lulu x = 1.345000000000000e+00 c = ; ord(c) = 32 x = 1.000000000000000e+00 s = a ./lireToto: attempt to read past end of file `toto.txt' (error #454 at 1f53) Trace/BPT trap $ more toto.txt a -12lulu
1.345 45 1a $
Baudouin Le Charlier
On 25 Nov 2012 at 16:41, Baudouin Le Charlier wrote:
Le 25 nov. 2012 à 15:13, Prof A Olowofoyeku (The African Chief) a écrit :
On 25 Nov 2012 at 12:13, Baudouin Le Charlier wrote:
It seems that {$I-} is not enough to disable the automatic handling of IO errors.
I doesn't disable error checking. It just stops it from automatically terminating the program immediately it encounters an I/O error.
Well, in fact, it does not stop it : (compiled with {$I-})
$ gp lireToto.pas
Perhaps if you reduced the code to 3 or 4 lines, one might find it easier to follow?
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
On 25 Nov 2012 at 16:31, Baudouin Le Charlier wrote:
Le 25 nov. 2012 à 15:13, Prof A Olowofoyeku (The African Chief) a écrit :
On 25 Nov 2012 at 12:13, Baudouin Le Charlier wrote:
It seems that {$I-} is not enough to disable the automatic handling of IO errors.
I doesn't disable error checking. It just stops it from automatically terminating the program immediately it encounters an I/O error.
That's what I finally guessed but not what was explained in the documentation I could find.
IOResult and {$I-/+} are Borland Pascal/Delphi compatibility issues. It stands to reason that expect that anyone who wants to use non-standard features (i.e., Borland Pascal/Delphi features) would have sufficient knowledge of Borland Pascal/Delphi to appreciate how those features are meant to be used.
This is a historical factor, and there was no need to duplicate features that Borland already documented well, and which were well known to Borland Pascal/Delphi programmers.
Perhaps someone should now duplicate that information - but I doubt whether it would be a sensible use of anyone's time. Just find the Borland Pascal and Delphi help files (freely available on the net), and you would find full documentation of these features. Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Le 25 nov. 2012 à 21:51, Prof A Olowofoyeku (The African Chief) a écrit :
On 25 Nov 2012 at 16:31, Baudouin Le Charlier wrote:
Le 25 nov. 2012 à 15:13, Prof A Olowofoyeku (The African Chief) a écrit :
On 25 Nov 2012 at 12:13, Baudouin Le Charlier wrote:
It seems that {$I-} is not enough to disable the automatic handling of IO errors.
I doesn't disable error checking. It just stops it from automatically terminating the program immediately it encounters an I/O error.
That's what I finally guessed but not what was explained in the documentation I could find.
IOResult and {$I-/+} are Borland Pascal/Delphi compatibility issues. It stands to reason that expect that anyone who wants to use non-standard features (i.e., Borland Pascal/Delphi features) would have sufficient knowledge of Borland Pascal/Delphi to appreciate how those features are meant to be used.
What are the standard features ? To me the standard features are just the original definition of files in Pascal given in Jensen and Wirth's book but they are incomplete and an actual implementation needs additional conventions.
This is a historical factor, and there was no need to duplicate features that Borland already documented well, and which were well known to Borland Pascal/Delphi programmers.
I am not sure they are so well known since you did not explain to me why (i.e. by which miracle) a program that stops abruptly (when compiled with $I-), stops normally if you add a call to ioResult *after* the io statement that makes the original program fail. I doubt very much that this could be explained in the original Borland documentation and also that this behavior should be well known of Borland Pascal programmers.
Best regards,
Baudouin
Perhaps someone should now duplicate that information - but I doubt whether it would be a sensible use of anyone's time. Just find the Borland Pascal and Delphi help files (freely available on the net), and you would find full documentation of these features. Best regards, The Chief
Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Gpc mailing list Gpc@gnu.de https://www.g-n-u.de/mailman/listinfo/gpc
On 26 Nov 2012 at 9:10, Baudouin Le Charlier wrote:
[...]
This is a historical factor, and there was no need to duplicate features that Borland already documented well, and which were well known to Borland Pascal/Delphi programmers.
I am not sure they are so well known since you did not explain to me why (i.e. by which miracle) a program that stops abruptly (when compiled with $I-), stops normally if you add a call to ioResult *after* the io statement that makes the original program fail. I doubt very much that this could be explained in the original Borland documentation and also that this behavior should be well known of Borland Pascal programmers.
As I said, the Borland Pascal/Delphi help files are freely available on the net. If you want to use Borland Pascal/Delphi compatibility features in GPC, you would do well to study the Borland documentation on those features.
This is from a 20 year old Borland Turbo Pascal help file:
[--- excerpt begins ---] $I: Input/Output-Checking Switch Enables or disables the automatic code generation that checks the result of a call to an I/O procedure
Syntax: $I+ or $I- Default: $I+ Type: Local Command-Line: /$I+ or /$I- Menu Command: Options|Compiler|I/O Checking
Remarks If an I/O procedure returns a non-zero I/O result when the $I switch is on, the program terminates, displaying a run-time error message.
When the $I switch is off, you must use the IOResult function to check for I/O errors. [--- excerpt ends ---]
Please let us stop this meaningless debate now. You would be far better off studying the Borland documentation. Should you think that this documentation really needs to be reproduced in the GPC documentation, please feel free to contribute the required documentation.
Best regards, The Chief ------- Prof. Abimbola Olowofoyeku (The African Chief) Web: http://www.greatchief.plus.com
Prof. A Olowofoyeku (The African Chief) wrote:
On 26 Nov 2012 at 9:10, Baudouin Le Charlier wrote:
[...]
This is a historical factor, and there was no need to duplicate features that Borland already documented well, and which were well known to Borland Pascal/Delphi programmers.
The historical facts are different. IOResult and {$I+/-} are an UCSD-Pascal feature, invented well before Turbo Pascal. Histoirical documentation is attached.
Regards,
Adriaan van Os