https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71744
Bug ID: 71744 Summary: Concurrently throwing exceptions is not scalable Product: gcc Version: 5.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: nyh at math dot technion.ac.il Target Milestone: --- Multiple threads on multiple cores should be able to concurrently throw exceptions without bothering one another. But unfortunately, it appears that in the current implementation of libstdc++ and/or glibc, the stack unwinding process takes a global lock (while getting the list of shared objects, and perhaps other things) which serializes these parallel exception-throwing and can dramatically slow down the program. This problem has been reported in the past by users - see for example http://stackoverflow.com/questions/26257343/does-stack-unwinding-really-require-locks https://blogs.oracle.com/dave/entry/synchronization_horror_story_of_the Some might dismiss this inefficiency with the standard "exceptions should be rare" excuse. They should be rare. But sometimes they are not, leading do a catastrophic collapse in performance. We saw an illustrative example of an "exception storm" in a Seastar (http://www.seastar-project.org/) application. This application can handle over a million requests per second on many cores. Some unexpected circumstance caused the application to slow down somewhat, which led to some of the requests timing out. The timeout was implemented as an exception, so now we had thousands of exceptions being thrown in all cores in parallel. This led to the applications threads starting to hang, once in a while, on the lock(s) inside "throw". This in turn made the application even slower, and created even more timeouts, which in turn resulted in even more exceptions. In this way the number of exceptions per second escalated, until the point where most of the work the application was doing was fighting over the "throw" locks, and no useful work was being done.