/** * Runs the object returned by WebAppManager::instance() * * Steps to do so are as follows: * - Install crash handlers for SIGILL, SIGSEGV, and SIGTERM * - Set the process name * - Wait until IpcServer in the main process is ready * - Set IpcServerPipeFd to -1 to indicate that we're done waiting for it * - Set host info for {@link WebAppManager::instance() WebAppManager::instance()} to what is returned by HostBase::instance()->getInfo() * - Initialize malloc stats * - Initialize the logs * - Start the Browser App Launcher * * @param data Not used * * @return Always returns 0 */ static int RunWebAppManagerTask(void* data) { // Install the handler for signals that we want to trap: // Note: We install the handlers after we initialize the setting because // we may do something different depending on the settings values. installOuterCrashHandler(SIGILL); installOuterCrashHandler(SIGSEGV); installOuterCrashHandler(SIGTERM); ::prctl(PR_SET_NAME, (unsigned long) "WebAppMgr", 0, 0, 0); ::prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); char msg = 0x00; int len = 0; // block here until the IpcServer in the main process is ready while (len != 1 || msg != msgOkToContinue) len = ::read(IpcServerPipeFd, &msg, 1); ::close(IpcServerPipeFd); IpcServerPipeFd = -1; const HostInfo* info = &(HostBase::instance()->getInfo()); WebAppManager::instance()->setHostInfo(info); initMallocStatsCb(WebAppManager::instance()->mainLoop(), s_mallocStatsInterval); logInit(); // Start the Browser App Launcher #ifdef NO_WEBKIT_INIT WindowServer::instance()->bootupFinished(); #else WebAppManager::instance()->run(); // Sync execution of the task #endif return 0; }
int main( int argc, char** argv) { appArgc = argc; appArgv = argv; std::set_terminate(generateGoodBacktraceTerminateHandler); g_thread_init(NULL); const char *renderMode; #if defined(TARGET_DEVICE) && defined(HAVE_OPENGL) ::setenv("QT_PLUGIN_PATH", "/usr/plugins", 1); renderMode = "HW egl"; #elif defined(TARGET_DEVICE) || defined(TARGET_EMULATOR) ::setenv("QT_PLUGIN_PATH", "/usr/plugins", 1); renderMode = "Software"; #elif defined(HAVE_OPENGL) renderMode = "HW OpenGL"; #else renderMode = "Software"; #endif g_debug("SysMgr compiled against Qt %s, running on %s, %s render mode requested", QT_VERSION_STR, qVersion(), renderMode); // Command-Line options parseCommandlineOptions(argc, argv); if (s_debugTrapStr && 0 == strcasecmp(s_debugTrapStr, "on")) { debugCrashes = true; } if (s_mallocStatsFileStr) { setupMallocStats(s_mallocStatsFileStr); } sysmgrPid = getpid(); // Load Settings (first!) Settings* settings = Settings::LunaSettings(); // Initialize logging handler g_log_set_default_handler(logFilter, NULL); #if defined(TARGET_DESKTOP) // use terminal logging when running on desktop settings->logger_useTerminal = true; #endif // disable color logging using an environment variable. Useful when run from QtCreator const char* useColor = ::getenv("COLOR_LOGGING"); if (useColor) settings->logger_useColor = (useColor[0] != 0 && useColor[0] != '0'); HostBase* host = HostBase::instance(); // the resolution is just a hint, the actual // resolution may get picked up from the fb driver on arm host->init(settings->displayWidth, settings->displayHeight); #if defined(TARGET_DEVICE) && defined(HAVE_OPENGL) if (settings->forceSoftwareRendering) ::setenv("QT_QPA_PLATFORM", "palm-soft", 0); else ::setenv("QT_QPA_PLATFORM", "palm", 0); #else // Do not override the value if the variable exists ::setenv("QT_QPA_PLATFORM", "palm", 0); #endif #if defined(TARGET_DEVICE) && defined(HAVE_OPENGL) if (!settings->forceSoftwareRendering) ::setenv("QWS_DISPLAY", "egl", 1); #endif // Install the handler for signals that we want to trap: // Note: We install the handlers after we initialize the setting because // we may do something different depending on the settings values. installOuterCrashHandler(SIGILL); installOuterCrashHandler(SIGSEGV); installOuterCrashHandler(SIGTERM); // Not needed anymore? ::prctl(PR_SET_NAME, (unsigned long) "WebAppMgr", 0, 0, 0); ::prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); const HostInfo* info = &(HostBase::instance()->getInfo()); WebAppManager::instance()->setHostInfo(info); initMallocStatsCb(WebAppManager::instance()->mainLoop(), s_mallocStatsInterval); logInit(); // Start the Browser App Launcher #ifdef NO_WEBKIT_INIT //WindowServer::instance()->bootupFinished(); #else WebAppManager::instance()->run(); // Sync execution of the task #endif return 0; }
/** * Handle a process signal * * Steps are as follows: * - Attempt to let WebKit handle the signal. If it does, keep running and reinstall the handler. Otherwise, continue. * - Log crash diagnostics. * - If debugging is enabled, start an infinite loop to give gdb a chance to connect and see what's going on. * * @param sig The signal which triggered this handler * @param info Pointer to information about the signal * @param data Pointer to a ucontext_t with info on the crashing process */ static void outerCrashHandler(int sig, siginfo_t *info, void *data) { // Let webkit handle the crash if it wants to. If it returns true, // the signal has been handled. Just return: if (Palm::WebGlobal::handleSignal(sig, info, data)) { // Webkit side has handled the signal. Hence, we're not going to crash, // and will keep running. Therefore, we need to re-install the signal // handler: installOuterCrashHandler(sig); return; } // Otherwise, report the crash diagnostics: struct sigaction previous_crash_action; installInnerCrashHandler(sig, &previous_crash_action); #if defined(TARGET_DESKTOP) const char *const logFileName = "/tmp/lunasysmgr.log"; #else const char *logFileName = "/var/log/lunasysmgr.log"; char logFileNameBuffer[64]; if (Settings::LunaSettings()->debug_doVerboseCrashLogging) { snprintf(logFileNameBuffer, 64, "/media/internal/lunasysmgr.%d.verbose.log", sysmgrPid); logFileName = logFileNameBuffer; } #endif crashLogFD = open(logFileName, O_WRONLY | O_CREAT | O_TRUNC); #if 0 // Disable until we can do this without calling malloc and free: int memTotal, memFree, swapTotal, swapFree, memchuteFree, memUsage; #endif if (crashLogFD != -1) { crash_printf("LunaSysMgr.%d: Caught signal %d\n", sysmgrPid, sig); crash_flush(); // Dump the register context for the crash to the logs: logCrashRegisterContext(sig, info, data); // Let webkit do some analysis on the crash information and log report // as appropriate: #ifndef FIX_FOR_QT Palm::WebGlobal::reportCrashDiagnostics(sig, info, data, crashLogFD, Settings::LunaSettings()->debug_doVerboseCrashLogging, &hasCrashedInCrashHandler); #endif crash_flush(); crash_printf("LunaSysMgr.%d: Caught signal %d END report\n", sysmgrPid, sig); crash_flush(); } // If the option to debug crashes is enabled, then we'll enter an infinite // loop here to capture the crash conditions until a gdb session can be // attached. // // By default, this option is disabled, and the crashHandler will return // to the crashing instruction. Since the crashHandler is set up to // fire only once (see SA_RESETHAND option which resets the handler after // it has fired), when we return to the crashing pc, we'll fault again. // This time, the fault will be handled by the default system handler and // generate a core or minicore as appropriate. if (debugCrashes || Settings::LunaSettings()->debug_loopInCrashHandler) { // Infinite loop until we turn off stayInLoop using gdb: while (stayInLoop) { // If we get here, sit and wait for someone to come and debug // this device. } } // Restore the previous handler before we return. Otherwise, the inner // handler will perpetually skip over faulting addresses: sigaction(sig, &previous_crash_action, NULL); // Close the file: fsync(crashLogFD); close(crashLogFD); crashLogFD = -1; }