diff --git a/hphp/doc/options.compiled b/hphp/doc/options.compiled index 21bfd7951dbdf..3e0aad81337eb 100644 --- a/hphp/doc/options.compiled +++ b/hphp/doc/options.compiled @@ -595,6 +595,8 @@ next requests. CoreDumpEmail = email address CoreDumpReport = true CoreDumpReportDirectory = /tmp + + StackTraceTimeout = 0 } - FullBacktrace, ServerErrorMessage, TranslateSource @@ -612,6 +614,12 @@ file's location. ClearInputOnSuccess can automatically delete requests that had 200 responses and it's useful to capture 500 errors on production without capturing good responses. +- StackTraceTimeout + +This specifies the maximum number of seconds spent for generating a stack trace +when hhvm is crashed. The default is 0 which means no timeout. This can be set +to prevent from deadlocks in the backtrace handler. + - APCSize There are options for APC size profiling. If enabled, APC overall size will be diff --git a/hphp/runtime/base/crash-reporter.cpp b/hphp/runtime/base/crash-reporter.cpp index de6136f2dc51d..25d4d82023e37 100644 --- a/hphp/runtime/base/crash-reporter.cpp +++ b/hphp/runtime/base/crash-reporter.cpp @@ -31,6 +31,17 @@ namespace HPHP { bool IsCrashing = false; static void bt_handler(int sig) { + if (RuntimeOption::StackTraceTimeout > 0) { + if (IsCrashing && sig == SIGALRM) { + // Raising the previous signal does not terminate the program. + signal(SIGABRT, SIG_DFL); + abort(); + } else { + signal(SIGALRM, bt_handler); + alarm(RuntimeOption::StackTraceTimeout); + } + } + // In case we crash again in the signal hander or something signal(sig, SIG_DFL); IsCrashing = true; diff --git a/hphp/runtime/base/runtime-option.cpp b/hphp/runtime/base/runtime-option.cpp index dacebc1376b4a..845fe6a098207 100644 --- a/hphp/runtime/base/runtime-option.cpp +++ b/hphp/runtime/base/runtime-option.cpp @@ -309,6 +309,7 @@ bool RuntimeOption::CoreDumpReport = true; std::string RuntimeOption::StackTraceFilename; bool RuntimeOption::LocalMemcache = false; bool RuntimeOption::MemcacheReadOnly = false; +int RuntimeOption::StackTraceTimeout = 0; // seconds; 0 means unlimited bool RuntimeOption::EnableStats = false; bool RuntimeOption::EnableAPCStats = false; @@ -1409,6 +1410,7 @@ void RuntimeOption::Load(IniSetting::Map& ini, Hdf& config, Config::Bind(LocalMemcache, ini, debug["LocalMemcache"]); Config::Bind(MemcacheReadOnly, ini, debug["MemcacheReadOnly"]); + Config::Bind(StackTraceTimeout, ini, debug["StackTraceTimeout"], 0); { Hdf simpleCounter = debug["SimpleCounter"]; diff --git a/hphp/runtime/base/runtime-option.h b/hphp/runtime/base/runtime-option.h index 61a82d56c6394..426bedb4fa1cd 100644 --- a/hphp/runtime/base/runtime-option.h +++ b/hphp/runtime/base/runtime-option.h @@ -293,6 +293,7 @@ class RuntimeOption { static std::string StackTraceFilename; static bool LocalMemcache; static bool MemcacheReadOnly; + static int StackTraceTimeout; static bool EnableStats; static bool EnableAPCStats;