Пример #1
0
int attach_process(int pid)
{
    int status = 0;

    gettimeofday(&freeze_time, NULL);

    attached_pid = pid;
    if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {
        perror("attach");
        detach_process(pid);
        return -1;
    }
    if (!proc_stopped(pid)) {
        struct itimerval tm;

        if (opt_use_waitpid_timeout) {
            /* setup alarm to avoid long waiting on waitpid */
            tm.it_interval.tv_sec = 0;
            tm.it_interval.tv_usec = 0;
            tm.it_value.tv_sec = 1;
            tm.it_value.tv_usec = stop_timeout % 1000000;
            setitimer(ITIMER_REAL, &tm, NULL);
        }

        if (waitpid(pid, &status, WUNTRACED) < 0) {
            if (errno == EINTR) {
                fprintf(stderr, "timeout on waitpid\n");
                detach_process(pid);
                return -1;
            }
            fprintf(stderr, "waitpid %d: %s\n", pid, strerror(errno));
            detach_process(pid);
            return -1;
        }

        if (opt_use_waitpid_timeout) {
            tm.it_value.tv_sec = 0;
            tm.it_value.tv_usec = 0;
            setitimer(ITIMER_REAL, &tm, NULL);
        }

        if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP)
            fprintf(stderr, "warning: waitpid(%d) WIFSTOPPED=%d WSTOPSIG=%d\n",
                    pid, WIFSTOPPED(status), WSTOPSIG(status));
    }
    if (kill(pid, SIGSTOP) < 0) {
        perror("send SIGSTOP");
        return -1;
    }
    return 0;
}
Пример #2
0
int backtrace_ptrace(int pid, int *tids, int *index, int nr_tids)
{
#if !defined (NO_LIBUNWIND_PTRACE)
    int i, count, rc = 0;
    int *threads = NULL;

    count = get_threads(pid, &threads);
    if (!count || threads == NULL)
        return -1;

    if (tids != NULL) {
        if (adjust_threads(threads, count, tids, index, nr_tids) < 0)
            return -1;

        free(threads);
        count = nr_tids;
        threads = tids;
    }

    if (attach_process(pid) < 0)
        return -1;

    for (i = 0; i < count; ++i) {
        void *upt_info;

        printf("--------------------  thread %d (%d)  --------------------\n",
               (index != NULL ? index[i] : i+1), threads[i]);

        if (threads[i] != pid && attach_thread(threads[i]) < 0) {
            rc = -1;
            break;
        }

        upt_info = _UPT_create(threads[i]);

        if (backtrace_thread(&_UPT_accessors, upt_info) < 0)
            rc = -1;

        _UPT_destroy(upt_info);

        if (threads[i] != pid && detach_thread(threads[i]))
            rc = -1;
        if (rc < 0)
            break;
    }

    free(threads);

    if (detach_process(pid) < 0)
        return -1;

    return rc;

#else
    return -1;
#endif /* NO_LIBUNWIND_PTRACE */
}
Пример #3
0
void* process_traffic(void *arg) {
	PGW pgw;

	while(1){
		pgw.read_data();
		if(pgw.status == 0)
			continue;
		pgw.set_metadata();

		if(pgw.type == 1){	
			attach_process(pgw);
		}
		else if(pgw.type == 2){
			data_transfer(pgw);
		}
		else if(pgw.type == 3){
			detach_process(pgw);
		}
		else{
			cout << "Incorrect type - " << pgw.type << endl;
		}
	}
	return NULL;
}
Пример #4
0
static int padzero(struct task_struct *tsk, unsigned long bss)
{
	int ret = 0;
	unsigned long nbyte;
	struct mm_struct *mm = NULL;

	nbyte = ELF_PAGEOFFSET(bss);
	if (nbyte) {
		nbyte = ELF_MIN_ALIGN - nbyte;
		if (tsk == current) {
			if (clear_user((void __user *) bss, nbyte))
				ret = -EFAULT;
		}
		else {
			struct eprocess *process = tsk->ethread->threads_process;
			mm = attach_process(&process->pcb);
			if (clear_user((void __user *) bss, nbyte))
				ret = -EFAULT;
			detach_process(mm);
		}
	}

	return ret;
}
Пример #5
0
/* Registers the call-back and configures the actions in case of a failure
 * with the Windows services manager. */
void
service_start(int *argcp, char **argvp[])
{
    int argc = *argcp;
    char **argv = *argvp;
    int i;
    SERVICE_TABLE_ENTRY service_table[] = {
        {(LPTSTR)program_name, (LPSERVICE_MAIN_FUNCTION)main},
        {NULL, NULL}
    };

    /* If one of the command line option is "--detach", we create
     * a new process in case of parent, wait for child to start and exit.
     * In case of the child, we just return. We should not be creating a
     * service in either case. */
    if (detach_process(argc, argv)) {
        return;
    }

    /* 'service_started' is 'false' when service_start() is called the first
     * time.  It is 'true', when it is called the second time by the Windows
     * services manager. */
    if (service_started) {
        init_service_status();

        wevent = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (!wevent) {
            char *msg_buf = ovs_lasterror_to_string();
            VLOG_FATAL("Failed to create a event (%s).", msg_buf);
        }

        poll_wevent_wait(wevent);

        /* Register the control handler. This function is called by the service
         * manager to stop the service. */
        hstatus = RegisterServiceCtrlHandler(program_name,
                                         (LPHANDLER_FUNCTION)control_handler);
        if (!hstatus) {
            char *msg_buf = ovs_lasterror_to_string();
            VLOG_FATAL("Failed to register the service control handler (%s).",
                        msg_buf);
        }

        if (monitor) {
            set_config_failure_actions();
        }

        /* When the service control manager does the call back, it does not
         * send the same arguments as sent to the main function during the
         * service start. So, use the arguments passed over during the first
         * time. */
        *argcp = sargc;
        *argvp = *sargvp;

        /* XXX: Windows implementation cannot have a unixctl commands in the
        * traditional sense of unix domain sockets. If an implementation is
        * done that involves 'unixctl' vlog commands the following call is
        * needed to make sure that the unixctl commands for vlog get
        * registered in a daemon, even before the first log message. */
        vlog_init();

        return;
    }

    assert_single_threaded();

    /* A reference to arguments passed to the main function the first time.
     * We need it after the call-back from service control manager. */
    sargc = argc;
    sargvp = argvp;

    /* We are only interested in the '--service' and '--service-monitor'
     * options before the call-back from the service control manager. */
    for (i = 0; i < argc; i ++) {
        if (!strcmp(argv[i], "--service")) {
            service_create = true;
        } else if (!strcmp(argv[i], "--service-monitor")) {
            monitor = true;
        }
    }

    /* If '--service' is not a command line option, run in foreground. */
    if (!service_create) {
        return;
    }

    /* If we have been configured to run as a service, then that service
     * should already have been created either manually or through a start up
     * script. */
    check_service();

    service_started = true;

    /* StartServiceCtrlDispatcher blocks and returns after the service is
     * stopped. */
    if (!StartServiceCtrlDispatcher(service_table)) {
        char *msg_buf = ovs_lasterror_to_string();
        VLOG_FATAL("Failed at StartServiceCtrlDispatcher (%s)", msg_buf);
    }
    exit(0);
}
Пример #6
0
/*
 * save process' memory maps, stack contents, thread identifiers and registers
 */
struct snapshot *get_snapshot(int pid, int *tids, int *index, int nr_tids)
{
    struct snapshot *res;
    int attached_tid = 0;
    int i, n_frames;
    long page, label, rc;
    struct mem_data_chunk **stacks_cover = NULL;

    if ((page = sysconf(_SC_PAGESIZE)) < 0) {
        perror("get pagesize");
        return NULL;
    }
    --page;

    res = calloc(1, sizeof(struct snapshot));

    /*
     * create memory_map structure corresponding to process' maps
     */
    res->map = create_maps(pid);
    if (res->map == NULL)
        goto get_snapshot_fail;

    /*
     * get process' threads
     */
    res->num_threads = get_threads(pid, &res->tids);
    if (res->num_threads < 0 || res->tids == NULL)
        goto get_snapshot_fail;

    /*
     * user-provided list of threads
     */
    if (tids != NULL) {
        if (adjust_threads(res->tids, res->num_threads, tids, index, nr_tids) < 0)
            goto get_snapshot_fail;

        free(res->tids);
        res->num_threads = nr_tids;
        res->tids = tids;
    }

    res->cur_thr = 0;

    res->regs = malloc(sizeof(res->regs[0])*res->num_threads);
    if (res->regs == NULL) {
        perror("malloc");
        goto get_snapshot_fail;
    }

    /* FREEZE PROCESS */
    if (attach_process(pid) < 0)
        goto get_snapshot_fail;

    for (i = 0; i < res->num_threads; ++i) {
        struct iovec iov;

        /*
         * we have already attached to main thread. call attach_thread()
         * for other ones
         */
        attached_tid = res->tids[i];
        if (res->tids[i] != pid && attach_thread(res->tids[i]) < 0)
            goto get_snapshot_fail_attached;

        /*
         * save thread's registers
         */
        iov.iov_len = sizeof(res->regs[0]);
        iov.iov_base = &res->regs[i];
        rc = ptrace(PTRACE_GETREGSET, res->tids[i], NT_PRSTATUS, &iov);
        if (rc < 0) {
            perror("PTRACE_GETREGSET");
            goto get_snapshot_fail_attached;
        }

        /*
         * save label on memory region. it will indicate that memory contents
         * upper than this point (%rsp) will needed to unwind stacks
         */
        label = SP_REG(&res->regs[i]) & ~page;
        rc = mem_map_add_label(res->map, (void *)label, res->num_threads);

        if (rc < 0) {
            fprintf(stderr, "failed to add label 0x%lx [rsp 0x%llx thread %d]\n",
                    label, (long long unsigned int)SP_REG(&res->regs[i]), res->tids[i]);
            goto get_snapshot_fail_attached;
        }

        /*
         * detach from thread. it will still be frozen due to SIGSTOP
         */
        if (res->tids[i] != pid && detach_thread(res->tids[i]) < 0)
            goto get_snapshot_fail_attached;
    }

    /*
     * arrange data chunks to copy memory contents. in most cases the chunks
     * will start from %rsp pointing somewhere in thread's stack
     * to the end of the stack region
     */
    stacks_cover = malloc(sizeof(struct mem_data_chunk*) * res->num_threads);

    n_frames = mem_map_build_label_cover(res->map, stack_size,
            stacks_cover, page + 1);

    if (stacks_cover == NULL) {
        fprintf(stderr, "error: stacks cover == NULL, n_frames=%d\n", n_frames);
        goto get_snapshot_fail_attached;
    }

    /*
     * copy memory contents
     */
    rc = copy_memory(pid, stacks_cover, n_frames);

    if (rc < 0)
        goto get_snapshot_fail_attached;

    /* UNFREEZE PROCESS */
    if (detach_process(pid) < 0)
        goto get_snapshot_fail;

    if (opt_verbose) {
        for (i = 0; i < n_frames; ++i) {
            struct mem_data_chunk *chunk = stacks_cover[i];
            printf("chunk #%d: 0x%lx-0x%lx length: %ldK\n",
                    i, (size_t)chunk->start,
                    (size_t)chunk->start + chunk->length,
                    chunk->length >> 10);
        }
    }

    free(stacks_cover);

    return res;

get_snapshot_fail_attached:
    if (attached_tid)
        detach_thread(attached_tid);

    detach_process(pid);

get_snapshot_fail:
    if (opt_verbose) {
        fprintf(stderr, "maps of %d:\n", pid);
        print_proc_maps(pid);
    }

    free(stacks_cover);
    snapshot_destroy(res);
    return NULL;
}
Пример #7
0
int backtrace_ptrace(int pid, int *tids, int *index, int nr_tids)
{
#if !defined (NO_LIBUNWIND_PTRACE)
    int i, count, rc = 0;
    int *threads = NULL;

    count = get_threads(pid, &threads);
    if (!count || threads == NULL)
        return -1;

    if (tids != NULL) {
        if (adjust_threads(threads, count, tids, index, nr_tids) < 0)
            return -1;

        free(threads);
        count = nr_tids;
        threads = tids;
    }

    if (attach_process(pid) < 0)
        return -1;

    for (i = 0; i < count; ++i) {
        void *upt_info;
        int x;
        char comm[16];
        char end_pad[25] = "------------------------";

        x = get_thread_comm(threads[i], comm, sizeof(comm));

        if (x > 0 && x <= sizeof(end_pad))
        {
            end_pad[sizeof(end_pad) - x] = '\0';
            printf("-------------- thread %d (%d) (%s) %s\n", (index != NULL ? index[i] : i + 1), threads[i], comm, end_pad);
        }

        if (threads[i] != pid && attach_thread(threads[i]) < 0) {
            rc = -1;
            break;
        }

        upt_info = _UPT_create(threads[i]);

        if (backtrace_thread(&_UPT_accessors, upt_info) < 0)
            rc = -1;

        _UPT_destroy(upt_info);

        if (threads[i] != pid && detach_thread(threads[i]))
            rc = -1;
        if (rc < 0)
            break;
    }

    free(threads);

    if (detach_process(pid) < 0)
        return -1;

    return rc;

#else
    return -1;
#endif /* NO_LIBUNWIND_PTRACE */
}
Пример #8
0
/*
 * save process' memory maps, stack contents, thread identifiers and registers
 */
struct snapshot *get_snapshot(int pid, int *tids, int *index, int nr_tids)
{
    struct snapshot *res;
    int i, attached_tid, n_frames;
    long page, label, rc;
    struct mem_data_chunk **stacks_cover = NULL;
    int v_major, v_minor;
    int use_process_vm_readv = 0;

    if ((page = sysconf(_SC_PAGESIZE)) < 0) {
        perror("get pagesize");
        return NULL;
    }
    --page;

    res = calloc(1, sizeof(struct snapshot));

    /*
     * create memory_map structure corresponding to process' maps
     */
    res->map = create_maps(pid);
    if (res->map == NULL)
        goto get_snapshot_fail;

    /*
     * get process' threads
     */
    res->num_threads = get_threads(pid, &res->tids);
    if (res->num_threads < 0 || res->tids == NULL)
        goto get_snapshot_fail;

    /*
     * user-provided list of threads
     */
    if (tids != NULL) {
        if (adjust_threads(res->tids, res->num_threads, tids, index, nr_tids) < 0)
            goto get_snapshot_fail;

        free(res->tids);
        res->num_threads = nr_tids;
        res->tids = tids;
    }

    res->cur_thr = 0;

    res->regs = malloc(sizeof(struct user_regs_struct)*res->num_threads);
    if (res->regs == NULL) {
        perror("malloc");
        goto get_snapshot_fail;
    }

    /*
     * decide how to copy memory contents of the process. on newer kernels
     * proc_vm_readv() is used by default. on older kernels or when the option
     * --proc-mem is specified read the file /proc/<pid>/mem
     */
    if (!opt_proc_mem) {
        if (get_kernel_version(&v_major, &v_minor) < 0)
            goto get_snapshot_fail;
        if (((v_major << 16) | v_minor) >= 0x30002)
            use_process_vm_readv = 1;
    } else {
        use_process_vm_readv = 0;
    }

    /* FREEZE PROCESS */
    if (attach_process(pid) < 0)
        goto get_snapshot_fail;

    for (i = 0; i < res->num_threads; ++i) {
        /*
         * we have already attached to main thread. call attach_thread()
         * for other ones
         */
        attached_tid = res->tids[i];
        if (res->tids[i] != pid && attach_thread(res->tids[i]) < 0)
            goto get_snapshot_fail_attached;

        /*
         * save thread's registers
         */
        rc = ptrace(PTRACE_GETREGS, res->tids[i], NULL, &res->regs[i]);
        if (rc < 0) {
            perror("PTRACE_GETREGS");
            goto get_snapshot_fail_attached;
        }

        /*
         * save label on memory region. it will indicate that memory contents
         * upper than this point (%rsp) will needed to unwind stacks
         */
        label = res->regs[i].rsp & ~page;
        rc = mem_map_add_label(res->map, (void *)label, res->num_threads);

        if (rc < 0) {
            fprintf(stderr, "failed to add label 0x%lx [rsp 0x%lx thread %d]\n",
                    label, res->regs[i].rsp, res->tids[i]);
            goto get_snapshot_fail_attached;
        }

        /*
         * detach from thread. it will still be frozen due to SIGSTOP
         */
        if (res->tids[i] != pid && detach_thread(res->tids[i]) < 0)
            goto get_snapshot_fail_attached;
    }

    /*
     * arrange data chunks to copy memory contents. in most cases the chunks
     * will start from %rsp pointing somewhere in thread's stack
     * to the end of the stack region
     */
    stacks_cover = malloc(sizeof(struct mem_data_chunk*) * res->num_threads);

    n_frames = mem_map_build_label_cover(res->map, stack_size,
            stacks_cover, page + 1);

    if (stacks_cover == NULL) {
        fprintf(stderr, "error: stacks cover == NULL, n_frames=%d\n", n_frames);
        goto get_snapshot_fail_attached;
    }

    /*
     * copy memory contents
     */
    rc = use_process_vm_readv ?
        copy_memory_process_vm_readv(pid, stacks_cover, n_frames) :
        copy_memory_proc_mem(pid, stacks_cover, n_frames);

    if (rc < 0)
        goto get_snapshot_fail_attached;

    /* UNFREEZE PROCESS */
    if (detach_process(pid) < 0)
        goto get_snapshot_fail;

    if (opt_verbose) {
        for (i = 0; i < n_frames; ++i) {
            struct mem_data_chunk *chunk = stacks_cover[i];
            printf("chunk #%d: 0x%lx-0x%lx length: %ldK\n",
                    i, (size_t)chunk->start,
                    (size_t)chunk->start + chunk->length,
                    chunk->length >> 10);
        }
    }

    free(stacks_cover);

    return res;

get_snapshot_fail_attached:
    if (attached_tid)
        detach_thread(attached_tid);

    detach_process(pid);

get_snapshot_fail:
    if (opt_verbose) {
        fprintf(stderr, "maps of %d:\n", pid);
        print_proc_maps(pid);
    }

    free(stacks_cover);
    snapshot_destroy(res);
    return NULL;
}