bool Process::failed() // ---------------------------------------------------------------------------- // Return true if the process crashed or returned a non-zero value // ---------------------------------------------------------------------------- { return (exitStatus() != QProcess::NormalExit) || exitCode(); }
bool Process::done(text *errors, text *output) // ---------------------------------------------------------------------------- // Return true if the process was successful // ---------------------------------------------------------------------------- { bool ok = true; // Flush streambuf if (pbase()) if (sync()) ok = false; delete[] pbase(); setp(NULL, NULL); // Close QProcess closeWriteChannel(); if (state() != NotRunning) if (!waitForFinished()) ok = false; int rc = exitCode(); if (rc) ok = false; if (output) *output = +out; if (errors) *errors = +err; return ok; }
void Task::runCloseAllVolumeTask() { m_table->setEnabled( false ) ; sleep( 1 ) ; // for ui effect int volumeCount = m_table->rowCount() ; if( volumeCount > 0 ){ QVector< QTableWidgetItem * > tableItems( volumeCount ) ; QTableWidgetItem ** it = tableItems.data() ; for( int i = 0 ; i < volumeCount ; i++ ){ *( it + i ) = m_table->item( i,0 ) ; } for( QTableWidgetItem * it : tableItems ){ QString device = it->text().replace( "\"","\"\"\"" ) ; auto r = utility::Task( QString( "%1 -q -d \"%2\"" ).arg( ZULUCRYPTzuluCrypt ).arg( device ) ) ; emit taskResult( it,r.exitCode() ) ; sleep( 1 ) ; // for ui effect } } m_table->setEnabled( true ) ; }
virtual ptr<Process> start() override { auto builder = _connector->processBuilder(); // Prepare the OAR command if (detach) throw illegal_argument_error("Cannot run OAR undetached"); auto pushstream = [&] (Redirect & r) { switch (r.type) { case Redirection::INHERIT: case Redirection::PIPE: throw illegal_argument_error("Cannot run OAR undetached"); case Redirection::NONE: builder->command.push_back("/dev/null"); break; case Redirection::FILE: builder->command.push_back(r.path); break; } }; auto process = builder->start(); builder->command.push_back("oarsub"); builder->command.push_back("-O"); pushstream(builder->stdout); builder->command.push_back("-E"); pushstream(builder->stderr); builder->detach = false; std::ostringstream oss; bool first; for(auto c: command) { if (first) first = false; else oss << " "; oss << "\"" << ShScriptBuilder::protect_quoted(c) << "\""; } builder->command.push_back(oss.str()); // Execute it EnvMatcher matcher("\nOAR_JOB_ID="); builder->stdout = Redirect::pipe([&](const char * bytes, size_t n) { matcher.process(bytes, n); }); int code = process->exitCode(); if (code != 0) { throw exception(fmt::format("Could not launch OAR process {}", code)); } if (matcher.value.empty()) throw exception("Could not get the OAR job ID"); return mkptr<OARProcess>(matcher.value, _connector); }
bool TempMemory::isThreadDead() const { HANDLE threadHandle(OpenThread(THREAD_QUERY_INFORMATION, FALSE, threadId_)); if(threadHandle) { DWORD exitCode(0); BOOL result = GetExitCodeThread(threadHandle, &exitCode); CloseHandle(threadHandle); if(result != 0) { if(exitCode == STILL_ACTIVE) { // still running return false; } else { // it's gone return true; } } else { // fail safe and don't delete in this case return false; } } else { // fail safe and don't delete in this case return false; } }
QString IpProcess::executeSynchronous(const QString &program, const QStringList &arguments) { QString empty(""); QString result(""); printCmdLine(program, arguments); if (arguments.count() > 0) { start(program, arguments); } else { start(program); } if (! waitForStarted()) return empty; closeWriteChannel(); int secondsToWait = 30; if (! waitForFinished(secondsToWait * 1000)) return empty; // exit code of zero means command completed ok // and that output is from stdout - error output is on stderrs if ( (exitCode() == 0) && (errStr.isEmpty()) ) { result = QString(QString(readAllStandardOutput())); } else { result = QString(QString(readAllStandardError())); } if (result.isEmpty()) { // result = parseErrorCode(); } // Send the result of executing the command emit cmdOutput(program, arguments, exitCode(), result); return QString(result); }
void Task::runExeTask() { auto r = utility::Task( m_exe ) ; m_status = r.exitCode() ; m_output = r.output() ; if( m_action == Task::closeVolumeTask ){ sleep( 1 ) ; // for UI effect } }
void KJavaProcess::slotExited() { int status = -1; if ( exitStatus() == NormalExit ) { status = exitCode(); } kDebug(6100) << "jvm exited with status " << status; emit exited(status); }
int KProcess::execute(int msecs) { start(); if (!waitForFinished(msecs)) { kill(); waitForFinished(-1); return -2; } return (exitStatus() == QProcess::NormalExit) ? exitCode() : -1; }
void ScProcess::postQuitNotification() { QString message; switch (exitStatus()) { case QProcess::CrashExit: message = tr("Interpreter has crashed or stopped forcefully. [Exit code: %1]\n").arg(exitCode()); break; default: message = tr("Interpreter has quit. [Exit code: %1]\n").arg(exitCode()); } emit scPost(message); }
std::string RunResult::str() const { if (exitCode() != 0) return "<failed>"; if (returnValues_.empty()) return "<nothing>"; std::ostringstream ret; for (RunReturn::const_iterator it = returnValues_.begin(); it != returnValues_.end(); ++it) ret << it->first << " =\t" << it->second << '\n'; return ret.str(); }
// // Perform the canonical last rites for a formerly alive child. // Requires master lock held throughout. // void Child::bury(int status) { assert(mState == alive); mState = dead; mStatus = status; mChildren().erase(mPid); #if !defined(NDEBUG) if (bySignal()) secdebug("unixchild", "%p (pid %d) died by signal %d%s", this, mPid, exitSignal(), coreDumped() ? " and dumped core" : ""); else secdebug("unixchild", "%p (pid %d) died by exit(%d)", this, mPid, exitCode()); #endif //NDEBUG }
void BaseShadow::logRequeueEvent( const char* reason ) { struct rusage run_remote_rusage; memset( &run_remote_rusage, 0, sizeof(struct rusage) ); run_remote_rusage = getRUsage(); int exit_reason = getExitReason(); JobEvictedEvent event; event.terminate_and_requeued = true; if( exitedBySignal() ) { event.normal = false; event.signal_number = exitSignal(); } else { event.normal = true; event.return_value = exitCode(); } if( exit_reason == JOB_COREDUMPED ) { event.setCoreFile( core_file_name ); } if( reason ) { event.setReason( reason ); } // TODO: fill in local rusage // event.run_local_rusage = r; event.run_remote_rusage = run_remote_rusage; /* we want to log the events from the perspective of the user job, so if the shadow *sent* the bytes, then that means the user job *received* the bytes */ event.recvd_bytes = bytesSent(); event.sent_bytes = bytesReceived(); if (!uLog.writeEvent (&event,jobAd)) { dprintf( D_ALWAYS, "Unable to log ULOG_JOB_EVICTED " "(and requeued) event\n" ); } }
int main(int argc, char** argv) { RemoveCrashDump removeCrashDump; #ifdef OS_Darwin struct rlimit rlp; if (getrlimit(RLIMIT_NOFILE, &rlp) == 0) { if (rlp.rlim_cur < 1000) { rlp.rlim_cur = 1000; setrlimit(RLIMIT_NOFILE, &rlp); } } #endif Rct::findExecutablePath(*argv); bool daemon = false; Server::Options serverOpts; const char * runtimeDir = getenv("XDG_RUNTIME_DIR"); if (runtimeDir == NULL) { serverOpts.socketFile = String::format<128>("%s.rdm", Path::home().constData()); } else { serverOpts.socketFile = String::format<1024>("%s/rdm.socket", runtimeDir); } serverOpts.jobCount = std::max(2, ThreadPool::idealThreadCount()); serverOpts.headerErrorJobCount = -1; serverOpts.rpVisitFileTimeout = DEFAULT_RP_VISITFILE_TIMEOUT; serverOpts.rpIndexDataMessageTimeout = DEFAULT_RP_INDEXER_MESSAGE_TIMEOUT; serverOpts.rpConnectTimeout = DEFAULT_RP_CONNECT_TIMEOUT; serverOpts.rpConnectAttempts = DEFAULT_RP_CONNECT_ATTEMPTS; serverOpts.maxFileMapScopeCacheSize = DEFAULT_RDM_MAX_FILE_MAP_CACHE_SIZE; serverOpts.errorLimit = DEFAULT_ERROR_LIMIT; serverOpts.rpNiceValue = INT_MIN; serverOpts.options = Server::Wall|Server::SpellChecking; serverOpts.maxCrashCount = DEFAULT_MAX_CRASH_COUNT; serverOpts.completionCacheSize = DEFAULT_COMPLETION_CACHE_SIZE; serverOpts.maxIncludeCompletionDepth = DEFAULT_MAX_INCLUDE_COMPLETION_DEPTH; serverOpts.rp = defaultRP(); strcpy(crashDumpFilePath, "crash.dump"); #ifdef FILEMANAGER_OPT_IN serverOpts.options |= Server::NoFileManagerWatch; #endif // #ifndef NDEBUG // serverOpts.options |= Server::SuspendRPOnCrash; // #endif serverOpts.dataDir = String::format<128>("%s.rtags", Path::home().constData()); if (!serverOpts.dataDir.exists()) { const char * dataDir = getenv("XDG_CACHE_HOME"); serverOpts.dataDir = dataDir ? dataDir : Path::home() + ".cache"; serverOpts.dataDir += "/rtags/"; serverOpts.dataDir.mkdir(Path::Recursive); } Path logFile; Flags<LogFlag> logFlags = DontRotate|LogStderr; LogLevel logLevel(LogLevel::Error); LogLevel logFileLogLevel(LogLevel::Error); bool sigHandler = true; assert(Path::home().endsWith('/')); int inactivityTimeout = 0; const std::initializer_list<CommandLineParser::Option<OptionType> > opts = { { None, 0, 0, CommandLineParser::NoValue, "Options:" }, { Help, "help", 'h', CommandLineParser::NoValue, "Display this page." }, { Version, "version", 0, CommandLineParser::NoValue, "Display version." }, { IncludePath, "include-path", 'I', CommandLineParser::Required, "Add additional include path to clang." }, { Isystem, "isystem", 's', CommandLineParser::Required, "Add additional system include path to clang." }, { Define, "define", 'D', CommandLineParser::Required, "Add additional define directive to clang." }, { DefaultArgument, "default-argument", 0, CommandLineParser::Required, "Add additional argument to clang." }, { LogFile, "log-file", 'L', CommandLineParser::Required, "Log to this file." }, { CrashDumpFile, "crash-dump-file", 0, CommandLineParser::Required, "File to dump crash log to (default is <datadir>/crash.dump)." }, { SetEnv, "setenv", 'e', CommandLineParser::Required, "Set this environment variable (--setenv \"foobar=1\")." }, { NoWall, "no-Wall", 'W', CommandLineParser::NoValue, "Don't use -Wall." }, { Weverything, "Weverything", 'u', CommandLineParser::NoValue, "Use -Weverything." }, { Verbose, "verbose", 'v', CommandLineParser::NoValue, "Change verbosity, multiple -v's are allowed." }, { JobCount, "job-count", 'j', CommandLineParser::Required, String::format("Spawn this many concurrent processes for indexing (default %d).", std::max(2, ThreadPool::idealThreadCount())) }, { HeaderErrorJobCount, "header-error-job-count", 'H', CommandLineParser::Required, "Allow this many concurrent header error jobs (default std::max(1, --job-count / 2))." }, { Test, "test", 't', CommandLineParser::Required, "Run this test." }, { TestTimeout, "test-timeout", 'z', CommandLineParser::Required, "Timeout for test to complete." }, { CleanSlate, "clean-slate", 'C', CommandLineParser::NoValue, "Clear out all data." }, { DisableSigHandler, "disable-sighandler", 'x', CommandLineParser::NoValue, "Disable signal handler to dump stack for crashes." }, { Silent, "silent", 'S', CommandLineParser::NoValue, "No logging to stdout/stderr." }, { ExcludeFilter, "exclude-filter", 'X', CommandLineParser::Required, "Files to exclude from rdm, default \"" DEFAULT_EXCLUDEFILTER "\"." }, { SocketFile, "socket-file", 'n', CommandLineParser::Required, "Use this file for the server socket (default ~/.rdm)." }, { DataDir, "data-dir", 'd', CommandLineParser::Required, "Use this directory to store persistent data (default $XDG_CACHE_HOME/rtags otherwise ~/.cache/rtags)." }, { IgnorePrintfFixits, "ignore-printf-fixits", 'F', CommandLineParser::NoValue, "Disregard any clang fixit that looks like it's trying to fix format for printf and friends." }, { ErrorLimit, "error-limit", 'f', CommandLineParser::Required, "Set error limit to argument (-ferror-limit={arg} (default " STR(DEFAULT_ERROR_LIMIT) ")." }, { BlockArgument, "block-argument", 'G', CommandLineParser::Required, "Block this argument from being passed to clang. E.g. rdm --block-argument -fno-inline" }, { NoSpellChecking, "no-spell-checking", 'l', CommandLineParser::NoValue, "Don't pass -fspell-checking." }, { LargeByValueCopy, "large-by-value-copy", 'r', CommandLineParser::Required, "Use -Wlarge-by-value-copy=[arg] when invoking clang." }, { AllowMultipleSources, "allow-multiple-sources", 'm', CommandLineParser::NoValue, "Don't merge source files added with -c." }, { NoStartupProject, "no-startup-project", 'o', CommandLineParser::NoValue, "Don't restore the last current project on startup." }, { NoNoUnknownWarningsOption, "no-no-unknown-warnings-option", 'Y', CommandLineParser::NoValue, "Don't pass -Wno-unknown-warning-option." }, { IgnoreCompiler, "ignore-compiler", 'b', CommandLineParser::Required, "Ignore this compiler." }, { CompilerWrappers, "compiler-wrappers", 0, CommandLineParser::Required, "Consider these filenames compiler wrappers (split on ;), default " DEFAULT_COMPILER_WRAPPERS "\"." }, { WatchSystemPaths, "watch-system-paths", 'w', CommandLineParser::NoValue, "Watch system paths for changes." }, { RpVisitFileTimeout, "rp-visit-file-timeout", 'Z', CommandLineParser::Required, "Timeout for rp visitfile commands in ms (0 means no timeout) (default " STR(DEFAULT_RP_VISITFILE_TIMEOUT) ")." }, { RpIndexerMessageTimeout, "rp-indexer-message-timeout", 'T', CommandLineParser::Required, "Timeout for rp indexer-message in ms (0 means no timeout) (default " STR(DEFAULT_RP_INDEXER_MESSAGE_TIMEOUT) ")." }, { RpConnectTimeout, "rp-connect-timeout", 'O', CommandLineParser::Required, "Timeout for connection from rp to rdm in ms (0 means no timeout) (default " STR(DEFAULT_RP_CONNECT_TIMEOUT) ")." }, { RpConnectAttempts, "rp-connect-attempts", 0, CommandLineParser::Required, "Number of times rp attempts to connect to rdm before giving up. (default " STR(DEFAULT_RP_CONNECT_ATTEMPTS) ")." }, { RpNiceValue, "rp-nice-value", 'a', CommandLineParser::Required, "Nice value to use for rp (nice(2)) (default is no nicing)." }, { SuspendRpOnCrash, "suspend-rp-on-crash", 'q', CommandLineParser::NoValue, "Suspend rp in SIGSEGV handler (default " DEFAULT_SUSPEND_RP ")." }, { RpLogToSyslog, "rp-log-to-syslog", 0, CommandLineParser::NoValue, "Make rp log to syslog." }, { StartSuspended, "start-suspended", 'Q', CommandLineParser::NoValue, "Start out suspended (no reindexing enabled)." }, { SeparateDebugAndRelease, "separate-debug-and-release", 'E', CommandLineParser::NoValue, "Normally rdm doesn't consider release and debug as different builds. Pass this if you want it to." }, { Separate32BitAnd64Bit, "separate-32-bit-and-64-bit", 0, CommandLineParser::NoValue, "Normally rdm doesn't consider -m32 and -m64 as different builds. Pass this if you want it to." }, { SourceIgnoreIncludePathDifferencesInUsr, "ignore-include-path-differences-in-usr", 0, CommandLineParser::NoValue, "Don't consider sources that only differ in includepaths within /usr (not including /usr/home/) as different builds." }, { MaxCrashCount, "max-crash-count", 'K', CommandLineParser::Required, "Max number of crashes before giving up a sourcefile (default " STR(DEFAULT_MAX_CRASH_COUNT) ")." }, { CompletionCacheSize, "completion-cache-size", 'i', CommandLineParser::Required, "Number of translation units to cache (default " STR(DEFAULT_COMPLETION_CACHE_SIZE) ")." }, { CompletionNoFilter, "completion-no-filter", 0, CommandLineParser::NoValue, "Don't filter private members and destructors from completions." }, { CompletionLogs, "completion-logs", 0, CommandLineParser::NoValue, "Log more info about completions." }, { MaxIncludeCompletionDepth, "max-include-completion-depth", 0, CommandLineParser::Required, "Max recursion depth for header completion (default " STR(DEFAULT_MAX_INCLUDE_COMPLETION_DEPTH) ")." }, { AllowWpedantic, "allow-Wpedantic", 'P', CommandLineParser::NoValue, "Don't strip out -Wpedantic. This can cause problems in certain projects." }, { AllowWErrorAndWFatalErrors, "allow-Werror", 0, CommandLineParser::NoValue, "Don't strip out -Werror and -Wfatal-errors. By default these are stripped out. " }, { EnableCompilerManager, "enable-compiler-manager", 'R', CommandLineParser::NoValue, "Query compilers for their actual include paths instead of letting clang use its own." }, { EnableNDEBUG, "enable-NDEBUG", 'g', CommandLineParser::NoValue, "Don't remove -DNDEBUG from compile lines." }, { Progress, "progress", 'p', CommandLineParser::NoValue, "Report compilation progress in diagnostics output." }, { MaxFileMapCacheSize, "max-file-map-cache-size", 'y', CommandLineParser::Required, "Max files to cache per query (Should not exceed maximum number of open file descriptors allowed per process) (default " STR(DEFAULT_RDM_MAX_FILE_MAP_CACHE_SIZE) ")." }, #ifdef FILEMANAGER_OPT_IN { FileManagerWatch, "filemanager-watch", 'M', CommandLineParser::NoValue, "Use a file system watcher for filemanager." }, #else { NoFileManagerWatch, "no-filemanager-watch", 'M', CommandLineParser::NoValue, "Don't use a file system watcher for filemanager." }, #endif { NoFileManager, "no-filemanager", 0, CommandLineParser::NoValue, "Don't scan project directory for files. (rc -P won't work)." }, { NoFileLock, "no-file-lock", 0, CommandLineParser::NoValue, "Disable file locking. Not entirely safe but might improve performance on certain systems." }, { PchEnabled, "pch-enabled", 0, CommandLineParser::NoValue, "Enable PCH (experimental)." }, { NoFilesystemWatcher, "no-filesystem-watcher", 'B', CommandLineParser::NoValue, "Disable file system watching altogether. Reindexing has to be triggered manually." }, { ArgTransform, "arg-transform", 'V', CommandLineParser::Required, "Use arg to transform arguments. [arg] should be executable with (execv(3))." }, { NoComments, "no-comments", 0, CommandLineParser::NoValue, "Don't parse/store doxygen comments." }, #ifdef RTAGS_HAS_LAUNCHD { Launchd, "launchd", 0, CommandLineParser::NoValue, "Run as a launchd job (use launchd API to retrieve socket opened by launchd on rdm's behalf)." }, #endif { InactivityTimeout, "inactivity-timeout", 0, CommandLineParser::Required, "Time in seconds after which rdm will quit if there's been no activity (N.B., once rdm has quit, something will need to re-run it!)." }, { Daemon, "daemon", 0, CommandLineParser::NoValue, "Run as daemon (detach from terminal)." }, { LogFileLogLevel, "log-file-log-level", 0, CommandLineParser::Required, "Log level for log file (default is error), options are: error, warning, debug or verbose-debug." }, { WatchSourcesOnly, "watch-sources-only", 0, CommandLineParser::NoValue, "Only watch source files (not dependencies)." }, { DebugLocations, "debug-locations", 0, CommandLineParser::NoValue, "Set debug locations." }, { ValidateFileMaps, "validate-file-maps", 0, CommandLineParser::NoValue, "Spend some time validating project data on startup." }, { TcpPort, "tcp-port", 0, CommandLineParser::Required, "Listen on this tcp socket (default none)." }, { RpPath, "rp-path", 0, CommandLineParser::Required, String::format<256>("Path to rp (default %s).", defaultRP().constData()) }, { LogTimestamp, "log-timestamp", 0, CommandLineParser::NoValue, "Add timestamp to logs." }, { LogFlushOption, "log-flush", 0, CommandLineParser::NoValue, "Flush stderr/stdout after each log." }, { SandboxRoot, "sandbox-root", 0, CommandLineParser::Required, "Create index using relative paths by stripping dir (enables copying of tag index db files without need to reindex)." }, { PollTimer, "poll-timer", 0, CommandLineParser::Required, "Poll the database of the current project every <arg> seconds. " }, { NoRealPath, "no-realpath", 0, CommandLineParser::NoValue, "Don't use realpath(3) for files" }, { Noop, "config", 'c', CommandLineParser::Required, "Use this file (instead of ~/.rdmrc)." }, { Noop, "no-rc", 'N', CommandLineParser::NoValue, "Don't load any rc files." } }; std::function<CommandLineParser::ParseStatus(OptionType type, String &&value, size_t &idx, const List<String> &args)> cb; cb = [&](OptionType type, String &&value, size_t &, const List<String> &) -> CommandLineParser::ParseStatus { switch (type) { case None: case Noop: break; case Help: { CommandLineParser::help(stdout, Rct::executablePath().fileName(), opts); return { String(), CommandLineParser::Parse_Ok }; } case Version: { fprintf(stdout, "%s\n", RTags::versionString().constData()); return { String(), CommandLineParser::Parse_Ok }; } case IncludePath: { serverOpts.includePaths.append(Source::Include(Source::Include::Type_Include, Path::resolved(value))); break; } case Isystem: { serverOpts.includePaths.append(Source::Include(Source::Include::Type_System, Path::resolved(value))); break; } case Define: { const size_t eq = value.indexOf('='); Source::Define def; if (eq == String::npos) { def.define = std::move(value); } else { def.define = value.left(eq); def.value = value.mid(eq + 1); } serverOpts.defines.append(def); break; } case DefaultArgument: { serverOpts.defaultArguments.append(std::move(value)); break; } case LogFile: { logFile = std::move(value); logFile.resolve(); logLevel = LogLevel::None; break; } case CrashDumpFile: { strncpy(crashDumpFilePath, value.constData(), sizeof(crashDumpFilePath) - 1); break; } case SetEnv: { putenv(&value[0]); break; } case NoWall: { serverOpts.options &= ~Server::Wall; break; } case Weverything: { serverOpts.options |= Server::Weverything; break; } case Verbose: { if (logLevel != LogLevel::None) ++logLevel; break; } case JobCount: { bool ok; serverOpts.jobCount = String(value).toULong(&ok); if (!ok) { return { String::format<1024>("Can't parse argument to -j %s. -j must be a positive integer.\n", value.constData()), CommandLineParser::Parse_Error }; } break; } case HeaderErrorJobCount: { bool ok; serverOpts.headerErrorJobCount = String(value).toULong(&ok); if (!ok) { return { String::format<1024>("Can't parse argument to -H %s. -H must be a positive integer.", value.constData()), CommandLineParser::Parse_Error }; } break; } case Test: { Path test(value); if (!test.resolve() || !test.isFile()) { return { String::format<1024>("%s doesn't seem to be a file", value.constData()), CommandLineParser::Parse_Error }; } serverOpts.tests += test; break; } case TestTimeout: { serverOpts.testTimeout = atoi(value.constData()); if (serverOpts.testTimeout <= 0) { return { String::format<1024>("Invalid argument to -z %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case PollTimer: { serverOpts.pollTimer = atoi(value.constData()); if (serverOpts.pollTimer < 0) { return { String::format<1024>("Invalid argument to --poll-timer %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case CleanSlate: { serverOpts.options |= Server::ClearProjects; break; } case DisableSigHandler: { sigHandler = false; break; } case Silent: { logLevel = LogLevel::None; break; } case ExcludeFilter: { serverOpts.excludeFilters += String(value).split(';'); break; } case SocketFile: { serverOpts.socketFile = std::move(value); serverOpts.socketFile.resolve(); break; } case DataDir: { serverOpts.dataDir = String::format<128>("%s", Path::resolved(value).constData()); break; } case IgnorePrintfFixits: { serverOpts.options |= Server::IgnorePrintfFixits; break; } case ErrorLimit: { bool ok; serverOpts.errorLimit = String(value).toULong(&ok); if (!ok) { return { String::format<1024>("Can't parse argument to --error-limit %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case BlockArgument: { serverOpts.blockedArguments << value; break; } case NoSpellChecking: { serverOpts.options &= ~Server::SpellChecking; break; } case LargeByValueCopy: { int large = atoi(value.constData()); if (large <= 0) { return { String::format<1024>("Can't parse argument to -r %s", value.constData()), CommandLineParser::Parse_Error }; } serverOpts.defaultArguments.append("-Wlarge-by-value-copy=" + String(value)); // ### not quite working break; } case AllowMultipleSources: { serverOpts.options |= Server::AllowMultipleSources; break; } case NoStartupProject: { serverOpts.options |= Server::NoStartupCurrentProject; break; } case NoNoUnknownWarningsOption: { serverOpts.options |= Server::NoNoUnknownWarningsOption; break; } case IgnoreCompiler: { serverOpts.ignoredCompilers.insert(Path::resolved(value)); break; } case CompilerWrappers: { serverOpts.compilerWrappers = String(value).split(";", String::SkipEmpty).toSet(); break; } case WatchSystemPaths: { serverOpts.options |= Server::WatchSystemPaths; break; } case RpVisitFileTimeout: { serverOpts.rpVisitFileTimeout = atoi(value.constData()); if (serverOpts.rpVisitFileTimeout < 0) { return { String::format<1024>("Invalid argument to -Z %s", value.constData()), CommandLineParser::Parse_Error }; } if (!serverOpts.rpVisitFileTimeout) serverOpts.rpVisitFileTimeout = -1; break; } case RpIndexerMessageTimeout: { serverOpts.rpIndexDataMessageTimeout = atoi(value.constData()); if (serverOpts.rpIndexDataMessageTimeout <= 0) { return { String::format<1024>("Can't parse argument to -T %s.", value.constData()), CommandLineParser::Parse_Error }; } break; } case RpConnectTimeout: { serverOpts.rpConnectTimeout = atoi(value.constData()); if (serverOpts.rpConnectTimeout < 0) { return { String::format<1024>("Invalid argument to -O %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case RpConnectAttempts: { serverOpts.rpConnectAttempts = atoi(value.constData()); if (serverOpts.rpConnectAttempts <= 0) { return { String::format<1024>("Invalid argument to --rp-connect-attempts %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case RpNiceValue: { bool ok; serverOpts.rpNiceValue = value.toLong(&ok); if (!ok) { return { String::format<1024>("Can't parse argument to -a %s.", value.constData()), CommandLineParser::Parse_Error }; } break; } case SuspendRpOnCrash: { serverOpts.options |= Server::SuspendRPOnCrash; break; } case RpLogToSyslog: { serverOpts.options |= Server::RPLogToSyslog; break; } case StartSuspended: { serverOpts.options |= Server::StartSuspended; break; } case SeparateDebugAndRelease: { serverOpts.options |= Server::SeparateDebugAndRelease; break; } case Separate32BitAnd64Bit: { serverOpts.options |= Server::Separate32BitAnd64Bit; break; } case SourceIgnoreIncludePathDifferencesInUsr: { serverOpts.options |= Server::SourceIgnoreIncludePathDifferencesInUsr; break; } case MaxCrashCount: { serverOpts.maxCrashCount = atoi(value.constData()); if (serverOpts.maxCrashCount <= 0) { return { String::format<1024>("Invalid argument to -K %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case CompletionCacheSize: { serverOpts.completionCacheSize = atoi(value.constData()); if (serverOpts.completionCacheSize <= 0) { return { String::format<1024>("Invalid argument to -i %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case CompletionNoFilter: { serverOpts.options |= Server::CompletionsNoFilter; break; } case CompletionLogs: { serverOpts.options |= Server::CompletionLogs; break; } case MaxIncludeCompletionDepth: { serverOpts.maxIncludeCompletionDepth = strtoul(value.constData(), 0, 10); break; } case AllowWpedantic: { serverOpts.options |= Server::AllowPedantic; break; } case AllowWErrorAndWFatalErrors: { serverOpts.options |= Server::AllowWErrorAndWFatalErrors; break; } case EnableCompilerManager: { serverOpts.options |= Server::EnableCompilerManager; break; } case EnableNDEBUG: { serverOpts.options |= Server::EnableNDEBUG; break; } case Progress: { serverOpts.options |= Server::Progress; break; } case MaxFileMapCacheSize: { serverOpts.maxFileMapScopeCacheSize = atoi(value.constData()); if (serverOpts.maxFileMapScopeCacheSize <= 0) { return { String::format<1024>("Invalid argument to -y %s", value.constData()), CommandLineParser::Parse_Error }; } break; } #ifdef FILEMANAGER_OPT_IN case FileManagerWatch: { serverOpts.options &= ~Server::NoFileManagerWatch; break; } #else case NoFileManagerWatch: { serverOpts.options |= Server::NoFileManagerWatch; break; } #endif case NoFileManager: { serverOpts.options |= Server::NoFileManager; break; } case NoFileLock: { serverOpts.options |= Server::NoFileLock; break; } case PchEnabled: { serverOpts.options |= Server::PCHEnabled; break; } case NoFilesystemWatcher: { serverOpts.options |= Server::NoFileSystemWatch; break; } case ArgTransform: { serverOpts.argTransform = Process::findCommand(value); if (!value.isEmpty() && serverOpts.argTransform.isEmpty()) { return { String::format<1024>("Invalid argument to -V. Can't resolve %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case NoComments: { serverOpts.options |= Server::NoComments; break; } #ifdef RTAGS_HAS_LAUNCHD case Launchd: { serverOpts.options |= Server::Launchd; break; } #endif case InactivityTimeout: { inactivityTimeout = atoi(value.constData()); // seconds. if (inactivityTimeout <= 0) { return { String::format<1024>("Invalid argument to --inactivity-timeout %s", value.constData()), CommandLineParser::Parse_Error }; } break; } case Daemon: { daemon = true; logLevel = LogLevel::None; break; } case LogFileLogLevel: { if (!strcasecmp(value.constData(), "verbose-debug")) { logFileLogLevel = LogLevel::VerboseDebug; } else if (!strcasecmp(value.constData(), "debug")) { logFileLogLevel = LogLevel::Debug; } else if (!strcasecmp(value.constData(), "warning")) { logFileLogLevel = LogLevel::Warning; } else if (!strcasecmp(value.constData(), "error")) { logFileLogLevel = LogLevel::Error; } else { return { String::format<1024>("Unknown log level: %s options are error, warning, debug or verbose-debug", value.constData()), CommandLineParser::Parse_Error }; } break; } case WatchSourcesOnly: { serverOpts.options |= Server::WatchSourcesOnly; break; } case DebugLocations: { if (value == "clear" || value == "none") { serverOpts.debugLocations.clear(); } else { serverOpts.debugLocations << value; } break; } case ValidateFileMaps: { serverOpts.options |= Server::ValidateFileMaps; break; } case TcpPort: { serverOpts.tcpPort = atoi(value.constData()); if (!serverOpts.tcpPort) { return { String::format<1024>("Invalid port %s for --tcp-port", value.constData()), CommandLineParser::Parse_Error }; } break; } case RpPath: { serverOpts.rp = std::move(value); if (serverOpts.rp.isFile()) { serverOpts.rp.resolve(); } else { return { String::format<1024>("%s is not a file", value.constData()), CommandLineParser::Parse_Error }; } break; } case LogTimestamp: { logFlags |= LogTimeStamp; break; } case LogFlushOption: { logFlags |= LogFlush; break; } case SandboxRoot: { serverOpts.sandboxRoot = std::move(value); if (!serverOpts.sandboxRoot.endsWith('/')) serverOpts.sandboxRoot += '/'; if (!serverOpts.sandboxRoot.resolve() || !serverOpts.sandboxRoot.isDir()) { return { String::format<1024>("%s is not a valid directory for sandbox-root", serverOpts.sandboxRoot.constData()), CommandLineParser::Parse_Error }; } break; } case NoRealPath: { Path::setRealPathEnabled(false); serverOpts.options |= Server::NoRealPath; break; } } return { String(), CommandLineParser::Parse_Exec }; }; const std::initializer_list<CommandLineParser::Option<CommandLineParser::ConfigOptionType> > configOpts = { { CommandLineParser::Config, "config", 'c', CommandLineParser::Required, "Use this file (instead of ~/.rdmrc)." }, { CommandLineParser::NoRc, "no-rc", 'N', CommandLineParser::NoValue, "Don't load any rc files." } }; const CommandLineParser::ParseStatus status = CommandLineParser::parse<OptionType>(argc, argv, opts, NullFlags, cb, "rdm", configOpts); switch (status.status) { case CommandLineParser::Parse_Error: fprintf(stderr, "%s\n", status.error.constData()); return 1; case CommandLineParser::Parse_Ok: return 0; case CommandLineParser::Parse_Exec: break; } if (daemon) { switch (fork()) { case -1: fprintf(stderr, "Failed to fork (%d) %s\n", errno, strerror(errno)); return 1; case 0: setsid(); switch (fork()) { case -1: fprintf(stderr, "Failed to fork (%d) %s\n", errno, strerror(errno)); return 1; case 0: break; default: return 0; } break; default: return 0; } } if (serverOpts.excludeFilters.isEmpty()) serverOpts.excludeFilters = String(DEFAULT_EXCLUDEFILTER).split(';'); if (serverOpts.compilerWrappers.isEmpty()) serverOpts.compilerWrappers = String(DEFAULT_COMPILER_WRAPPERS).split(';').toSet(); if (!serverOpts.headerErrorJobCount) { serverOpts.headerErrorJobCount = std::max<size_t>(1, serverOpts.jobCount / 2); } else { serverOpts.headerErrorJobCount = std::min(serverOpts.headerErrorJobCount, serverOpts.jobCount); } if (sigHandler) { signal(SIGSEGV, signalHandler); signal(SIGBUS, signalHandler); signal(SIGILL, signalHandler); signal(SIGABRT, signalHandler); } if (!initLogging(argv[0], logFlags, logLevel, logFile, logFileLogLevel)) { fprintf(stderr, "Can't initialize logging with %d %s %s\n", logLevel.toInt(), logFile.constData(), logFlags.toString().constData()); return 1; } #ifdef RTAGS_HAS_LAUNCHD if (serverOpts.options & Server::Launchd) { // Clamp inactivity timeout. launchd starts to worry if the // process runs for less than 10 seconds. static const int MIN_INACTIVITY_TIMEOUT = 15; // includes // fudge factor. if (inactivityTimeout < MIN_INACTIVITY_TIMEOUT) { inactivityTimeout = MIN_INACTIVITY_TIMEOUT; fprintf(stderr, "launchd mode - clamped inactivity timeout to %d to avoid launchd warnings.\n", inactivityTimeout); } } #endif EventLoop::SharedPtr loop(new EventLoop); loop->init(EventLoop::MainEventLoop|EventLoop::EnableSigIntHandler|EventLoop::EnableSigTermHandler); auto server = std::make_shared<Server>(); if (!serverOpts.tests.isEmpty()) { char buf[1024]; Path path; while (true) { strcpy(buf, "/tmp/rtags-test-XXXXXX"); if (!mkdtemp(buf)) { fprintf(stderr, "Failed to mkdtemp (%d)\n", errno); return 1; } path = buf; path.resolve(); break; } serverOpts.dataDir = path; strcpy(buf, "/tmp/rtags-sock-XXXXXX"); const int fd = mkstemp(buf); if (fd == -1) { fprintf(stderr, "Failed to mkstemp (%d)\n", errno); return 1; } close(fd); serverOpts.socketFile = buf; serverOpts.socketFile.resolve(); } serverOpts.dataDir = serverOpts.dataDir.ensureTrailingSlash(); #ifdef HAVE_BACKTRACE if (strlen(crashDumpFilePath)) { if (crashDumpFilePath[0] != '/') { const String f = crashDumpFilePath; snprintf(crashDumpFilePath, sizeof(crashDumpFilePath), "%s%s", serverOpts.dataDir.constData(), f.constData()); } snprintf(crashDumpTempFilePath, sizeof(crashDumpTempFilePath), "%s.tmp", crashDumpFilePath); Path::mkdir(serverOpts.dataDir); crashDumpFile = fopen(crashDumpTempFilePath, "w"); if (!crashDumpFile) { fprintf(stderr, "Couldn't open temp file %s for write (%d)\n", crashDumpTempFilePath, errno); } } #endif if (!server->init(serverOpts)) { cleanupLogging(); return 1; } if (!serverOpts.tests.isEmpty()) { return server->runTests() ? 0 : 1; } loop->setInactivityTimeout(inactivityTimeout * 1000); loop->exec(); const int ret = server->exitCode(); server.reset(); cleanupLogging(); return ret; }
// kind defaults to US_NORMAL. void BaseShadow::logTerminateEvent( int exitReason, update_style_t kind ) { struct rusage run_remote_rusage; JobTerminatedEvent event; MyString corefile; memset( &run_remote_rusage, 0, sizeof(struct rusage) ); switch( exitReason ) { case JOB_EXITED: case JOB_COREDUMPED: break; default: dprintf( D_ALWAYS, "UserLog logTerminateEvent with unknown reason (%d), aborting\n", exitReason ); return; } if (kind == US_TERMINATE_PENDING) { int exited_by_signal = FALSE; int exit_signal = 0; int exit_code = 0; getJobAdExitedBySignal(jobAd, exited_by_signal); if (exited_by_signal == TRUE) { getJobAdExitSignal(jobAd, exit_signal); event.normal = false; event.signalNumber = exit_signal; } else { getJobAdExitCode(jobAd, exit_code); event.normal = true; event.returnValue = exit_code; } /* grab usage information out of job ad */ double real_value; if( jobAd->LookupFloat(ATTR_JOB_REMOTE_SYS_CPU, real_value) ) { run_remote_rusage.ru_stime.tv_sec = (time_t) real_value; } if( jobAd->LookupFloat(ATTR_JOB_REMOTE_USER_CPU, real_value) ) { run_remote_rusage.ru_utime.tv_sec = (time_t) real_value; } event.run_remote_rusage = run_remote_rusage; event.total_remote_rusage = run_remote_rusage; /* we want to log the events from the perspective of the user job, so if the shadow *sent* the bytes, then that means the user job *received* the bytes */ jobAd->LookupFloat(ATTR_BYTES_SENT, event.recvd_bytes); jobAd->LookupFloat(ATTR_BYTES_RECVD, event.sent_bytes); event.total_recvd_bytes = event.recvd_bytes; event.total_sent_bytes = event.sent_bytes; if( exited_by_signal == TRUE ) { jobAd->LookupString(ATTR_JOB_CORE_FILENAME, corefile); event.setCoreFile( corefile.Value() ); } if (!uLog.writeEvent (&event,jobAd)) { dprintf (D_ALWAYS,"Unable to log " "ULOG_JOB_TERMINATED event\n"); EXCEPT("UserLog Unable to log ULOG_JOB_TERMINATED event"); } return; } // the default kind == US_NORMAL path run_remote_rusage = getRUsage(); if( exitedBySignal() ) { event.normal = false; event.signalNumber = exitSignal(); } else { event.normal = true; event.returnValue = exitCode(); } // TODO: fill in local/total rusage // event.run_local_rusage = r; event.run_remote_rusage = run_remote_rusage; // event.total_local_rusage = r; event.total_remote_rusage = run_remote_rusage; /* we want to log the events from the perspective of the user job, so if the shadow *sent* the bytes, then that means the user job *received* the bytes */ event.recvd_bytes = bytesSent(); event.sent_bytes = bytesReceived(); event.total_recvd_bytes = prev_run_bytes_recvd + bytesSent(); event.total_sent_bytes = prev_run_bytes_sent + bytesReceived(); if( exitReason == JOB_COREDUMPED ) { event.setCoreFile( core_file_name ); } #if 1 set_usageAd(jobAd, &event.pusageAd); #else std::string resslist; if ( ! jobAd->LookupString("PartitionableResources", resslist)) resslist = "Cpus, Disk, Memory"; StringList reslist(resslist.c_str()); if (reslist.number() > 0) { int64_t int64_value = 0; ClassAd * puAd = new ClassAd(); reslist.rewind(); char * resname = NULL; while ((resname = reslist.next()) != NULL) { MyString attr; int64_value = -1; attr.formatstr("%s", resname); // provisioned value if (jobAd->LookupInteger(attr.Value(), int64_value)) { puAd->Assign(resname, int64_value); } // /*for debugging*/ else { puAd->Assign(resname, 42); } int64_value = -2; attr.formatstr("Request%s", resname); // requested value if (jobAd->LookupInteger(attr.Value(), int64_value)) { puAd->Assign(attr.Value(), int64_value); } // /*for debugging*/ else { puAd->Assign(attr.Value(), 99); } int64_value = -3; attr.formatstr("%sUsage", resname); // usage value if (jobAd->LookupInteger(attr.Value(), int64_value)) { puAd->Assign(attr.Value(), int64_value); } } event.pusageAd = puAd; } #endif if (!uLog.writeEvent (&event,jobAd)) { dprintf (D_ALWAYS,"Unable to log " "ULOG_JOB_TERMINATED event\n"); EXCEPT("UserLog Unable to log ULOG_JOB_TERMINATED event"); } }
void BaseShadow::terminateJob( update_style_t kind ) // has a default argument of US_NORMAL { int reason; bool signaled; MyString str; if( ! jobAd ) { dprintf( D_ALWAYS, "In terminateJob() w/ NULL JobAd!" ); } /* The first thing we do is record that we are in a termination pending state. */ if (kind == US_NORMAL) { str.formatstr("%s = TRUE", ATTR_TERMINATION_PENDING); jobAd->Insert(str.Value()); } if (kind == US_TERMINATE_PENDING) { // In this case, the job had already completed once and the // status had been saved to the job queue, however, for // some reason, the shadow didn't exit with a good value and // the job had been requeued. When this style of update // is used, it is a shortcut from the very birth of the shadow // to here, and so there will not be a remote resource or // anything like that set up. In this situation, we just // want to write the log event and mail the user and exit // with a good exit code so the schedd removes the job from // the queue. If for some reason the logging fails once again, // the process continues to repeat. // This means at least once semantics for the termination event // and user email, but at no time should the job actually execute // again. int exited_by_signal = FALSE; int exit_signal = 0; int exit_code = 0; getJobAdExitedBySignal(jobAd, exited_by_signal); if (exited_by_signal == TRUE) { getJobAdExitSignal(jobAd, exit_signal); } else { getJobAdExitCode(jobAd, exit_code); } if (exited_by_signal == TRUE) { reason = JOB_COREDUMPED; str.formatstr("%s = \"%s\"", ATTR_JOB_CORE_FILENAME, core_file_name); jobAd->Insert(str.Value()); } else { reason = JOB_EXITED; } dprintf( D_ALWAYS, "Job %d.%d terminated: %s %d\n", getCluster(), getProc(), exited_by_signal? "killed by signal" : "exited with status", exited_by_signal ? exit_signal : exit_code ); // write stuff to user log, but get values from jobad logTerminateEvent( reason, kind ); // email the user, but get values from jobad emailTerminateEvent( reason, kind ); DC_Exit( reason ); } // the default path when kind == US_NORMAL // cleanup this shadow (kill starters, etc) cleanUp(); reason = getExitReason(); signaled = exitedBySignal(); /* also store the corefilename into the jobad so we can recover this during a termination pending scenario. */ if( reason == JOB_COREDUMPED ) { str.formatstr("%s = \"%s\"", ATTR_JOB_CORE_FILENAME, getCoreName()); jobAd->Insert(str.Value()); } // Update final Job committed time int last_ckpt_time = 0; jobAd->LookupInteger(ATTR_LAST_CKPT_TIME, last_ckpt_time); int current_start_time = 0; jobAd->LookupInteger(ATTR_JOB_CURRENT_START_DATE, current_start_time); int int_value = (last_ckpt_time > current_start_time) ? last_ckpt_time : current_start_time; if( int_value > 0 ) { int job_committed_time = 0; jobAd->LookupInteger(ATTR_JOB_COMMITTED_TIME, job_committed_time); int delta = (int)time(NULL) - int_value; job_committed_time += delta; jobAd->Assign(ATTR_JOB_COMMITTED_TIME, job_committed_time); float slot_weight = 1; jobAd->LookupFloat(ATTR_JOB_MACHINE_ATTR_SLOT_WEIGHT0, slot_weight); float slot_time = 0; jobAd->LookupFloat(ATTR_COMMITTED_SLOT_TIME, slot_time); slot_time += slot_weight * delta; jobAd->Assign(ATTR_COMMITTED_SLOT_TIME, slot_time); } CommitSuspensionTime(jobAd); // update the job ad in the queue with some important final // attributes so we know what happened to the job when using // condor_history... if (m_num_cleanup_retries < 1 && param_boolean("SHADOW_TEST_JOB_CLEANUP_RETRY", false)) { dprintf( D_ALWAYS, "Testing Failure to perform final update to job queue!\n"); retryJobCleanup(); return; } if( !updateJobInQueue(U_TERMINATE) ) { dprintf( D_ALWAYS, "Failed to perform final update to job queue!\n"); retryJobCleanup(); return; } // Let's maximize the effectiveness of that queue synchronization and // only record the job as done if the update to the queue was successful. // If any of these next operations fail and the shadow exits with an // exit code which causes the job to get requeued, it will be in the // "terminate pending" state marked by the ATTR_TERMINATION_PENDING // attribute. dprintf( D_ALWAYS, "Job %d.%d terminated: %s %d\n", getCluster(), getProc(), signaled ? "killed by signal" : "exited with status", signaled ? exitSignal() : exitCode() ); // write stuff to user log: logTerminateEvent( reason ); // email the user emailTerminateEvent( reason ); if( reason == JOB_EXITED && claimIsClosing() ) { // Startd not accepting any more jobs on this claim. // We do this here to avoid having to treat this case // identically to JOB_EXITED in the code leading up to // this point. dprintf(D_FULLDEBUG,"Startd is closing claim, so no more jobs can be run on it.\n"); reason = JOB_EXITED_AND_CLAIM_CLOSING; } // try to get a new job for this shadow if( recycleShadow(reason) ) { // recycleShadow delete's this, so we must return immediately return; } // does not return. DC_Exit( reason ); }
void Task::openMountPointTask() { auto r = utility::Task( QString( "%1 \"%2\"" ).arg( m_folderOpener ).arg( m_mpoint ) ) ; m_exitCode = r.exitCode() ; m_exitStatus = r.exitStatus() ; }
int main(int argc, char *argv[], char* envp[]) { if (argc < 2) { fprintf(stderr, "Usage: %s prog_filename prog_aruments\n", argv[0]); return 3; } #if 0 if (strcmp(argv[1], "prog") != 0 && strcmp(argv[1], "all")) { fprintf(stderr, "Options for patch selection are 'progonly' or 'all'\n"); return 3; } #endif int patchall = 0; //strcmp(argv[1], "all") != 0; // Create process BPatch_process *appProc = bpatch.processCreate(argv[1], (const char**) &(argv[1])); // Load pthread into the process... appProc->loadLibrary("libpthread.so.0"); // Get the process image BPatch_image *appImage = appProc->getImage(); // Find all the instrumentable procedures BPatch_Vector<BPatch_function*> *functions = appImage->getProcedures(); /************************************************************************* * General function search * *************************************************************************/ // Find the printf function BPatch_Vector<BPatch_function*> printfFuncs; appImage->findFunction("printf", printfFuncs); if (printfFuncs.size() == 0) appImage->findFunction("_printf", printfFuncs); if (printfFuncs.size() == 0) appImage->findFunction("__printf", printfFuncs); if(printfFuncs.size() == 0) { fprintf(stderr, "Could not find printf() function"); return 2; } // Find the exit function BPatch_Vector<BPatch_function*> exitFuncs; appImage->findFunction("exit", exitFuncs); if (exitFuncs.size() == 0) appImage->findFunction("_exit", exitFuncs); if (exitFuncs.size() == 0) appImage->findFunction("__exit", exitFuncs); if(exitFuncs.size() == 0) { fprintf(stderr, "Could not find exit() function"); return 2; } // Find the perror function BPatch_Vector<BPatch_function*> perrorFuncs; appImage->findFunction("perror", perrorFuncs); if (perrorFuncs.size() == 0) appImage->findFunction("_perror", perrorFuncs); if (perrorFuncs.size() == 0) appImage->findFunction("__perror", perrorFuncs); if(perrorFuncs.size() == 0) { fprintf(stderr, "Could not find perror() function"); return 2; } BPatch_Vector<BPatch_snippet*> mainEntryBlock; /************************************************************************ * Error exit call * ************************************************************************/ BPatch_Vector<BPatch_snippet*> exitArgs; BPatch_constExpr exitCode(-2); exitArgs.push_back(&exitCode); // Open call BPatch_funcCallExpr exitOnErrorCall(*exitFuncs[0], exitArgs); /************************************************************************ * Open imitate device patch * * **********************************************************************/ // Find main() BPatch_Vector<BPatch_function*> mainFunctions; appImage->findFunction("main", mainFunctions); if (mainFunctions.size() == 0) appImage->findFunction("_main", mainFunctions); if (mainFunctions.size() == 0) appImage->findFunction("__main", mainFunctions); if(mainFunctions.size() == 0) { fprintf(stderr, "Could not find main() function"); return 2; } // find open() BPatch_Vector<BPatch_function*> openFunctions; appImage->findFunction("open64", openFunctions); if (openFunctions.size() == 0) appImage->findFunction("open", openFunctions); if (openFunctions.size() == 0) appImage->findFunction("_open", openFunctions); if (openFunctions.size() == 0) appImage->findFunction("__open", openFunctions); if(openFunctions.size() == 0) { fprintf(stderr, "Could not find open() function"); return 2; } // Get main() entry point BPatch_Vector<BPatch_point*> *mainPoints = mainFunctions[0]->findPoint(BPatch_entry); // Open call arguments BPatch_Vector<BPatch_snippet*> openArgs; BPatch_constExpr fileName("/dev/imitate0"); BPatch_constExpr fileFlags(O_RDWR); openArgs.push_back(&fileName); openArgs.push_back(&fileFlags); // Open call BPatch_funcCallExpr openDevCall(*openFunctions[0], openArgs); // Allocate file descriptor BPatch_variableExpr *devFd = appProc->malloc(*appImage->findType("int")); // Assign fd with result of open call BPatch_arithExpr openDevice(BPatch_assign, *devFd, openDevCall); // defFd check BPatch_boolExpr devFdCheck(BPatch_lt, *devFd, BPatch_constExpr(0)); // perror message BPatch_Vector<BPatch_snippet*> devFdErrorArgs; BPatch_constExpr devFdErrorMsg("Opening imitate kernel device"); devFdErrorArgs.push_back(&devFdErrorMsg); BPatch_funcCallExpr devFdError(*perrorFuncs[0], devFdErrorArgs); BPatch_Vector<BPatch_snippet*> openErrorBlock; openErrorBlock.push_back(&devFdError); openErrorBlock.push_back(&exitOnErrorCall); // if (devFd < 0) { perror(...) } BPatch_ifExpr devFdBlock(devFdCheck, BPatch_sequence(openErrorBlock)); mainEntryBlock.push_back(&openDevice); mainEntryBlock.push_back(&devFdBlock); /************************************************************************* * Send ioctl IMITATE_APP_RECORD to module * *************************************************************************/ // find ioctl() BPatch_Vector<BPatch_function*> ioctlFunctions; appImage->findFunction("ioctl", ioctlFunctions); if (ioctlFunctions.size() == 0) appImage->findFunction("_ioctl", ioctlFunctions); if (ioctlFunctions.size() == 0) appImage->findFunction("__ioctl", ioctlFunctions); if(ioctlFunctions.size() == 0) { fprintf(stderr, "Could not find ioctl() function"); return 2; } // ioctl() arguments BPatch_Vector<BPatch_snippet*> ioctlArgs; BPatch_constExpr operation(IMITATE_APP_RECORD); fprintf(stderr, "PPID: %d\n", getppid()); BPatch_constExpr monitorPid(getppid()); ioctlArgs.push_back(devFd); ioctlArgs.push_back(&operation); ioctlArgs.push_back(&monitorPid); // ioctl() call BPatch_funcCallExpr ioctlCall(*ioctlFunctions[0], ioctlArgs); // ioctl() result check BPatch_boolExpr ioctlCheck(BPatch_lt, ioctlCall, BPatch_constExpr(0)); // perror message BPatch_Vector<BPatch_snippet*> ioctlErrorArgs; BPatch_constExpr ioctlErrorMsg("Notifying imitate kernel driver of RECORD"); ioctlErrorArgs.push_back(&ioctlErrorMsg); BPatch_funcCallExpr ioctlError(*perrorFuncs[0], ioctlErrorArgs); BPatch_Vector<BPatch_snippet*> ioctlErrorBlock; ioctlErrorBlock.push_back(&ioctlError); ioctlErrorBlock.push_back(&exitOnErrorCall); // if (ioctl(...) < 0) { perror(...) } BPatch_ifExpr ioctlBlock(ioctlCheck, BPatch_sequence(ioctlErrorBlock)); // Add ioctl check to entry block mainEntryBlock.push_back(&ioctlBlock); /************************************************************************* * Counter mmap() * *************************************************************************/ // Find the mmap function BPatch_Vector<BPatch_function*> mmapFuncs; appImage->findFunction("mmap", mmapFuncs); if (mmapFuncs.size() == 0) appImage->findFunction("_mmap", mmapFuncs); if (mmapFuncs.size() == 0) appImage->findFunction("__mmap", mmapFuncs); if(mmapFuncs.size() == 0) { fprintf(stderr, "Could not find mmap() function"); return 2; } // Allocate counter BPatch_variableExpr *counterAddr = appProc->malloc(sizeof(sched_counter_t*)); sched_counter_t counterVal = 0; counterAddr->writeValue(&counterVal, sizeof(sched_counter_t*), false); // Notify kernel of address BPatch_Vector<BPatch_snippet*> mmapArgs; BPatch_constExpr mmapStart(0); BPatch_constExpr mmapLength(sizeof(sched_counter_t)); BPatch_constExpr mmapProt(PROT_READ | PROT_WRITE); BPatch_constExpr mmapFlags(MAP_SHARED); BPatch_constExpr mmapOffset(0); mmapArgs.push_back(&mmapStart); mmapArgs.push_back(&mmapLength); mmapArgs.push_back(&mmapProt); mmapArgs.push_back(&mmapFlags); mmapArgs.push_back(devFd); mmapArgs.push_back(&mmapOffset); // mmap() call BPatch_funcCallExpr mmapCall(*mmapFuncs[0], mmapArgs); // assign result to counterAddr BPatch_arithExpr mmapAssign(BPatch_assign, *counterAddr, mmapCall); // Add to entry block mainEntryBlock.push_back(&mmapAssign); // mmap() result check BPatch_boolExpr mmapCheck(BPatch_eq, *counterAddr, BPatch_constExpr(MAP_FAILED)); // perror message BPatch_Vector<BPatch_snippet*> mmapErrorArgs; BPatch_constExpr mmapErrorMsg("Memory mapping schedule (back edge) counter"); mmapErrorArgs.push_back(&mmapErrorMsg); BPatch_funcCallExpr mmapError(*perrorFuncs[0], mmapErrorArgs); BPatch_Vector<BPatch_snippet*> mmapErrorBlock; mmapErrorBlock.push_back(&mmapError); mmapErrorBlock.push_back(&exitOnErrorCall); // if (mmap(...) == MAP_FAILED) { perror(...) } BPatch_ifExpr mmapBlock(mmapCheck, BPatch_sequence(mmapErrorBlock)); mainEntryBlock.push_back(&mmapBlock); // Patch main entry BPatch_sequence mainEntrySeq(mainEntryBlock); appProc->insertSnippet(mainEntrySeq, *mainPoints); /************************************************************************* * Back-edge patching * *************************************************************************/ #if 0 printf("intCounter address: %x\n PID: %d\n", intCounter->getBaseAddr(), appProc->getPid()); fflush(stdout); #endif // Find the mutex lock/unlock functions BPatch_Vector<BPatch_function*> mutexLockFunctions; appImage->findFunction("pthread_mutex_lock", mutexLockFunctions); if (mutexLockFunctions.size() == 0) appImage->findFunction("_pthread_mutex_lock", mutexLockFunctions); if (mutexLockFunctions.size() == 0) appImage->findFunction("__pthread_mutex_lock", mutexLockFunctions); if(mutexLockFunctions.size() == 0) { fprintf(stderr, "Could not find pthread_mutex_lock() function"); return 2; } BPatch_Vector<BPatch_function*> mutexUnlockFunctions; appImage->findFunction("pthread_mutex_unlock", mutexUnlockFunctions); if (mutexUnlockFunctions.size() == 0) appImage->findFunction("_pthread_mutex_unlock", mutexUnlockFunctions); if (mutexUnlockFunctions.size() == 0) appImage->findFunction("__pthread_mutex_unlock", mutexUnlockFunctions); if(mutexUnlockFunctions.size() == 0) { fprintf(stderr, "Could not find pthread_mutex_unlock() function"); return 2; } // Allocate a mutex pthread_mutex_t mutexValue = PTHREAD_MUTEX_INITIALIZER; BPatch_variableExpr *mutex = appProc->malloc(sizeof(pthread_mutex_t)); mutex->writeValue(&mutexValue, sizeof(pthread_mutex_t), false); // Build mutex lock call BPatch_Vector<BPatch_snippet*> mutexArgs; BPatch_constExpr mutexAddress(mutex->getBaseAddr()); mutexArgs.push_back(&mutexAddress); BPatch_funcCallExpr mutexLockCall(*mutexLockFunctions[0], mutexArgs); BPatch_funcCallExpr mutexUnlockCall(*mutexUnlockFunctions[0], mutexArgs); BPatch_arithExpr derefCounter(BPatch_deref, *counterAddr); // Create 'increment counter' snippet BPatch_arithExpr addOneToCounter(BPatch_assign, derefCounter, BPatch_arithExpr(BPatch_plus, derefCounter, BPatch_constExpr(1))); BPatch_Vector<BPatch_snippet*> snippet; snippet.push_back(&mutexLockCall); snippet.push_back(&addOneToCounter); snippet.push_back(&mutexUnlockCall); BPatch_sequence addOneAtomic(snippet); char *name = (char*) malloc(sizeof(char)*200); char *modname = (char*) malloc(sizeof(char)*200); if (! (name && modname)) { fprintf(stderr, "%s %d: Out of memory!", __FILE__, __LINE__); return 1; } appProc->beginInsertionSet(); // Iterate through the procedures for (int i = 0; i < functions->size(); i++) { (*functions)[i]->getName(name, 199); (*functions)[i]->getModuleName(modname, 199); if ((patchall && strcmp(modname, "DEFAULT_MODULE") != 0) || strncmp(name, "pthread", 7) == 0 || strncmp(modname, "libpthread", 10) == 0 || strncmp(modname, "libdyninst", 10) == 0 || (name[0] == '_' && name[1] != '_' && strncmp(modname, "libc", 4) == 0)) continue; fprintf(stderr, "patcher: Patching function: '%s' (%s)", name, modname); // Patch back-edge for call if (strcmp(name, "main") != 0) appProc->insertSnippet(addOneAtomic, *((*functions)[i]->findPoint(BPatch_entry))); // Get the control flow graph for the procedure BPatch_flowGraph *graph = (*functions)[i]->getCFG(); // Find the loops BPatch_Vector<BPatch_basicBlockLoop*> *loops = new BPatch_Vector<BPatch_basicBlockLoop*>(); graph->getLoops(*loops); // Patch the loop back-edges for(int j = 0; j < loops->size(); j++) { appProc->insertSnippet(addOneAtomic, *((*loops)[j]->getBackEdge()->getPoint())); fprintf(stderr, ".", (int) (*loops)[j]->getBackEdge()->getPoint()->getAddress()); } fprintf(stderr, "\n"); // Free the loops found delete(loops); } fprintf(stderr, "Finalising patches..."); fflush(stderr); appProc->finalizeInsertionSet(false); fprintf(stderr, "Done.\n----------------------------------------\n"); // Clear up memory used to store the name free(name); free(modname); #if 0 /************************************************************************* * Exit point counter print patch * *************************************************************************/ // Patch exit() function to print out no of back branches at the end // Get exit() exit point BPatch_Vector<BPatch_point*> *exitPoints = exitFuncs[0]->findPoint(BPatch_entry); // Build printf() call: // printf("Total Total Back-branches: %d\n", counter); // Build arguments to printf() BPatch_Vector<BPatch_snippet*> printfArgs; BPatch_constExpr formatString("Total Back-branches: %d\n"); printfArgs.push_back(&formatString); printfArgs.push_back(&derefCounter); // Build call to printf() BPatch_funcCallExpr printfCall(*printfFuncs[0], printfArgs); // Patch into exit() appProc->insertSnippet(printfCall, *exitPoints); #endif // Continue mutatee... appProc->continueExecution(); // Wait for mutatee to finish while (!appProc->isTerminated()) { bpatch.waitForStatusChange(); } fprintf(stderr, "----------------------------------------\n"); fprintf(stderr, "Done.\n"); return 0; }
void keyDialog::openVolume() { int keyType = m_ui->cbKeyType->currentIndex() ; if( m_volumeIsEncFs ){ if( keyType == keyDialog::Key ){ m_key = m_ui->lineEditKey->text() ; }else if( keyType == keyDialog::keyfile ){ QFile f( m_ui->lineEditKey->text() ) ; f.open( QIODevice::ReadOnly ) ; m_key = f.readAll() ; }else if( keyType == keyDialog::plugin ){ /* * m_key is already set */ } return this->encfsMount() ; } if( m_ui->lineEditKey->text().isEmpty() ){ if( keyType == keyDialog::Key ){ ; }else if( keyType == keyDialog::plugin ){ DialogMsg msg( this ) ; msg.ShowUIOK( tr( "ERROR" ),tr( "Plug in name field is empty" ) ) ; m_ui->lineEditKey->setFocus() ; return this->enableAll() ; }else if( keyType == keyDialog::keyfile ){ DialogMsg msg( this ) ; msg.ShowUIOK( tr( "ERROR" ),tr( "Keyfile field is empty" ) ) ; m_ui->lineEditKey->setFocus() ; return this->enableAll() ; } } QString test_name = m_ui->lineEditMountPoint->text() ; if( test_name.contains( "/" ) ){ DialogMsg msg( this ) ; msg.ShowUIOK( tr( "ERROR" ),tr( "\"/\" character is not allowed in the mount name field" ) ) ; m_ui->lineEditKey->setFocus() ; return this->enableAll() ; } QString m ; if( keyType == keyDialog::Key ){ QString addr = utility::keyPath() ; m = QString( "-f %1" ).arg( addr ) ; QString key = m_ui->lineEditKey->text() ; utility::keySend( addr,key ) ; }else if( keyType == keyDialog::keyfile ){ QString e = m_ui->lineEditKey->text().replace( "\"","\"\"\"" ) ; m = "-f \"" + utility::resolvePath( e ) + "\"" ; }else if( keyType == keyDialog::plugin ){ if( m_key.isEmpty() ){ m = "-G " + m_ui->lineEditKey->text().replace( "\"","\"\"\"" ) ; }else{ QString addr = utility::keyPath() ; m = QString( "-f %1" ).arg( addr ) ; utility::keySend( addr,m_key ) ; } }else if( keyType == keyDialog::tcryptKeys ){ QString addr = utility::keyPath() ; m = QString( "-f %1 " ).arg( addr ) ; utility::keySend( addr,m_key ) ; }else{ qDebug() << "ERROR: Uncaught condition" ; } QString volume = m_path ; volume.replace( "\"","\"\"\"" ) ; QString exe = zuluMountPath ; if( m_ui->checkBoxShareMountPoint->isChecked() ){ exe += " -M -m -d \"" + volume + "\"" ; }else{ exe += " -m -d \"" + volume + "\"" ; } if( m_ui->checkBoxOpenReadOnly->isChecked() ){ exe += " -e ro" ; }else{ exe += " e rw" ; } QString mountPoint = m_ui->lineEditMountPoint->text() ; mountPoint.replace( "\"","\"\"\"" ) ; exe += " -z \"" + mountPoint + "\"" ; if( !m_options.isEmpty() ){ exe += " -Y " + m_options ; } if( !m_deviceOffSet.isEmpty() ){ exe += " -o " + m_deviceOffSet ; } if( !m_keyFiles.isEmpty() ){ for( const auto& it : m_keyFiles ){ QString e = it ; e.replace( "\"","\"\"\"" ) ; exe += " -F \"" + e + "\"" ; } } if( m_veraCryptVolume ){ if( m_veraCryptPIMValue > 0 ){ exe += " -t veracrypt." + QString::number( m_veraCryptPIMValue ) + " " + m ; }else{ exe += " -t veracrypt " + m ; } }else{ exe += " " + m ; } m_veraCryptWarning.show( m_veraCryptVolume ) ; m_working = true ; auto s = utility::Task::run( utility::appendUserUID( exe ) ).await() ; m_working = false ; m_veraCryptWarning.stopTimer() ; if( s.success() ){ if( utility::mapperPathExists( m_path ) ) { /* * The volume is reported as opened and it actually is */ m_success( utility::mountPath( mountPoint ) ) ; }else{ /* * The volume is reported as opened but it isnt,possible reason is a backe end crash */ DialogMsg msg( this ) ; msg.ShowUIOK( tr( "ERROR" ),tr( "An error has occured and the volume could not be opened" ) ) ; m_cancel() ; } this->HideUI() ; }else{ m_veraCryptWarning.hide() ; if( s.exitCode() == 12 && m_ui->cbKeyType->currentIndex() == keyDialog::plugin ){ /* * A user cancelled the plugin */ this->enableAll() ; }else{ QString z = s.output() ; z.replace( tr( "ERROR: " ),"" ) ; DialogMsg msg( this ) ; msg.ShowUIOK( tr( "ERROR" ),z ) ; if( m_ui->cbKeyType->currentIndex() == keyDialog::Key ){ m_ui->lineEditKey->clear() ; } this->enableAll() ; m_ui->lineEditKey->setFocus() ; } } }