Dear GPC Users,
I'm trying to force the operating system to give my Pascal code a 2-MByte stack so I can solve a problem with a recursive routine. I have tried:
const {for recursive routines} minstacksize: cardinal = 2000000; attribute (name = '_stklen');
But that does not appear to work. Perhaps I am not trying hard enough. Am I on the right track?
Yours, Kevan
-------------------------------------------- On Thu, 7/25/13, Kevan Hashemi hashemi@brandeis.edu wrote:
Subject: Minimum Stack Size To: "gpc@gnu.de" gpc@gnu.de Date: Thursday, July 25, 2013, 4:47 PM
Dear GPC Users,
I'm trying to force the operating system to give my Pascal code a 2-MByte stack so I can solve a problem with a recursive routine. I have tried:
const {for recursive routines} minstacksize: cardinal = 2000000; attribute (name = '_stklen');
But that does not appear to work. Perhaps I am not trying hard enough. Am I on the right track?
Yours, Kevan
-- Kevan Hashemi, Electrical Engineer Physics Department, Brandeis University http://alignment.hep.brandeis.edu/
What you describe doing, I found in a FAQ, but the paragraphs around it mentioned DJGPP. I'm not clear on what DJGPP is, or whether you're using it. (I think I'm not using it -- I'm using MinGW.)
The same place mentions using a program named "stubedit" to set the stack size: stubedit your_app.exe minstack=5000K Do you have a "stubedit"?
In doc/gpc/gpcc.txt there's mention of an option (switch?): Stack size: -$M<StackSize>
"ld" has an option: --stack <size> I think you can get that through to "ld" by putting -Xlinker --stack=2000000 on your "gpc" command.
I don't see "stklen" in my map file, but I wonder whether you need more or fewer underscores. (Maybe "attribute(name=) used to "help" you by prepending an underscore, but has since been changed to do exactly what you tell it to do.)
I haven't tried any of these things.
Kevan Hashemi wrote:
I'm trying to force the operating system to give my Pascal code a 2-MByte stack so I can solve a problem with a recursive routine. I have tried:
const {for recursive routines} minstacksize: cardinal = 2000000; attribute (name = '_stklen');
But that does not appear to work. Perhaps I am not trying hard enough. Am I on the right track?
Seting stack limit is mostly operating system matter and has little to do with Gpc. On linux the ulimit command allows changing stack limit:
limit -s 2048
sets limit to 2MB (unit is kilobyte). Note that in most Linux distributions default limit seem to be higher, like 8MB. Other systems have their own means.
On 26/07/2013 11:47, Waldek Hebisch wrote:
Seting stack limit is mostly operating system matter and has little to do with Gpc. On linux the ulimit command allows changing stack limit:
limit -s 2048
Should that be ulimit -s 2048?
Martin Liddle wrote:
On 26/07/2013 11:47, Waldek Hebisch wrote:
Seting stack limit is mostly operating system matter and has little to do with Gpc. On linux the ulimit command allows changing stack limit:
limit -s 2048
Should that be ulimit -s 2048?
Yes.
Thank you all for your instructions, which make perfect sense to me. As you say, the default stack size on MacOS is 8 MBytes, which I think should be enough.
I want to reach a recursion depth of around 10,000. So long as each recursion consumes less than 800 bytes, I'll be okay. But the program crashes at a depth of around 2000, which suggests tht each time the procedure calls itself, it uses 4 kBytes of stack space.
If you have a minute, please consider the following:
procedure recursive(i:integer); begin if i<2000 then recursive(i+1); end;
Now, if I were programming this in assembler on a 32-bit machine, I would push the intereger and the program counter onto the stack, using eight bytes. Does GPC push all registers onto the stack for a procedure call, and if so, can this take 4 kBytes?
Yours, Kevan
Waldek Hebisch wrote:
Martin Liddle wrote:
On 26/07/2013 11:47, Waldek Hebisch wrote:
Seting stack limit is mostly operating system matter and has little to do with Gpc. On linux the ulimit command allows changing stack limit:
limit -s 2048
Should that be ulimit -s 2048?
Yes.
program t16( input, output ) ;
procedure recursive(i:integer); begin if i<2000 then recursive(i+1); end;
begin recursive(0) ; end.
This completes for me. (Windows XP, MinGW) The procedure uses 0x18 bytes of stack per call.
If your procedure has local variables, that increases the size of its stack frame. If your procedure has an argument that is a structure or array that is being passed by value, the compiler will be making a copy in the stack frame of the current invocation before calling the next level.
You can use "gdb" to look at the first few instructions of your procedure. I think if you compile with a "-S" option, you will have an assembly language source file to look at.
Kevan Hashemi wrote:
If you have a minute, please consider the following:
procedure recursive(i:integer); begin if i<2000 then recursive(i+1); end;
Please post a complete test program with instructions to reproduce the problem. Doing so will also help you solve problem yourself.
[p18:~/gpc/testgpc/adriaan] adriaan% cat teststack.pas
program teststack;
procedure recursive(i:integer); begin if i<2000 then recursive(i+1); end;
begin recursive( 1) end.
[p18:~/gpc/testgpc/adriaan] adriaan% gp teststack.pas -Wl,-stack_size,10000 [p18:~/gpc/testgpc/adriaan] adriaan% ./teststack Segmentation fault
[p18:~/gpc/testgpc/adriaan] adriaan% gp teststack.pas -Wl,-stack_size,20000 [p18:~/gpc/testgpc/adriaan] adriaan% ./teststack
In other words, stack usage is not excessive.
Jay Michael wrote
If your procedure has local variables, that increases the size of its stack frame. If your procedure has an argument that is a structure or array that is being passed by value, the compiler will be making a copy in the stack frame of the current invocation before calling the next level.
Yes, that's the probable cause of the stack overflow. Excessive stack usage is often a sign of misdesigned code.
Regards,
Adriaan van Os
Adriaan:
In other words, stack usage is not excessive.
Thank you for your attention. Using the same test program you tried, I get the same result on MacOS, except I get a message
"warning no -stack_addr specified using the default addr: 0xc0000000".
which appears to be harmless.
Please post a complete test program with instructions to reproduce the problem. Doing so will also help you solve problem yourself.
That's good advice. I find that I cannot reproduce the problem in my code using a recursive test procedure. I conclude that I have been wrong all along in my assumption that deep recursion was causing my code to crash. I will look for another cause.
Jay:
You can use "gdb" to look at the first few instructions
That sounds useful. Thank you for the test you ran on Windows.
Yours, Kevan
Waldek Hebisch wrote:
Kevan Hashemi wrote:
I'm trying to force the operating system to give my Pascal code a 2-MByte stack so I can solve a problem with a recursive routine. I have tried:
const {for recursive routines} minstacksize: cardinal = 2000000; attribute (name = '_stklen');
But that does not appear to work. Perhaps I am not trying hard enough. Am I on the right track?
Seting stack limit is mostly operating system matter and has little to do with Gpc. On linux the ulimit command allows changing stack limit:
On Mac OS X, also a UNIX flavor, the stack limit can be set compile-time with the -stack_size linker option, see https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/ld.1.html.
Therefore it can be set through gpc with -Wl,-stack_size,hhh where hhh is the stacksize in hexadecimal.
Regards,
Adriaan van Os
On Mac OS X, also a UNIX flavor, the stack limit can be set compile-time with the -stack_size linker option, see https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/ld.1.html.
Therefore it can be set through gpc with -Wl,-stack_size,hhh where hhh is the stacksize in hexadecimal.
You can even set the stack size dynamically in the running application with setrlimit, see http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/getrlimit.2.html and http://developer.apple.com/library/mac/#qa/qa1419/_index.html.
Regards,
Adriaan van Os
Hi,
Correction: It is stack over-flow, but that's because I'm reaching a depth of 170,000 in an error case. I was able to set the stack size and increase the failure depth. So all makes sense. Thank you for your help.
Kevan