Date: Mon, 25 Jun 2001 15:56:03 +0300 (IDT) From: Eli Zaretskii X-Sender: eliz AT is To: djgpp AT delorie DOT com Subject: Re: Peculiar behavior of program. In-Reply-To: <3b3723d5.238217279@news.primus.ca> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk On Mon, 25 Jun 2001, Graaagh the Mighty wrote: > On Sun, 24 Jun 2001 10:58:32 +0300 (IDT), Eli Zaretskii > sat on a tribble, which squeaked: > > >I cannot define it precisely because the critical number of recursive > >invocations depends on the size taken by the automatic variables. > > The number of invocations, no; the stack's size in bytes, yes You should be safe all the way until you hit the stack bottom, i.e. use up all the 512KB of the default stack. > >You can use the `stackavail' library function to track the amount of > >free stack at any point in your program. For example, you could add a > >printf line which prints the result at interesting points, where you > >think there might be lots of recusrion. > > Thanks. To check for overflow I'll add lines to the recursive parts to > make the program scream and die if this gets below, say, 16k. You can go as far as 1KB, I think. Unless a single invocation uses up more than 1K of stack space, that is. > However, shouldn't the host (or whatever manages access protection) be > detecting if the stack is overflowed? That would require to use a separate selector for the stack (because the stack is expand-down, and so needs a special segment setup for detecting stack overflows). This is possible, but has a serious problem: you cannot use -fomit-stack-pointer, because the EBP register will trigger a GPF if loaded with a value larger than the stack size. We actually had such a setup in the old v1.x days, and the complaints and FAQs due to -fomit-frame-pointer convinced us that the cure is worse than the disease (experience shows that stack overflows are extremely rare in typical DJGPP usage). > >This is consistent with the fact that CWSDPMI rather than the > >application prints the crash message: having the exception tables > >damaged is one of the cases when CWSDPMI aborts the program rather > >than letting it abort itself. > > How can the tables get damaged? For a wild pointer to run into the > exception tables, it has to run out of its normal bounds, and cause a > SIGSEGV, doesn't it? The tables are part of the application's data segment, so no level of protection can prevent the application from overwriting them. DPMI limitations don't allow to use a different segment for those tables, since the only register that is guaranteed to be valid when you enter an exception handler is CS. So at least some crucial data needed for exception handling _must_ be accessible via CS. That is why CS and DS in the DJGPP run-time environment share the same memory region. > >It's next to impossible to make this much better, given all the > >limitations of the DPMI spec and its implementations in most popular > >hosts. > > Those limitations don't apply to CWSDPMI. I was talking about the code that gets linked into your program, not about CWSDPMI. The code in your program doesn't know what host it will run with, so it needs to work with all of them, which means playing by the rules. > >For example, the exception handlers cannot be bulletproof if > >they aren't write-protected (your program could--and probably > >did--scribble over them)... > > Aren't the exception handlers protected against being scribbled on by > user code? I.e. outside the program's own allowed address range? No. See above. > Perhaps they should be, so a program would segfault before trashing > them. It would be nice if they could, but DPMI won't let you; see above.