예제 #1
0
파일: restorer.c 프로젝트: rmoorman/criu
/*
 * Threads restoration via sigreturn. Note it's locked
 * routine and calls for unlock at the end.
 */
long __export_restore_thread(struct thread_restore_args *args)
{
	struct rt_sigframe *rt_sigframe;
	k_rtsigset_t to_block;
	unsigned long new_sp;
	int my_pid = sys_gettid();
	int ret;

	if (my_pid != args->pid) {
		pr_err("Thread pid mismatch %d/%d\n", my_pid, args->pid);
		goto core_restore_end;
	}

	/* All signals must be handled by thread leader */
	ksigfillset(&to_block);
	ret = sys_sigprocmask(SIG_SETMASK, &to_block, NULL, sizeof(k_rtsigset_t));
	if (ret) {
		pr_err("Unable to block signals %d", ret);
		goto core_restore_end;
	}

	rt_sigframe = (void *)args->mem_zone.rt_sigframe;

	if (restore_thread_common(rt_sigframe, args))
		goto core_restore_end;

	ret = restore_creds(&args->ta->creds);
	if (ret)
		goto core_restore_end;

	ret = restore_dumpable_flag(&args->ta->mm);
	if (ret)
		goto core_restore_end;

	pr_info("%ld: Restored\n", sys_gettid());

	restore_finish_stage(CR_STATE_RESTORE);

	if (restore_signals(args->siginfo, args->siginfo_nr, false))
		goto core_restore_end;

	restore_finish_stage(CR_STATE_RESTORE_SIGCHLD);
	restore_pdeath_sig(args);
	restore_finish_stage(CR_STATE_RESTORE_CREDS);
	futex_dec_and_wake(&thread_inprogress);

	new_sp = (long)rt_sigframe + SIGFRAME_OFFSET;
	rst_sigreturn(new_sp);

core_restore_end:
	pr_err("Restorer abnormal termination for %ld\n", sys_getpid());
	futex_abort_and_wake(&task_entries->nr_in_progress);
	sys_exit_group(1);
	return -1;
}
예제 #2
0
파일: mutex.c 프로젝트: forhappy/libloader
void
xmutex_unlock(struct xmutex * lock, sigset_t sigset)
{
	TRACE(MUTEX, "thread %d:%d is unlocking %p\n",
			sys_getpid(), sys_gettid(), lock);
	/* atomic_dec(&lock->val) != 1 */
	if (!atomic_dec_and_test(&lock->val)) {
		atomic_set(&lock->val, 0);
		futex_wake(&lock->val, 1);
	}
	restore_signals(sigset);
	TRACE(MUTEX, "thread %d:%d unlocked %p\n",
			sys_getpid(), sys_gettid(), lock);
}
예제 #3
0
파일: target_fork.c 프로젝트: KurSh/rr
int main(int argc, char** argv) {
	int num_syscalls;
	int child;
	int i;

	bad_breakpoint();

	test_assert(argc == 2);
	num_syscalls = atoi(argv[1]);

	atomic_printf("%d: running %d syscalls ...\n", getpid(), num_syscalls);
	for (i = 0; i < num_syscalls; ++i) {
		sys_gettid();
	}

	if (0 == (child = fork())) {
		good_breakpoint();
		exit(0);
	}

	atomic_printf("child %d\n", child);

	waitpid(child, NULL, 0);

	atomic_puts("EXIT-SUCCESS");
	return 0;
}
예제 #4
0
static int
open_counter(size_t nr_switches)
{
    struct perf_event_attr attr;
    int fd;
    struct f_owner_ex own;

    memset(&attr, 0, sizeof(attr));
    attr.size = sizeof(attr);
    attr.type = PERF_TYPE_SOFTWARE;
    attr.config = PERF_COUNT_SW_CONTEXT_SWITCHES;
    attr.disabled = 1;
    attr.sample_period = nr_switches;

    fd = sys_perf_event_open(&attr, 0/*self*/, -1/*any cpu*/, -1, 0);
    if (0 > fd)
        err(1, "perf_event_open(cs, period=%u)", nr_switches);

    if (fcntl(fd, F_SETFL, O_ASYNC))
        err(1, "fcntl(O_ASYNC)");

    own.type = F_OWNER_TID;
    own.pid = sys_gettid();
    if (fcntl(fd, F_SETOWN_EX, &own))
        err(1, "fcntl(SETOWN_EX)");

    if (fcntl(fd, F_SETSIG, SIGIO))
        err(1, "fcntl(SETSIG, SIGIO)");

    return fd;
}
예제 #5
0
int main(void) {
  signal(SIGUSR1, sighandler);
  signal(SIGUSR2, sighandler);
  tgkill(getpid(), sys_gettid(), SIGUSR1);
  tgkill(getpid(), sys_gettid(), SIGUSR2);

  test_assert(2 == num_signals_caught);

  syscall(SYS_tkill, sys_gettid(), SIGUSR1);
  syscall(SYS_tkill, sys_gettid(), SIGUSR2);

  test_assert(4 == num_signals_caught);

  atomic_puts("EXIT-SUCCESS");
  return 0;
}
예제 #6
0
파일: taint.c 프로젝트: brainsmoke/minemu
static int in_dirlist(char *path, char *dirs)
{
	char *p;
	int match = 0;
	while (*dirs && !match)
	{
		p = path;
		match = 1;
		while ( *dirs != '\0' && *dirs != ':' )
		{
			if (*p != *dirs)
				match = 0;

			if (*p)
				p++;

			dirs++;
		}
		if (*p != '/')
			match = 0;

		if (*dirs != '\0')
			dirs++;
	}

if (match) sys_gettid();
	return match;
}
예제 #7
0
static int restore_signals(siginfo_t *ptr, int nr, bool group)
{
	int ret, i;
	k_rtsigset_t to_block;

	ksigfillset(&to_block);
	ret = sys_sigprocmask(SIG_SETMASK, &to_block, NULL, sizeof(k_rtsigset_t));
	if (ret) {
		pr_err("Unable to block signals %d", ret);
		return -1;
	}

	for (i = 0; i < nr; i++) {
		siginfo_t *info = ptr + i;

		pr_info("Restore signal %d group %d\n", info->si_signo, group);
		if (group)
			ret = sys_rt_sigqueueinfo(sys_getpid(), info->si_signo, info);
		else
			ret = sys_rt_tgsigqueueinfo(sys_getpid(),
						sys_gettid(), info->si_signo, info);
		if (ret) {
			pr_err("Unable to send siginfo %d %x with code %d\n",
					info->si_signo, info->si_code, ret);
			return -1;;
		}
	}

	return 0;
}
예제 #8
0
static void* reader_thread(void* dontcare) {
    char token = start_token;
    struct sigaction act;
    int readsock = sockfds[1];
    char c = sentinel_token;
    int flags = 0;

    reader_tid = sys_gettid();

    flags = SA_RESTART;

    memset(&act, 0, sizeof(act));
    act.sa_handler = sighandler;
    act.sa_flags = flags;
    sigaction(SIGUSR1, &act, NULL);

    memset(&act, 0, sizeof(act));
    act.sa_handler = sighandler2;
    act.sa_flags = flags;
    sigaction(SIGUSR2, &act, NULL);

    pthread_barrier_wait(&barrier);

    atomic_puts("r: blocking on read, awaiting signal ...");

    test_assert(1 == read(readsock, &c, sizeof(c)));
    test_assert(2 == reader_caught_signal);
    token += reader_caught_signal;

    atomic_printf("r: ... read level 0 '%c'\n", c);
    test_assert(c == token);

    return NULL;
}
예제 #9
0
파일: clone.c 프로젝트: koolhazz/rr
int main(int argc, char *argv[]) {
	const size_t stack_size = 1 << 20;
	void* stack = mmap(NULL, stack_size,
			   PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
			   -1, 0);
	int pid;
	sigset_t set;

	sys_gettid();
	/* NB: no syscalls in between the sys_gettid() above and this
	 * clone(). */
	breakpoint();

	/* Warning: strace gets the parameter order wrong and will print
	   child_tidptr as 0 here. */
	pid = clone(child, stack + stack_size,
		CLONE_VM | CLONE_FS | CLONE_FILES |
		CLONE_THREAD | CLONE_SIGHAND |
		CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID,
		NULL, &child_tid, NULL, &child_tid);

	atomic_printf("clone()d pid: %d\n", pid);
	test_assert(pid > 0);

	futex(&child_tid, FUTEX_WAIT, pid, NULL, NULL, 0);
	test_assert(child_tid_copy == pid);
	/* clone() should have cleared child_tid now */
	test_assert(child_tid == 0);

	sys_gettid();

	sigfillset(&set);
	test_assert(0 == sigprocmask(SIG_BLOCK, &set, NULL));

	/* NB: no syscalls in between the sys_gettid() above and this
	 * clone(). */
	breakpoint();
	pid = clone(child, stack + stack_size,
		    CLONE_SIGHAND /*must also have CLONE_VM*/,
		    NULL, NULL, NULL);

	atomic_printf("clone(CLONE_SIGHAND)'d pid: %d\n", pid);
	test_assert(-1 == pid);

	atomic_puts("EXIT-SUCCESS");
	return 0;
}
예제 #10
0
long
hio_gettid(void)
{
	if (!syscall_isset(__NR_gettid, current->aspace->hio_syscall_mask))
		return sys_gettid();

	return hio_format_and_exec_syscall(__NR_gettid, 0);
}
예제 #11
0
static void sighandler(int sig) {
	test_assert(sys_gettid() == reader_tid);
	++reader_caught_signal;

	atomic_puts("r: in sighandler level 1 ...");
	cond_wait(1);
	atomic_puts("r: ... wait done");
}
예제 #12
0
파일: tgkill03.c 프로젝트: kraj/ltp
static void *child_thread_func(void *arg)
{
	child_tid = sys_gettid();

	TST_CHECKPOINT_WAKE_AND_WAIT(0);

	return arg;
}
예제 #13
0
파일: mutex.c 프로젝트: forhappy/libloader
sigset_t
xmutex_lock(struct xmutex * lock)
{
	TRACE(MUTEX, "thread %d:%d is locking %p\n",
			sys_getpid(), sys_gettid(), lock);
	int c;
	sigset_t sigset = block_signals();
	if ((c = atomic_cmpxchg(&lock->val, 0, 1)) != 0) {
		do {
			if (c == 2 || atomic_cmpxchg(&lock->val, 1, 2) != 0)
				futex_wait(&lock->val, 2);
		} while ((c = atomic_cmpxchg(&lock->val, 0, 2)) != 0);
	}
	TRACE(MUTEX, "thread %d:%d gained lock %p\n",
			sys_getpid(), sys_gettid(), lock);
	return sigset;
}
예제 #14
0
/*
 * Threads restoration via sigreturn. Note it's locked
 * routine and calls for unlock at the end.
 */
long __export_restore_thread(struct thread_restore_args *args)
{
	struct rt_sigframe *rt_sigframe;
	unsigned long new_sp;
	int my_pid = sys_gettid();
	int ret;

	if (my_pid != args->pid) {
		pr_err("Thread pid mismatch %d/%d\n", my_pid, args->pid);
		goto core_restore_end;
	}

	rt_sigframe = (void *)args->mem_zone.rt_sigframe + 8;

	if (restore_thread_common(rt_sigframe, args))
		goto core_restore_end;

	mutex_unlock(&args->ta->rst_lock);

	ret = restore_creds(&args->ta->creds);
	if (ret)
		goto core_restore_end;

	pr_info("%ld: Restored\n", sys_gettid());

	restore_finish_stage(CR_STATE_RESTORE);

	if (restore_signals(args->siginfo, args->siginfo_nr, false))
		goto core_restore_end;

	restore_finish_stage(CR_STATE_RESTORE_SIGCHLD);
	restore_finish_stage(CR_STATE_RESTORE_CREDS);
	futex_dec_and_wake(&thread_inprogress);

	new_sp = (long)rt_sigframe + SIGFRAME_OFFSET;
	ARCH_RT_SIGRETURN(new_sp);

core_restore_end:
	pr_err("Restorer abnormal termination for %ld\n", sys_getpid());
	futex_abort_and_wake(&task_entries->nr_in_progress);
	sys_exit_group(1);
	return -1;
}
예제 #15
0
파일: parasite.c 프로젝트: OSLL/pmover
static int dump_tid_info(struct parasite_dump_tid_info *args)
{
	int ret;

	ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long) &args->tid_addr, 0, 0, 0);
	if (ret)
		return ret;

	args->tid = sys_gettid();

	return 0;
}
예제 #16
0
static void sighandler2(int sig) {
    char c = sentinel_token;

    test_assert(sys_gettid() == reader_tid);
    ++reader_caught_signal;

    atomic_puts("r: in sighandler level 2 ...");

    test_assert(1 == read(sockfds[1], &c, sizeof(c)));
    atomic_printf("r: ... read level 2 '%c'\n", c);
    test_assert(c == start_token);
}
예제 #17
0
static int fini_thread(void)
{
	struct tid_state_s *s;

	s = find_thread_state(sys_gettid());
	if (!s)
		return -ENOENT;

	if (s->use_sig_blocked)
		return sys_sigprocmask(SIG_SETMASK, &s->sig_blocked,
				       NULL, sizeof(k_rtsigset_t));

	return 0;
}
예제 #18
0
파일: goto_event.c 프로젝트: KurSh/rr
static void* child_thread(void* num_syscallsp) {
	int num_syscalls = (uintptr_t)num_syscallsp;
	int i;

	first_breakpoint();

	/* NB: this test assumes that gettid() produces at least one
	 * trace event per syscall. */
	atomic_printf("%d: running %d syscalls ...\n", getpid(), num_syscalls);
	for (i = 0; i < num_syscalls; ++i) {
		(void)sys_gettid();
	}

	second_breakpoint();

	return NULL;
}
예제 #19
0
파일: tgkill03.c 프로젝트: kraj/ltp
static void setup(void)
{
	sigset_t sigusr1;
	pthread_t defunct_thread;

	sigemptyset(&sigusr1);
	sigaddset(&sigusr1, SIGUSR1);
	pthread_sigmask(SIG_BLOCK, &sigusr1, NULL);

	parent_tgid = getpid();
	parent_tid = sys_gettid();

	SAFE_PTHREAD_CREATE(&child_thread, NULL, child_thread_func, NULL);

	TST_CHECKPOINT_WAIT(0);

	SAFE_PTHREAD_CREATE(&defunct_thread, NULL, defunct_thread_func, NULL);

	SAFE_PTHREAD_JOIN(defunct_thread, NULL);
}
예제 #20
0
static int init_thread(void)
{
	k_rtsigset_t to_block;
	int ret;

	if (next_tid_state >= nr_tid_state)
		return -ENOMEM;

	ksigfillset(&to_block);
	ret = sys_sigprocmask(SIG_SETMASK, &to_block,
			      &tid_state[next_tid_state].sig_blocked,
			      sizeof(k_rtsigset_t));
	if (ret >= 0)
		tid_state[next_tid_state].use_sig_blocked = true;
	tid_state[next_tid_state].tid = sys_gettid();

	next_tid_state++;

	return ret;
}
예제 #21
0
파일: restorer.c 프로젝트: rmoorman/criu
static int restore_signals(siginfo_t *ptr, int nr, bool group)
{
	int ret, i;

	for (i = 0; i < nr; i++) {
		siginfo_t *info = ptr + i;

		pr_info("Restore signal %d group %d\n", info->si_signo, group);
		if (group)
			ret = sys_rt_sigqueueinfo(sys_getpid(), info->si_signo, info);
		else
			ret = sys_rt_tgsigqueueinfo(sys_getpid(),
						sys_gettid(), info->si_signo, info);
		if (ret) {
			pr_err("Unable to send siginfo %d %x with code %d\n",
					info->si_signo, info->si_code, ret);
			return -1;;
		}
	}

	return 0;
}
예제 #22
0
static int dump_thread(struct parasite_dump_thread *args)
{
	pid_t tid = sys_gettid();
	struct tid_state_s *s;
	int ret;

	s = find_thread_state(tid);
	if (!s)
		return -ENOENT;

	if (!s->use_sig_blocked)
		return -EINVAL;

	ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long) &args->tid_addr, 0, 0, 0);
	if (ret)
		return ret;

	args->blocked = s->sig_blocked;
	args->tid = tid;
	args->tls = arch_get_tls();

	return 0;
}
예제 #23
0
static void unblock_signals(void) {
  sigset_t set;
  sigfillset(&set);
  test_assert(0 == pthread_sigmask(SIG_UNBLOCK, &set, NULL));
  atomic_printf("  %d: unblocked all sigs\n", sys_gettid());
}
예제 #24
0
static int sockfds[2];

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

static void cond_wait(int secs) {
  struct timespec ts;

  clock_gettime(CLOCK_REALTIME, &ts);
  ts.tv_sec += secs;

  test_assert(ETIMEDOUT == pthread_cond_timedwait(&cond, &lock, &ts));
}

static void sighandler(__attribute__((unused)) int sig) {
  test_assert(sys_gettid() == reader_tid);
  ++reader_caught_signal;

  atomic_puts("r: in sighandler level 1 ...");
  cond_wait(1);
  atomic_puts("r: ... wait done");
}

static void* reader_thread(__attribute__((unused)) void* dontcare) {
  char token = start_token;
  struct sigaction act;
  int readsock = sockfds[1];
  char c = sentinel_token;
  int flags = 0;

  pthread_mutex_lock(&lock);
예제 #25
0
static void fin_sleep(int secs) {
  struct timespec req = {.tv_sec = secs };
  struct timespec rem = {.tv_sec = -1, .tv_nsec = -1 };

  test_assert(0 == nanosleep(&req, &rem));
  test_assert(-1 == rem.tv_sec && -1 == rem.tv_nsec);
}

static void sighandler(__attribute__((unused)) int sig) {
  test_assert(sys_gettid() == reader_tid);
  ++reader_caught_signal;

  atomic_puts("r: in sighandler level 1 ...");
  intr_sleep(2);
}

static void sighandler2(__attribute__((unused)) int sig) {
  test_assert(sys_gettid() == reader_tid);
  ++reader_caught_signal;

  atomic_puts("r: in sighandler level 2 ...");
  fin_sleep(1);
}

static void* reader_thread(__attribute__((unused)) void* dontcare) {
  struct sigaction act;
  int flags = 0;

  reader_tid = sys_gettid();

  act.sa_handler = sighandler;
  sigemptyset(&act.sa_mask);
  act.sa_flags = flags;
  sigaction(SIGUSR1, &act, NULL);

  act.sa_handler = sighandler2;
  sigemptyset(&act.sa_mask);
  act.sa_flags = flags;
  sigaction(SIGUSR2, &act, NULL);

  pthread_barrier_wait(&barrier);

  atomic_puts("r: blocking on sleep, awaiting signal ...");
  intr_sleep(3);

  return NULL;
}

int main(void) {
  struct timeval ts;

  /* (Kick on the syscallbuf if it's enabled.) */
  gettimeofday(&ts, NULL);

  pthread_barrier_init(&barrier, NULL, 2);
  pthread_create(&reader, NULL, reader_thread, NULL);

  pthread_barrier_wait(&barrier);

  /* Force a blocked read() that's interrupted by a SIGUSR1,
   * which then itself blocks on read() and succeeds. */
  atomic_puts("M: sleeping ...");
  usleep(500000);

  atomic_puts("M: killing reader ...");
  pthread_kill(reader, SIGUSR1);
  atomic_puts("M:   (quick nap)");
  usleep(100000);

  atomic_puts("M: killing reader again ...");
  pthread_kill(reader, SIGUSR2);

  atomic_puts("M:   ... done");

  pthread_join(reader, NULL);

  atomic_puts("EXIT-SUCCESS");
  return 0;
}
예제 #26
0
파일: tgkill03.c 프로젝트: kraj/ltp
static void *defunct_thread_func(void *arg)
{
	defunct_tid = sys_gettid();

	return arg;
}
예제 #27
0
static void write_tid(void) {
  pid_t tid = sys_gettid();
  test_assert(sizeof(tid) == write(tid_pipe[1], &tid, sizeof(tid)));
}
예제 #28
0
/* -*- Mode: C; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */

#include "rrutil.h"

static int v;
static int* p;
static int pipe_fds[2];

static void* run_thread(__attribute__((unused)) void* p) {
  char ch;
  test_assert(1 == read(pipe_fds[0], &ch, 1));
  test_assert(sys_gettid() == syscall(SYS_set_tid_address, &v));
  return NULL;
}

static void* run_thread2(__attribute__((unused)) void* q) {
  test_assert(sys_gettid() == syscall(SYS_set_tid_address, p));
  test_assert(1 == write(pipe_fds[1], "x", 1));
  return NULL;
}

int main(void) {
  pthread_t thread;
  char ch;

  test_assert(0 == pipe(pipe_fds));

  v = 1;
  pthread_create(&thread, NULL, run_thread, NULL);
  test_assert(1 == write(pipe_fds[1], "x", 1));
  int ret = syscall(SYS_futex, &v, FUTEX_WAIT, 1, NULL, NULL, 0);
예제 #29
0
파일: lock.c 프로젝트: Open-Party/criu
void task_waiter_complete_current(task_waiter_t *t)
{
    return task_waiter_complete(t, (int)sys_gettid());
}
예제 #30
0
static void sighandler(int sig) {
  atomic_printf("Task %d got signal %d\n", sys_gettid(), sig);
  ++num_signals_caught;
}