Folks:
I discovered a program that crashes the GPC compiler, attached.
Regards,
Tom
Thomas D. Schneider, Ph.D. Senior Investigator National Institutes of Health National Cancer Institute Frederick National Laboratory for Cancer Research Gene Regulation and Chromosome Biology Laboratory Molecular Information Theory Group Frederick, Maryland 21702-1201 schneidt@mail.nih.gov http://alum.mit.edu/www/toms
On 17 Feb 2013 at 2:17, Thomas Schneider wrote:
Folks:
I discovered a program that crashes the GPC compiler, attached.
Regards,
Compiling it does not crash my Mingw gpc compiler. The compiled program however crashes when you try to run it.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Thomas Schneider wrote:
I discovered a program that crashes the GPC compiler, attached.
It doesn't crash the compiler on Mac OS X, but it does cause a runtime error, because you are overflowing the stack.
procedure writeprism(var dianalysis: text; dataprism: trisquare);
Ough. You are passing a very large datastructure as value parameter, which implies that a copy of it is put on the stack. This costs a huge amount of stack and a lot of time. Instead, try
procedure writeprism(var dianalysis: text; var dataprism: trisquare);
procedure themain(var da: text); var dataprism: trisquare; (* the data structure for diana *)
It is a local variable of main, therefore it lives on the stack. Instead, try
var dataprism: trisquare; (* the data structure for diana *)
procedure themain(var da: text);
(a rare case where the use global variables is advised).
Regards,
Adriaan van Os
Adriaan:
It doesn't crash the compiler on Mac OS X, but it does cause a runtime error, because you are overflowing the stack.
Well, I am running Mac OS X 10.7 and it does crash the compiler on my machine. The error message is:
% gpc trim10-fail.p gpc: Internal error: Illegal instruction: 4 (program gpc1) Please submit a full bug report. See URL:http://www.gnu-pascal.de/todo.html for instructions.
procedure writeprism(var dianalysis: text; dataprism: trisquare);
Ough. You are passing a very large datastructure as value parameter, which implies that a copy of it is put on the stack. This costs a huge amount of stack and a lot of time.
Oh!!! Right. I suppose that the original author (who was a rather smart high school student at the time) probably didn't appreciate the distinction. But I should have noticed it ...
Great suggestion!!
Instead, try
procedure writeprism(var dianalysis: text; var dataprism: trisquare);
That compiles!
procedure themain(var da: text); var dataprism: trisquare; (* the data structure for diana *)
It is a local variable of main, therefore it lives on the stack. Instead, try
var dataprism: trisquare; (* the data structure for diana *)
procedure themain(var da: text);
(a rare case where the use global variables is advised).
That works in the test program and the original (when I make all calls var. THANKS! The reason is that if I define it in a procedure it goes on the stack but if I define it globally the memory for it is allocated as part of the program? Why would that make a difference?
I get segmentation faults when I run with the numbers too big (trimax=2003001). I'm somewhat puzzled by this since I have 26G free Physical memory ... I calculate that for that size it should only take 32048096 = 32,048,096 = 32M integers. What's happening?
By the way, I've get this when I compile:
ld: warning: -macosx_version_min not specified, assuming 10.7 ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in __start from /Developer/SDKs/MacOSX10.5.sdk//usr/lib/crt1.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
Does that matter? I am on 10.7 ...
Tom
Thomas D. Schneider, Ph.D. Senior Investigator National Institutes of Health National Cancer Institute Frederick National Laboratory for Cancer Research Gene Regulation and Chromosome Biology Laboratory Molecular Information Theory Group Frederick, Maryland 21702-1201 schneidt@mail.nih.gov http://alum.mit.edu/www/toms
On 17 Feb 2013 at 11:43, Thomas Schneider wrote:
Instead, try
procedure writeprism(var dianalysis: text; var dataprism: trisquare);
That compiles!
You can use "const dataprism : trisquare" as well - if you will not be changing anything in dataprism.
[...]
(a rare case where the use global variables is advised).
That works in the test program and the original (when I make all calls var. THANKS! The reason is that if I define it in a procedure it goes on the stack but if I define it globally the memory for it is allocated as part of the program? Why would that make a difference?
Local variables (and parameters passed by value) go on the stack, which is typically very small. You can increase it in some unix systems. Everything else (AFAIK) goes on the heap - which, put simply (As far as I understand) is as big as all the memory available to the program (installed RAM + virtual memory on the system).
I get segmentation faults when I run with the numbers too big (trimax=2003001). I'm somewhat puzzled by this since I have 26G free Physical memory ... I calculate that for that size it should only take 32048096 = 32,048,096 = 32M integers. What's happening?
Do this at the beginning of your program: writeln (sizeof (trisquare));
You will see exactly how big the data structure is.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Chief:
Local variables (and parameters passed by value) go on the stack, which is typically very small. You can increase it in some unix systems. Everything else (AFAIK) goes on the heap - which, put simply (As far as I understand) is as big as all the memory available to the program (installed RAM + virtual memory on the system).
Ok, I thought it might be on the heap but I had understood the heap contained pointer structures.
I get segmentation faults when I run with the numbers too big (trimax=2003001). I'm somewhat puzzled by this since I have 26G free Physical memory ... I calculate that for that size it should only take 32048096 = 32,048,096 = 32M integers. What's happening?
Do this at the beginning of your program: writeln (sizeof (trisquare));
You will see exactly how big the data structure is.
Thanks for the tip!
sizeof (trisquare) =128192384 trimax = 2003001 sizeof(trisquare)/trimax = 64.0001597603
http://www.gnu-pascal.de/gpc/SizeOf.html "Returns the size of a type or variable in bytes."
Ahh, that makes sense. There are 16 integers per triangular array element. Each integer is 64 bits which is 8 bytes ... 16*8=128. Hmm I'm still off by a factor of 2! Ok I ran sizeof on an integer ... 4 bytes. Fair enough, my integers are 32 bits long.
So my structure is still only 128Mb. I have a lot more free than that!
Tom
Thomas D. Schneider, Ph.D. Senior Investigator National Institutes of Health National Cancer Institute Frederick National Laboratory for Cancer Research Gene Regulation and Chromosome Biology Laboratory Molecular Information Theory Group Frederick, Maryland 21702-1201 schneidt@mail.nih.gov http://alum.mit.edu/www/toms
On 17 Feb 2013 at 12:55, Thomas Schneider wrote:
Chief:
Local variables (and parameters passed by value) go on the stack, which is typically very small. You can increase it in some unix systems. Everything else (AFAIK) goes on the heap - which, put simply (As far as I understand) is as big as all the memory available to the program (installed RAM + virtual memory on the system).
Ok, I thought it might be on the heap but I had understood the heap contained pointer structures.
Yes, the heap does - but you did not declare a pointer.
I get segmentation faults when I run with the numbers too big (trimax=2003001). I'm somewhat puzzled by this since I have 26G free Physical memory ... I calculate that for that size it should only take 32048096 = 32,048,096 = 32M integers. What's happening?
[...]
So my structure is still only 128Mb. I have a lot more free than that!
Are you still using a local variable, or a global variable? If you are using a global variable, there should be no problem at all. If you are still using a local variable, it would still overflow the stack. It is unusual to have stack space that is bigger than a few kilobytes, so 128mb is still far too big. To check the size of your stack (assuming it supports plain unix commands), run "ulimit -a" at a command prompt.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Chief:
Local variables (and parameters passed by value) go on the stack, which is typically very small. You can increase it in some unix systems. Everything else (AFAIK) goes on the heap - which, put simply (As far as I understand) is as big as all the memory available to the program (installed RAM + virtual memory on the system).
Ok, I thought it might be on the heap but I had understood the heap contained pointer structures.
Yes, the heap does - but you did not declare a pointer.
Ok, got it.
I get segmentation faults when I run with the numbers too big (trimax=2003001). I'm somewhat puzzled by this since I have 26G free Physical memory ... I calculate that for that size it should only take 32048096 = 32,048,096 = 32M integers. What's happening?
[...]
So my structure is still only 128Mb. I have a lot more free than that!
Are you still using a local variable, or a global variable? If you are using a global variable, there should be no problem at all. If you are still using a local variable, it would still overflow the stack. It is unusual to have stack space that is bigger than a few kilobytes, so 128mb is still far too big. To check the size of your stack (assuming it supports plain unix commands), run "ulimit -a" at a command prompt.
I am currently using a global variable and passing by var. with trimax at 501502 it compiles and runs.
When I set it to 2003001 it compiles but gives a segmention fault even though it's global. Maybe there's a limitation to allocating that way?
Then I switched dataprism to be a pointer using 'dataprism: ^trisquare;' as you suggested and changed the calls to be 'dataprism^' (a rather cute trick!) and ... it compiles but still gives me a segmentation fault!
Tom
Thomas D. Schneider, Ph.D. Senior Investigator National Institutes of Health National Cancer Institute Frederick National Laboratory for Cancer Research Gene Regulation and Chromosome Biology Laboratory Molecular Information Theory Group Frederick, Maryland 21702-1201 schneidt@mail.nih.gov http://alum.mit.edu/www/toms
On 18 Feb 2013 at 0:51, Thomas Schneider wrote:
[...]
I am currently using a global variable and passing by var. with trimax at 501502 it compiles and runs.
When I set it to 2003001 it compiles but gives a segmention fault even though it's global. Maybe there's a limitation to allocating that way?
Nope. The only limitation is the amount of available memory. On my Windows system I get no segfaults, even when allocating the full 490mb. I know precious little about OS X, but I think that you should check how much memory your system is allocating to programs.
Then I switched dataprism to be a pointer using 'dataprism: ^trisquare;' as you suggested and changed the calls to be 'dataprism^' (a rather cute trick!) and ... it compiles but still gives me a segmentation fault!
See above. I believe that you may have run into some sort of system limitation. There must be ways of increasing system resources available to applications on OS X (there is on unix systems, and I believe that OS X is, at its heart, a unix system).
Best regards, The Chief ------- Prof. Abimbola Olowofoyeku (The African Chief) Web: http://www.greatchief.plus.com
Abimbola:
See above. I believe that you may have run into some sort of system limitation. There must be ways of increasing system resources available to applications on OS X (there is on unix systems, and I believe that OS X is, at its heart, a unix system).
Yes, it's a Berkeley unix. Haven't found the incantation yet.
Tom
Thomas D. Schneider, Ph.D. Senior Investigator National Institutes of Health National Cancer Institute Frederick National Laboratory for Cancer Research Gene Regulation and Chromosome Biology Laboratory Molecular Information Theory Group Frederick, Maryland 21702-1201 schneidt@mail.nih.gov http://alum.mit.edu/www/toms
Thomas Schneider wrote:
When I set it to 2003001 it compiles but gives a segmention fault even though it's global. Maybe there's a limitation to allocating that way?
In a 32-bit process, an application can linearly address no more than typically 2 GB, even if the computer has more RAM. As a 64-bit operating system, Mac OS X can run 32-bit and 64-bit proceses. A 64-bit process can linearly address 2^63 bytes, but your program is 32-bit as it was compiled as such. With regard to a compiler capable of compiling 64-bit applications, see my message to this list of 23-06-2011 21:24.
Regards,
Adriaan van Os
Adriaan:
In a 32-bit process, an application can linearly address no more than typically 2 GB, even if the computer has more RAM. As a 64-bit operating system, Mac OS X can run 32-bit and 64-bit proceses. A 64-bit process can linearly address 2^63 bytes, but your program is 32-bit as it was compiled as such. With regard to a compiler capable of compiling 64-bit applications, see my message to this list of 23-06-2011 21:24.
That's at http://www.g-n-u.de/pipermail/gpc/2011-June/015064.html
I have:
% gpc --version gpc 20070904, based on gcc-3.4.6
Is there an upgrade available and should I? Where do I find it? There are a lot of options available at http://www.microbizz.nl/gpc.html and with all the different schemes people use for versions I can't tell if 'GNU Pascal 3.4.6u4' is more recent than the one I have. (Why can't the versions just be numbered consecutively?)
Thanks,
Tom
Thomas D. Schneider, Ph.D. Senior Investigator National Institutes of Health National Cancer Institute Frederick National Laboratory for Cancer Research Gene Regulation and Chromosome Biology Laboratory Molecular Information Theory Group Frederick, Maryland 21702-1201 schneidt@mail.nih.gov http://alum.mit.edu/www/toms
On 17 Feb 2013 at 9:46, Adriaan van Os wrote:
Thomas Schneider wrote:
I discovered a program that crashes the GPC compiler, attached.
It doesn't crash the compiler on Mac OS X, but it does cause a runtime error, because you are overflowing the stack.
procedure writeprism(var dianalysis: text; dataprism: trisquare);
Ough. You are passing a very large datastructure as value parameter, which implies that a copy of it is put on the stack. This costs a huge amount of stack and a lot of time. Instead, try
procedure writeprism(var dianalysis: text; var dataprism: trisquare);
procedure themain(var da: text); var dataprism: trisquare; (* the data structure for diana *)
It is a local variable of main, therefore it lives on the stack. Instead, try
var dataprism: trisquare; (* the data structure for diana *)
procedure themain(var da: text);
(a rare case where the use global variables is advised).
It is a very large data structure (about 490mb). It doesn't make a lot of sense to have a static variable of that size. It is probably better to use a pointer. That way, it can be a local variable:
procedure themain(var da: text); var dataprism: ^trisquare; (* the data structure for diana *)
But I guess that the real issue here is the compiler crash that the OP gets. I can't reproduce the compiler crash, and neither can Adriaan. Can anyone else reproduce it?
Perhaps the OP can provide more details for those who are maintaining the compiler (e.g., what OS, what gpc version, etc?).
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Prof:
It is a very large data structure (about 490mb). It doesn't make a lot of sense to have a static variable of that size. It is probably better to use a pointer. That way, it can be a local variable:
procedure themain(var da: text); var dataprism: ^trisquare; (* the data structure for diana *)
I don't understand. What that would gain me?
But I guess that the real issue here is the compiler crash that the OP gets. I can't reproduce the compiler crash, and neither can Adriaan. Can anyone else reproduce it?
Perhaps the OP can provide more details for those who are maintaining the compiler (e.g., what OS, what gpc version, etc?).
% gpc --version gpc 20070904, based on gcc-3.4.6 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% uname -a Darwin FR-W-C130981 11.4.2 Darwin Kernel Version 11.4.2: Thu Aug 23 16:25:48 PDT 2012; root:xnu-1699.32.7~1/RELEASE_X86_64 x86_64
Tom
Thomas D. Schneider, Ph.D. Senior Investigator National Institutes of Health National Cancer Institute Frederick National Laboratory for Cancer Research Gene Regulation and Chromosome Biology Laboratory Molecular Information Theory Group Frederick, Maryland 21702-1201 schneidt@mail.nih.gov http://alum.mit.edu/www/toms
On 17 Feb 2013 at 12:59, Thomas Schneider wrote:
Prof:
It is a very large data structure (about 490mb). It doesn't make a lot of sense to have a static variable of that size. It is probably better to use a pointer. That way, it can be a local variable:
procedure themain(var da: text); var dataprism: ^trisquare; (* the data structure for diana *)
I don't understand. What that would gain me?
procedure themain(var da: text); var dataprism: ^trisquare; begin new (dataprism); writeln(output,' trimdiana -gpc bug',version:4:2); writeprism(da, dataprism^); dispose (dataprism); end;
The dataprism pointer is 4 bytes on a 32-bit system. I don't know its size on a 64-bit system (i.e., whether it is 4 or 8 bytes - probably the latter); "sizeof (pointer)" should give you that information.
Pointers (or, at least, what they point to) are allocated on the heap, so you will not overflow the stack like you did when you declared dataprism as a local trisquare variable. Using a pointer, you are only playing with 4 or 8 bytes on the stack, whereas, before, you were playing with 490mb (which would overflow any stack).
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Chief:
procedure themain(var da: text); var dataprism: ^trisquare; begin new (dataprism); writeln(output,' trimdiana -gpc bug',version:4:2); writeprism(da, dataprism^); dispose (dataprism); end;
The dataprism pointer is 4 bytes on a 32-bit system. I don't know its size on a 64-bit system (i.e., whether it is 4 or 8 bytes - probably the latter); "sizeof (pointer)" should give you that information.
Pointers (or, at least, what they point to) are allocated on the heap, so you will not overflow the stack like you did when you declared dataprism as a local trisquare variable. Using a pointer, you are only playing with 4 or 8 bytes on the stack, whereas, before, you were playing with 490mb (which would overflow any stack).
Thanks for explaining.
Tom
Thomas D. Schneider, Ph.D. Senior Investigator National Institutes of Health National Cancer Institute Frederick National Laboratory for Cancer Research Gene Regulation and Chromosome Biology Laboratory Molecular Information Theory Group Frederick, Maryland 21702-1201 schneidt@mail.nih.gov http://alum.mit.edu/www/toms