#68 Tomcat stack overflows

open
nobody
tomcat (9)
8
2013-12-25
2010-01-18
Steve Blackburn
No

From Eric Bodden:

By accident I just discovered that the tomcat benchmark suffers from
multiple StackOVerFlowErrors during execution in DaCapo.

Apparently, these errors are caught and "swallowed" somewhere so that
they never make it to the surface. Nevertheless, I believe that this
should be fixed because it could alter the performance of the
benchmark according to the -Xss flag that was used to start the VM.

I have a part of the offending stack trace attached below.

Eric

NioEndpoint.setProperty(String, String) line: 531
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: not available
IntrospectionUtils.setProperty(Object, String, String) line: 354
NioEndpoint.setProperty(String, String) line: 539
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: not available
IntrospectionUtils.setProperty(Object, String, String) line: 354
NioEndpoint.setProperty(String, String) line: 539
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: not available
IntrospectionUtils.setProperty(Object, String, String) line: 354
NioEndpoint.setProperty(String, String) line: 539
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: not available
IntrospectionUtils.setProperty(Object, String, String) line: 354
NioEndpoint.setProperty(String, String) line: 539
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: not available
IntrospectionUtils.setProperty(Object, String, String) line: 354
NioEndpoint.setProperty(String, String) line: 539
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: not available
IntrospectionUtils.setProperty(Object, String, String) line: 354
NioEndpoint.setProperty(String, String) line: 539
Http11NioProtocol.setProperty(String, String) line: 102
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: not available
IntrospectionUtils.setProperty(Object, String, String) line: 354
Connector.setProperty(String, String) line: 321
Connector.setRedirectPort(int) line: 799
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: not available
IntrospectionUtils.setProperty(Object, String, String) line: 331
SetAllPropertiesRule.begin(String, String, Attributes) line: 66
Digester.startElement(String, String, String, Attributes) line: 1358
SAXParserImpl$JAXPSAXParser(AbstractSAXParser).startElement(QName,
XMLAttributes, Augmentations) line: 501
SAXParserImpl$JAXPSAXParser(AbstractXMLDocumentParser).emptyElement(QName,
XMLAttributes, Augmentations) line: 179
XMLDocumentScannerImpl(XMLDocumentFragmentScannerImpl).scanStartElement()
line: 1339
XMLDocumentScannerImpl$ContentDriver(XMLDocumentFragmentScannerImpl$FragmentContentDriver).next()
line: 2747
XMLDocumentScannerImpl.next() line: 648
XMLDocumentScannerImpl(XMLDocumentFragmentScannerImpl).scanDocument(boolean)
line: 510
XIncludeAwareParserConfiguration(XML11Configuration).parse(boolean) line: 807
XIncludeAwareParserConfiguration(XML11Configuration).parse(XMLInputSource)
line: 737
SAXParserImpl$JAXPSAXParser(XMLParser).parse(XMLInputSource) line: 107
SAXParserImpl$JAXPSAXParser(AbstractSAXParser).parse(InputSource) line: 1205
SAXParserImpl$JAXPSAXParser.parse(InputSource) line: 522
Digester.parse(InputSource) line: 1644
Catalina.load() line: 521
Catalina.load(String[]) line: 555
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: not available
Bootstrap.load(String[]) line: 260
Bootstrap.main(String[]) line: 405
Control.exec(String) line: 55
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: not available
Tomcat.prepare(String) line: 67
Tomcat(Benchmark).run(Callback, String) line: 144
TestHarness.runBenchmark(File, String, TestHarness) line: 218
TestHarness.main(String[]) line: 171
Harness.main(String[]) line: 17

Discussion

  • Eric Bodden
    Eric Bodden
    2010-01-19

    > How do you get this stacktrace ? Could you give some more environment
    > details ? Which stack sizes have you observed success and failure ?

    I ran the benchmark in the Eclipse debugger and set a method breakpoint at IntrospectionUtils.setProperty. That way you can see the stack unfold very easily. As I wrote, the code itself never prints a stack trace because the error seems to be "swallowed" in a catch block or something similar.

    About the environment... I am on OSX 10.6, with Java 1.6.0_17. I used various stack sizes, all seem to cause failure. I am very positive that this is an "open-ended" stack overflow, i.e., it does not matter how much stack you give, the VM will always run out. You can see in the debugger that the arguments of "setProperty" never change from one call to the next.

    It's odd though, that the benchmark still "completes normally", i.e., shows PASSED in the end, despite these errors. Apparently they happen in a chunk of code that the benchmark does not really rely on.

     
  • John N Zigman
    John N Zigman
    2010-03-11

    The StackOverflowException is raise exactly three times during the initialization of the Tomcat server.

    No StackOverflow exception is raised during the timed benchmark phase.

    It appears that the StackOverflow is caused by the operation of the parse while processing the server.xml file (although I have yet to confirm this). Furthermore, the exception does appear as Eric noted to be due to a open-ended call chain of
    IntrospectionUtils.setProperty(Object, String, String) line: 354
    NioEndpoint.setProperty(String, String) line: 539
    being repeated.

    At this point it does not seem to adversely affect the configuration of the server so the server seems to behave as expected, furthermore the StackOverflow only occur during the server configuration phase prior to benchmarking.

     
  • John N Zigman
    John N Zigman
    2010-03-11

    Note: The exceptions were recorde on a GNU/Linux i386 installation running Sun 1.6 JDK using a C agent intercepting the JVMTI_EXCEPTION_EVENT and turning the logging for different parts of the execution.

     
  • John N Zigman
    John N Zigman
    2010-03-11

    Varying the stack size (within reason) does not change the number of StackOverflow exceptions in initialization of the Tomcat server, nor does it introduce StackOverflow exceptions into the iterate phase of the benchmark.

     

  • Anonymous
    2012-12-06

    It seems that this is a bug in tomcat:

    https://issues.apache.org/bugzilla/show_bug.cgi?id=48252

    It's fixed in the latest version of tomcat.