Closed Bug 96128 Opened 23 years ago Closed 20 years ago

stack overflow crash with infinite recursion

Categories

(Core :: JavaScript Engine, defect)

x86
Windows NT
defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 220408

People

(Reporter: jband_mozilla, Assigned: khanson)

References

Details

(Keywords: crash, js1.5, Whiteboard: Is this related to bug #96526?)

Attachments

(2 files)

The JS infinite recursion protection is built into the bytecode interpreter 
loop is not catching some cases. See: 
http://lxr.mozilla.org/seamonkey/ident?i=MAX_INTERP_LEVEL

On NT4 the simple code...

  function T(){return new T();}; T() 

...causes a stack overflow crash in debug builds of both the browser and the 
shell. In the release builds this is safely caught by the "too much recursion" 
mechanism. If I remove the 'new' from the code above this is safely caught in 
both debug and release builds. The 'new' causes a lookup for the Constructor 
name and seems to (at least) double the number of items on the C stack for the 
given interpLevel depth.

I suspect we are simply running afoul of the number chosen for the hard limit 
here and should lower the #define'd value of MAX_INTERP_LEVEL. I'm not clear on 
exactly what cases the inline call stuff is kicked in, so I don't know if 
MAX_INLINE_CALL_COUNT is at issue also.

Changing MAX_INTERP_LEVEL to 250 makes it not crash for me. (Changing it to 500 
did not fix the crash). Such a change may simply be a bandaid; there may be a 
more appropriate fix.
Ick.  This number might have to be tuned for different OSes, or even for
different versions of the same OS!  Perhaps we should just reduce (if not
eliminate) interpreter recursion, _a la_ the inline_call: stuff.

/be
Reassigning to khanson - 
Assignee: rogerl → khanson
jband's testcase added to JS test suite:

          mozilla/js/tests/js1_5/Regress/regress-96128-n.js


On WinNT, I experience what jband saw: the debug JS shell crashes,
but the optimized JS shell gracefully errors with exit code 3 and
this message:

          InternalError: too much recursion


On Linux, I am getting the graceful error in both the debug and
optimized JS shells...
Status: NEW → ASSIGNED
Target Milestone: --- → mozilla0.9.8
targeting for 9.9.
Target Milestone: mozilla0.9.8 → mozilla0.9.9
Whiteboard: Is thiss related to bug #96526
Whiteboard: Is thiss related to bug #96526 → Is this related to bug #96526?
Target Milestone: mozilla0.9.9 → mozilla1.0.1
Blocks: 149801
Attached patch Proposed patchSplinter Review
Sets the MAX_INTERP_LEVEL to 320.  For the Mac the level is also screened for a
low stack space dynamically using a call to StackSpace ().  For the test case
above, the Mac halts at a level of 99.	It would be very useful to find a
function like StackSpace () for the non Mac version.
Is 16K based on anything, or just a SWAG?  It seems big for a "red zone", but I
don't know what else to use -- my gut would favor 8K.  Can we measure, perhaps
disassemble compiled to see frame sizes by finding stack pointer adjustment code?

/be
Keywords: js1.5, mozilla1.2
I tried 10k and it crashed.  It is the value used by a similar code snippet in
jsregexp.c.
Oh, I hadn't seen that jsregexp.c code.  Rogerl, how'd you come up with that
magic 16K?  Should we enshrine it with a common macro so khanson can use it in
jsinterp.c?

/be
I know of no StackSize equiv for Win32 or Linux. There is an article about Win32
stacks at:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/prothred_0b8l.asp

The normal way to deal with this sort of problem on Win32 is reactive rather
than proactive: wrap the doubtful code with a structured exception handler and
handle the case where the system was unable to give you more stack space. *How*
you go about handling it and what state things are left in is a messy problem
though.

It appears that a Win32 version of StackSize would not be hard to write. The
Platform SDK has headers for NT_TIB (thread info block) which has members:
StackBase and StackLimit. Apparently this block is always pointed to by an
offset from the FS register. Of course the current stack pointer is always in a
register. I *assume* that the limit it refers to is the *reserved* memory limit.
So, it is possible that actually committing stack memory might fail before the
limit is reached. I don't know if these things are identical across Win32
platforms (e.g. Win95 v. Win200 etc).

Again, if it *really* makes sense to try to adaptively cope with stack overflow
in the js interp loop for Win32 then appropriately placed structured exception
handling may be worth investigating.

On the issue of the choice of magic numbers... I would expect less per function
stack use in a release build... We should not limit the release builds with 'red
zones' sized for debug builds. Do we have a reasonable way to estimate limiting
stack requirements at the interp loop level? Or is it 'OK' to just try it with
some arbitrary bit of nesting code?
I will try to determine the correct size of the red zone in various
environments.  Note, it should be large enough to provide the stack and heap
necessary for a graceful exit.
*** Bug 157434 has been marked as a duplicate of this bug. ***
(Sorry - on vacation, so not checking email very often).
The stack sniffing code came from Beard & Waldemar. I'm not sure, but I think 
the 16K is the default stack size given to a Mac application by the Finder (back 
in the good old days). The (candidate) new engine doesn't use the same code 
since it doesn't recurse on the stack, but macro-fying the code snippet seems 
like a handy thing to do for the major recursion sensitive passes.
I reported a similar bugs unchecked stack overflow during recursion in parser,
regexp parser and toSource implementation: see bug 192414 and bug 192465.

It seems having StackSize available would be a proper remedy for this.
Igor, sorry this dropped off my radar.  Can it wait till 1.6alpha?

/be
Perhaps it makes sence to use SpaceSize on Mac when limitting maximal  stack
consumption instead of compilation-time limit set by
JS_DEFAULT_STACK_SIZE_LIMIT?

This is completely untested since I do not have access to any MAC.
Target Milestone: mozilla1.0.1 → ---
I don't know that StackSpace() returns anything useful in Mach-O. It might not.
Can we measure stack depth by referring to the address of some variable on the
stack in the frame for a non-recursing function?
Keywords: mozilla1.2crash
This is now a dup of bug 220408.

/be

*** This bug has been marked as a duplicate of 220408 ***
Status: ASSIGNED → RESOLVED
Closed: 20 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: