Esempio n. 1
0
	virtual void execProgram() const {
		if (hasEnvOption("PASSENGER_RUN_HELPER_AGENT_IN_VALGRIND", false)) {
			execlp("valgrind", "valgrind", "--dsymutil=yes",
				helperAgentFilename.c_str(), (char *) 0);
		} else {
			execl(helperAgentFilename.c_str(), "PassengerHelperAgent", (char *) 0);
		}
	}
Esempio n. 2
0
	virtual void execProgram() const {
		if (hasEnvOption("PASSENGER_RUN_CORE_IN_VALGRIND", false)) {
			execlp("valgrind", "valgrind", "--dsymutil=yes", "--track-origins=yes", "--leak-check=full",
				agentFilename.c_str(), "core",
				// Some extra space to allow the child process to change its process title.
				"                                                ", (char *) 0);
		} else {
			execl(agentFilename.c_str(), AGENT_EXE, "core",
				// Some extra space to allow the child process to change its process title.
				"                                                ", (char *) 0);
		}
	}
Esempio n. 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;
}
Esempio n. 4
0
VariantMap
initializeAgent(int argc, char *argv[], const char *processName) {
	TRACE_POINT();
	VariantMap options;
	
	ignoreSigpipe();
	if (hasEnvOption("PASSENGER_ABORT_HANDLER", true)) {
		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;
}