Gale Paeper wrote:
I wouldn't rely up the lack of a OS stack overflow report as indicative of a small stack size. In one -O3 execution test I ran with 10000 levels of recursion, I got no problems reported; however, the trash stack frame size was still 80 bytes as the assembly code showed.
I am puzzled. I think this *should* be reliable, the way the kernel works. Are you sure ? The difference between our tests is (maybe) you run OS X 10.3, where I run 10.2. However, I do have noticed that (on 10.2) "limit stacksize" gets confused when called three or four times in the same terminal window (so I always open a new terminal window before calling "limit stacksize"). Did you try adding a __UNIXSTACK segment with the linker, e.g.
% gpc -o nonloc2goto nonloc2goto.pas -Wl,-stack_size,0x100000,-stack_addr,0xc0000000
I also tried varying optimization levels from no optimatization, -O, -O2, and -O3 and all stack frame sizes for thr trash procedure and function was 80 bytes.
Sorry, this is a misunderstanding, --no-inline reduces the stack frame size for "recursion.pas" (the simple testprogram in my previous post) and for "nonloc2goto.pas" but not for "nonloc4goto.pas".
I also saw a range of errors (illegal instruction, bus error, malloc deallocation problems) during program termination indicating something was stomping on memory being referenced by the terminating code. (This was seen in some follow up testing with a reduced recursion level to keep the stack in the 512K bounds. With or without Frank's writeln suggestion, I got the expected Pascal output - the errors showed up during termination code execution after the main program code had finished ececuting.) But that may be just bugs in the older gpc version 20030830 I'm testing with and may have been fixed in the new gpc version 20040516.
I tried and didn't witness any difference in behaviour between the various compilers. The problem is that when stack is low, you are no longer running in an environment where anything can be trusted. For example, the Darwin kernel raises SIGSEGV for a stack overflow, then it attempts to create a signal frame on the already-full stack. This sometimes results in SIGBUS being reported, rather than SIGSEGV (see http://gcc.gnu.org/ml/gcc-patches/2003-02/msg00747.html).
The same problem is in the GPC runtime, see the comment on top of the "InstallDefaultSignalHandlers" procedure in error.pas. A solution is to use an alternative stack in the signal handler. I have included a post by Matt Watson on the darwin-development list, with an example signal handler that uses an alternative stack.
I didn't see any difference between Apple's gcc generated assembly code and the GPC driven C compiler generated assembly code. For both compilers' generated assembly code, the trash procedure was tail call optimized with no stack frame and the trash function had a stack frame size of 80 bytes.
OK, I were just asking to be sure when reporting this whole thing to the gcc back-end folks.
Regards,
Adriaan van Os