PR# 14450 Routine `exception_trace' from EXCEPTIONS not thead-safe
Problem Report Summary
Submitter: prestoat2000
Category: Runtime
Priority: Medium
Date: 2008/06/05
Class: Bug
Severity: Serious
Number: 14450
Release: 6.2.73753
Confidential: No
Status: Closed
Responsible:
Environment: Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.8.1.13) Gecko/20080328 Firefox/2.0.0.13
Solaris 10 on SPARC
Synopsis: Routine `exception_trace' from EXCEPTIONS not thead-safe
Description
Routine `exception_trace' from EXCEPTIONS does not seem to be thread-safe. The attached classes and config file can be used as the basis for an eweasel test to demonstrate this. Root class TEST creates 3 worker threads, of types WORKER1, WORKER2 and WORKER3. These classes inherit from WORKER and each call a recursive routine `count' times. The recursive routine recurses to `depth' and then raises a developer exception whose name is different for each worker ("weasel", "stoat" and "ermine", for workers 1, 2 and 3), gets the exception trace in the rescue clause and makes sure the trace does not contain either of the other two names, which would indicate an incorrect trace. If any incorrect names appear in the trace, they are displayed. Executing the system with a relatively large depth and count results in either incorrect traces or in a segmentation fault. Part of the problem is probably use of the static variable `buffer' in routine `print_object_location_reason_effect' in except.c. Another part of the problem might be (not sure about this) calling `egc_last_exception' from within `last_exception' in except.c without adequate locking.
To Reproduce
Finalize with attached Ace file (has exception_trace on and multithreaded on) and attached classes. Execute system with arguments 100 10000 (depth 100, iteration count 10000). Finds some incorrect exception traces. Execute system with arguments 10000 100 (depth 10000, iteration count 100). Usually crashes with seg fault in routine called from `last_exception' in except.c.
Problem Report Interactions
Never mind. I found out that the default stack size on Solaris is 1 MB (2 MB for 64-bit processes). So the originally reported problem definitely seems to be fixed. There does not seem to be a way to specify stack size for a thread in THREAD_ATTRIBUTES, which seems like a deficiency. Closing report.
This seems to be only partially fixed. With rev 74123, when I run it with a moderate depth and a large iteration count (arguments 100 100000 or even 5000 100000) it runs fine and does not find any name mismatches in the exception trace. But when I run it with a depth >= 7166 and iteration count of 1 (e.g., arguments 8000 1), it crashes with a seg fault. I have stack size set to "unlimited" and I verified that the stack for each thread is only about 1 MB. These results are on OpenSolaris 2008.05 snv_93 on x86. Haven't tried on Solaris SPARC yet. In fact, it crashes with just one main thread and one worker if depth >= 7166, even if it does not raise an exception. Maybe there is a per-thread stack limit I'm not aware of. I will try on Solaris SPARC.
This should be fixed in rev#73875, as test#except027 has been fixed. Can you confirm this on Solaris? Thanks.
test#except027 added. It is probably due to the unsafe buffer. On Windows, I didn't get crash when: Execute system with arguments 10000 100 (depth 10000, iteration count 100). Usually crashes with seg fault in routine called from `last_exception' in except.c. I even changed arguments to 100000 100, I got a crash of stack overflow. After that I ten times the stack size to be 50000000 (50M). The crash was gone.