void StandardExtension::initStandard() { // define('HHVM_VERSION_ID', XXYYZZ); Native::registerConstant<KindOfInt64>( s_HHVM_VERSION_ID.get(), ((HHVM_VERSION_MAJOR * 10000) + (HHVM_VERSION_MINOR * 100) + HHVM_VERSION_PATCH) ); // define('HPHP_VERSION', 'XX.YY.XX') // define('HHVM_VERSION', 'XX.YY.XX') Native::registerConstant<KindOfPersistentString>( s_HHVM_VERSION.get(), s_HHVM_VERSION_string.get() ); Native::registerConstant<KindOfPersistentString>( s_HPHP_VERSION.get(), s_HHVM_VERSION_string.get() ); Native::registerConstant<KindOfBoolean>( s_HHVM_DEBUG.get(), debug ); Native::registerConstant<KindOfPersistentString>( s_HHVM_COMPILER_ID.get(), makeStaticString(compilerId()) ); Native::registerConstant<KindOfPersistentString>( s_HHVM_REPO_SCHEMA.get(), makeStaticString(repoSchemaId()) ); }
void CompilationStatsData :: translateToExternalFormat(SQL_COMPILATION_STATS_DATA *query_cmp_data) { query_cmp_data->compileStartTime = compileStartTime(); query_cmp_data->compileEndTime = compileEndTime(); if ( query_cmp_data->compileEndTime == 0) { query_cmp_data->compileEndTime = NA_ConvertTimestamp(NA_JulianTimestamp()) ; } str_cpy_all(query_cmp_data->compilerId, compilerId(), COMPILER_ID_LEN); query_cmp_data->cmpCpuTotal = cmpCpuTotal(); query_cmp_data->cmpCpuBinder = cmpCpuBinder(); query_cmp_data->cmpCpuNormalizer = cmpCpuNormalizer(); query_cmp_data->cmpCpuAnalyzer = cmpCpuAnalyzer(); query_cmp_data->cmpCpuOptimizer = cmpCpuOptimizer(); query_cmp_data->cmpCpuGenerator = cmpCpuGenerator(); query_cmp_data->metadataCacheHits = metadataCacheHits(); query_cmp_data->metadataCacheLookups = metadataCacheLookups(); query_cmp_data->queryCacheState = queryCacheState(); query_cmp_data->histogramCacheHits = histogramCacheHits(); query_cmp_data->histogramCacheLookups = histogramCacheLookups(); query_cmp_data->stmtHeapSize = stmtHeapSize(); }
static void bt_handler(int sig) { if (IsCrashing) { // If we re-enter bt_handler while already crashing, just abort. This // includes if we hit the timeout set below. signal(SIGABRT, SIG_DFL); abort(); } // TSAN instruments malloc() to make sure it can't be used in signal handlers. // Unfortunately, we use malloc() all over the place here. This is bad, but // ends up working most of the time. Just abort so TSAN won't infinite crash // loop. if (use_tsan) { signal(SIGABRT, SIG_DFL); abort(); } // In case we crash again in the signal handler or something. Do this before // setting up the timeout to avoid potential races. IsCrashing = true; signal(sig, SIG_DFL); if (RuntimeOption::StackTraceTimeout > 0) { signal(SIGALRM, bt_handler); alarm(RuntimeOption::StackTraceTimeout); } // Make a stacktrace file to prove we were crashing. Do this before anything // else has a chance to deadlock us. int fd = ::open(RuntimeOption::StackTraceFilename.c_str(), O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR); if (RuntimeOption::EvalDumpRingBufferOnCrash) { Trace::dumpRingBuffer(RuntimeOption::EvalDumpRingBufferOnCrash, 0); } if (RuntimeOption::EvalSpinOnCrash) { char buf[128]; snprintf(buf, 127, "Crashed. Waiting for debugger to attach pid %d\n", getpid()); buf[127] = 0; write(STDERR_FILENO, buf, strlen(buf)); for (;;) sleep(1); } if (fd < 0) { // Nothing to do if we can't write the file raise(sig); return; } // Turn on stack traces for coredumps StackTrace::Enabled = true; StackTrace::FunctionBlacklist = s_newBlacklist; StackTrace::FunctionBlacklistCount = 3; StackTraceNoHeap st; auto const debuggerCount = [&] { if (RuntimeOption::EnableDebugger) { return Eval::Debugger::CountConnectedProxy(); } // We don't have a count of xdebug clients across all requests, so just // check the current request. if (XDebugServer::isAttached()) { return 1; } return 0; }(); st.log(strsignal(sig), fd, compilerId().begin(), debuggerCount); // flush so if php crashes us we still have this output so far ::fsync(fd); if (fd >= 0) { // Don't attempt to determine function arguments in the PHP backtrace, as // that might involve re-entering the VM. if (!g_context.isNull()) { dprintf(fd, "\nPHP Stacktrace:\n\n%s", debug_string_backtrace( /*skip*/false, /*ignore_args*/true ).data()); } ::close(fd); } if (jit::transdb::enabled()) { jit::tc::dump(true); } if (!RuntimeOption::CoreDumpEmail.empty()) { char format [] = "cat %s | mail -s \"Stack Trace from %s\" '%s'"; char* cmdline = (char*)alloca(sizeof(char) * (strlen(format) +RuntimeOption::StackTraceFilename.length() +strlen(Process::GetAppName().c_str()) +strlen(RuntimeOption::CoreDumpEmail.c_str())+1)); sprintf(cmdline, format, RuntimeOption::StackTraceFilename.c_str(), Process::GetAppName().c_str(), RuntimeOption::CoreDumpEmail.c_str()); FileUtil::ssystem(cmdline); } // Calling all of these library functions in a signal handler // is completely undefined behavior, but we seem to get away with it. // Do it last just in case Logger::Error("Core dumped: %s", strsignal(sig)); Logger::Error("Stack trace in %s", RuntimeOption::StackTraceFilename.c_str()); // Flush whatever access logs are still pending Logger::FlushAll(); HttpRequestHandler::GetAccessLog().flushAllWriters(); // Give the debugger a chance to do extra logging if there are any attached // debugger clients. Eval::Debugger::LogShutdown(Eval::Debugger::ShutdownKind::Abnormal); if (!g_context.isNull()) { // sync up gdb Dwarf info so that gdb can do a full backtrace // from the core file. Do this at the very end as syncing needs // to allocate memory for the ELF file. g_context->syncGdbState(); } // re-raise the signal and pass it to the default handler // to terminate the process. raise(sig); }