{
    ::exit(exitCode);
}


static
bool installAbortHandler()
{
    // If it didn't succeed there's not much we can do,
    // so don't check result.
    ::signal(SIGABRT, &sigAbortHandler);
    return true;
}


static bool const abortHandlerInstalled = installAbortHandler();


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


//- Get last windows api error from GetLastError
std::string MSwindows::getLastError()
{
    // Based on an example at:
    // http://msdn2.microsoft.com/en-us/library/ms680582(VS.85).aspx

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError();
Example #2
0
VariantMap
initializeAgent(int argc, char *argv[], const char *processName) {
	TRACE_POINT();
	VariantMap options;
	
	ignoreSigpipe();
	installAbortHandler();
	setup_syscall_interruption_support();
	setvbuf(stdout, NULL, _IONBF, 0);
	setvbuf(stderr, NULL, _IONBF, 0);
	
	try {
		if (argc == 1) {
			int ret = fcntl(FEEDBACK_FD, F_GETFL);
			if (ret == -1) {
				if (errno == EBADF) {
					fprintf(stderr,
						"You're not supposed to start this program from the command line. "
						"It's used internally by Phusion Passenger.\n");
					exit(1);
				} else {
					int e = errno;
					fprintf(stderr,
						"Encountered an error in feedback file descriptor 3: %s (%d)\n",
							strerror(e), e);
					exit(1);
				}
			} else {
				_feedbackFdAvailable = true;
				options.readFrom(FEEDBACK_FD);
				if (options.getBool("fire_and_forget", false)) {
					_feedbackFdAvailable = false;
					close(FEEDBACK_FD);
				}
			}
		} else {
			options.readFrom((const char **) argv + 1, argc - 1);
		}
		
		setLogLevel(options.getInt("log_level", false, 0));
		if (!options.get("debug_log_file", false).empty()) {
			if (strcmp(processName, "PassengerWatchdog") == 0) {
				/* Have the watchdog set STDOUT and STDERR to the debug
				 * log file so that system abort() calls that stuff
				 * are properly logged.
				 */
				string filename = options.get("debug_log_file");
				options.erase("debug_log_file");
				
				int fd = open(filename.c_str(), O_CREAT | O_WRONLY | O_APPEND, 0644);
				if (fd == -1) {
					int e = errno;
					throw FileSystemException("Cannot open debug log file " +
						filename, e, filename);
				}
				
				dup2(fd, STDOUT_FILENO);
				dup2(fd, STDERR_FILENO);
				close(fd);
			} else {
				setDebugFile(options.get("debug_log_file").c_str());
			}
		}
	} catch (const tracable_exception &e) {
		P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace());
		exit(1);
	}
	
	// Change process title.
	strncpy(argv[0], processName, strlen(argv[0]));
	for (int i = 1; i < argc; i++) {
		memset(argv[i], '\0', strlen(argv[i]));
	}
	
	return options;
}
Example #3
0
VariantMap
initializeAgent(int argc, char *argv[], const char *processName) {
	VariantMap options;
	const char *seedStr;

	seedStr = getenv("PASSENGER_RANDOM_SEED");
	if (seedStr == NULL || *seedStr == '\0') {
		randomSeed = (unsigned int) time(NULL);
	} else {
		randomSeed = (unsigned int) atoll(seedStr);
	}
	srand(randomSeed);
	srandom(randomSeed);
	
	ignoreSigpipe();
	if (hasEnvOption("PASSENGER_ABORT_HANDLER", true)) {
		shouldDumpWithCrashWatch = hasEnvOption("PASSENGER_DUMP_WITH_CRASH_WATCH", true);
		beepOnAbort  = hasEnvOption("PASSENGER_BEEP_ON_ABORT", false);
		stopOnAbort = hasEnvOption("PASSENGER_STOP_ON_ABORT", false);
		IGNORE_SYSCALL_RESULT(pipe(emergencyPipe1));
		IGNORE_SYSCALL_RESULT(pipe(emergencyPipe2));
		installAbortHandler();
	}
	oxt::initialize();
	setup_syscall_interruption_support();
	if (getenv("PASSENGER_SIMULATE_SYSCALL_FAILURES")) {
		initializeSyscallFailureSimulation(processName);
	}
	setvbuf(stdout, NULL, _IONBF, 0);
	setvbuf(stderr, NULL, _IONBF, 0);
	
	TRACE_POINT();
	try {
		if (argc == 1) {
			int e;

			switch (fdIsSocket(FEEDBACK_FD)) {
			case FISR_YES:
				_feedbackFdAvailable = true;
				options.readFrom(FEEDBACK_FD);
				if (options.getBool("fire_and_forget", false)) {
					_feedbackFdAvailable = false;
					close(FEEDBACK_FD);
				}
				break;
			case FISR_NO:
				fprintf(stderr,
					"You're not supposed to start this program from the command line. "
					"It's used internally by Phusion Passenger.\n");
				exit(1);
				break;
			case FISR_ERROR:
				e = errno;
				fprintf(stderr,
					"Encountered an error in feedback file descriptor 3: %s (%d)\n",
						strerror(e), e);
				exit(1);
				break;
			}
		} else {
			options.readFrom((const char **) argv + 1, argc - 1);
		}
		
		#ifdef __linux__
			if (options.has("passenger_root")) {
				ResourceLocator locator(options.get("passenger_root", true));
				string ruby = options.get("default_ruby", false, DEFAULT_RUBY);
				string path = ruby + " \"" + locator.getHelperScriptsDir() +
					"/backtrace-sanitizer.rb\"";
				backtraceSanitizerCommand = strdup(path.c_str());
			}
		#endif
		if (backtraceSanitizerCommand == NULL) {
			backtraceSanitizerCommand = "c++filt -n";
			backtraceSanitizerPassProgramInfo = false;
		}

		options.setDefaultInt("log_level", DEFAULT_LOG_LEVEL);
		setLogLevel(options.getInt("log_level"));
		if (!options.get("debug_log_file", false).empty()) {
			if (strcmp(processName, "PassengerWatchdog") == 0) {
				/* Have the watchdog set STDOUT and STDERR to the debug
				 * log file so that system abort() calls that stuff
				 * are properly logged.
				 */
				string filename = options.get("debug_log_file");
				options.erase("debug_log_file");
				
				int fd = open(filename.c_str(), O_CREAT | O_WRONLY | O_APPEND, 0644);
				if (fd == -1) {
					int e = errno;
					throw FileSystemException("Cannot open debug log file " +
						filename, e, filename);
				}
				
				dup2(fd, STDOUT_FILENO);
				dup2(fd, STDERR_FILENO);
				close(fd);
			} else {
				setDebugFile(options.get("debug_log_file").c_str());
			}
		}
	} catch (const tracable_exception &e) {
		P_ERROR("*** ERROR: " << e.what() << "\n" << e.backtrace());
		exit(1);
	}
	
	// Change process title.
	argv0 = strdup(argv[0]);
	strncpy(argv[0], processName, strlen(argv[0]));
	for (int i = 1; i < argc; i++) {
		memset(argv[i], '\0', strlen(argv[i]));
	}

	P_DEBUG("Random seed: " << randomSeed);
	
	return options;
}