コード例 #1
0
ファイル: TraceThread.cpp プロジェクト: autopin/autopin-plus
void TraceThread::attach() {
	bool tasks_changed = true;
	ProcessTree::autopin_tid_list no_trace;
	int errsave, status;

	context.debug("TraceThread is attaching");

	// attach to all tasks and child processes of the observed_process

	while (tasks_changed) {
		ProcessTree::autopin_tid_list attach_tasks = observed_process->getProcessTree().getAllTasks();
		tasks_changed = false;

		for (const auto &attach_task : attach_tasks) {
			if (tasks.find(attach_task) != tasks.end())
				continue;
			else if (no_trace.find(attach_task) != no_trace.end())
				continue;
			else
				tasks_changed = true;

			long ret;
			pid_t pid = attach_task;

			ret = ptrace(PTRACE_ATTACH, pid, nullptr, nullptr);

			if (ret == -1) {
				errsave = errno;

				if (errsave == ESRCH || errsave == EPERM) {
					no_trace.insert(pid);
					context.report(Error::PROC_TRACE, "cannot_trace", "Not going to trace " + QString::number(pid));
				} else {
					context.report(Error::UNKNOWN, "PTRACE_ATTACH",
								   "Could not attach to process with pid " + QString::number(pid));
				}
				continue;
			}

			// wait for the process to stop
			waitpid(pid, &status, __WALL);
			if (WIFEXITED(status)) {
				context.report(Error::PROC_TRACE, "cannot_trace",
							   "Task " + QString::number(pid) + " has already exited");
				continue;
			}

			// set ptrace options
			ret = ptrace(PTRACE_SETOPTIONS, pid, nullptr, ptrace_opt);
			if (ret == -1) {
				errsave = errno;

				if (errsave == ESRCH || errsave == EPERM) {
					no_trace.insert(pid);
					context.report(Error::PROC_TRACE, "cannot_trace", "Not going to trace " + QString::number(pid));
				} else {
					context.report(Error::UNKNOWN, "PTRACE_SETOPTIONS",
								   "Could set ptrace options for process " + QString::number(pid));
				}

				ptrace(PTRACE_DETACH, pid, nullptr, nullptr);

				continue;
			} else {
				context.info("  :: Attached to task " + QString::number(pid));
				tasks.insert(pid);
			}
		}
	}

	// continue all tasks
	for (const auto &elem : tasks) ptraceContinue(elem);

	// continue the process if it has been started by autopin+
	if (observed_process->getExec()) kill(pid, SIGUSR1);
}
コード例 #2
0
/*
int WaitXX(int mode,int *sigp)
*/
int WaitXXX(int mode,int *sigp,int *statp)
{   int status[4]; /**/
    int pid,xpid,sig,xcode,st;
    int serrno;

    if( sigp )
        *sigp = 0;
    for(;;) {
        pid = wait3(status,mode,NULL);
        if( statp ) {
            *statp = getWaitExitCode(status);
        }
        if( !lTRACE() )
            if( sigp == NULL )
                break;
        if( pid <= 0 )
            break;
        st = status[0];

        if( 0 <= (xcode = getWaitExitCode(status)) ) {
            if( isWindows() ) {
                /* introduced in 6.0.4 for PTRACE ?
                 * but seems useless to wait exited process
                 * and anyway unsupported on Windows
                 */
                xpid = -1;
            } else
                xpid = waitpid(pid,status,0);
            if( lTRVERB() )
                TraceLog("- Wait [%04X] pid=%d EXITED(%d) %d\n",
                         st,pid,xcode,xpid);
            return pid;
        }
        if( 0 < (sig = getWaitExitSig(status)) ) {
            xpid = waitpid(pid,status,0);
            TraceLog("- Wait [%04X] pid=%d SIGNALED(%d=%s)%s %d\n",
                     st,pid,sig,sigsym(sig),
                     getWaitExitCore(status)?" COREDUMP":"",xpid);
            if( sigp )
                *sigp = sig;
            return pid;
        }
        if( 0 < (sig = getWaitStopSig(status)) ) {
            if( lTRVERB() || !usualsig(sig) )
                TraceLog("- Wait [%04X] pid=%d STOPSIG(%d=%s)\n",
                         st,pid,sig,sigsym(sig));
            if( sig == SIGTRAP ) {
                if( lNOEXEC() )
                    ptraceKill(pid);
                else	ptraceContinue(pid,0);
            } else	ptraceContinue(pid,sig);
            continue;
        }
        TraceLog("- Wait [%04X] pid=%d wait unknown\n",st,pid);
        if( mode == WAIT_WNOHANG )
            break;
    }
    /*
    serrno = errno;
    syslog_ERROR("-- Wait()=%d, errno=%d\n",pid,errno);
    errno = serrno;
    */
    return pid;
}
コード例 #3
0
ファイル: TraceThread.cpp プロジェクト: autopin/autopin-plus
void TraceThread::run() {
	int status;
	long ret;
	pid_t trace_pid;
	unsigned long event_msg;

	setupSignalHandler();

	// attach to processes
	attach();

	// Check if the observed process is traced
	if (tasks.find(pid) == tasks.end()) {
		trace_mutex.unlock();
		context.report(Error::PROC_TRACE, "observed_process", "Cannot trace the observed_process");
	}

	context.info("Attached to all tasks of process " + QString::number(pid));
	trace_mutex.unlock();

	// start the loop for tracking process events
	while (true) {
		context.debug("Trace Thread is waiting");
		// set alarm
		alarm(3);
		trace_pid = waitpid(-1, &status, __WALL);
		alarm(0);

		if (alarm_occured) {
			context.debug("ALARM!");
			alarm_occured = false;

			if (exreq)
				break;
			else if (trace_pid == -1)
				continue;
		}

		if (trace_pid == -1) {
			context.report(Error::PROC_TRACE, "waitpid", "waitpid failed while tracing the observed process");
			continue;
		}

		context.debug("Got signal from: " + QString::number(trace_pid));

		// check return status of waitpid

		if (WIFEXITED(status) || WIFSIGNALED(status)) {
			tasks.erase(trace_pid);

			emit sig_TaskTerminated(trace_pid);

			if (pid == trace_pid) return;
		} else if (WIFSTOPPED(status)) {

			if (WSTOPSIG(status) == SIGTRAP) {
				ret = ptrace(PTRACE_GETEVENTMSG, trace_pid, nullptr, (void *)&event_msg);

				if (ret != 0)
					context.report(Error::PROC_TRACE, "ptrace_eventmsg", "Could not get ptrace event information");

				switch (status >> 16) {
				case (PTRACE_EVENT_CLONE):

				case (PTRACE_EVENT_FORK):

				case (PTRACE_EVENT_VFORK):
					newTask(event_msg);
					break;

				default:
					context.debug("Received unhandled ptrace event!");
					break;
				}

				ptraceContinue(trace_pid);

			} else if (WSTOPSIG(status) == SIGSTOP) {
				context.debug("Received stop signal!");

				if (tasks.find(trace_pid) != tasks.end()) {
					ptraceContinue(trace_pid);
				} else
					newTask(trace_pid);

			} else {
				context.debug("Received unhandled signal!");
				ptraceContinue(trace_pid, WSTOPSIG(status));
			}

		} else {