int main(int argc, char *argv[]) { int fd; ssize_t size; fd = open(TEST_FILE, O_CREAT | O_EXCL | O_RDWR, 0600); test_assert(0 <= fd); size = get_file_size(TEST_FILE); atomic_printf("initial file size: %d\n", size); test_assert(0 == size); truncate(TEST_FILE, 4096); size = get_file_size(TEST_FILE); atomic_printf("after truncate(4096): %d\n", size); test_assert(4096 == size); ftruncate(fd, 8192); size = get_file_size(TEST_FILE); atomic_printf("after truncate(8192): %d\n", size); test_assert(8192 == size); unlink(TEST_FILE); atomic_puts("EXIT-SUCCESS"); return 0; }
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; }
int main(void) { size_t num_bytes = sysconf(_SC_PAGESIZE); int fd = open(DUMMY_FILE, O_CREAT | O_EXCL | O_RDWR, 0600); int* rpage; size_t i; test_assert(fd >= 0); overwrite_file(DUMMY_FILE, num_bytes); rpage = mmap(NULL, num_bytes, PROT_READ, MAP_SHARED, fd, 0); atomic_printf("rpage:%p\n", rpage); test_assert(rpage != (void*)-1); for (i = 0; i < num_bytes / sizeof(magic); ++i) { test_assert(rpage[i] == magic); } lseek(fd, 0, SEEK_SET); for (i = 0; i < num_bytes / sizeof(i); ++i) { int written; write(fd, &i, sizeof(i)); written = rpage[i]; atomic_printf("(wrote %d, read %d)", (int)i, written); test_assert(written == (ssize_t)i); } atomic_puts(" done"); return 0; }
static int interrupted_sleep(void) { struct timespec ts = { .tv_sec = 2 }; alarm(1); errno = 0; /* The implementation of sleep() is technically allowed to use * SIGALRM, so we have to use nanosleep() for pedantry. */ nanosleep(&ts, NULL); return errno; } static int caught_signal; static void handle_signal(int sig) { ++caught_signal; } int main(int argc, char *argv[]) { int err; signal(SIGALRM, SIG_IGN); err = interrupted_sleep(); atomic_printf("No sighandler; sleep exits with errno %d\n", err); test_assert(0 == err); signal(SIGALRM, handle_signal); err = interrupted_sleep(); atomic_printf("With sighandler; sleep exits with errno %d\n", err); test_assert(1 == caught_signal); test_assert(EINTR == err); atomic_puts("EXIT-SUCCESS"); return 1; }
int main(int argc, char* argv[]) { size_t page_size = sysconf(_SC_PAGESIZE); uint8_t* map1 = mmap(NULL, 2 * page_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); uint8_t* map1_end = map1 + 2 * page_size; uint8_t* map2; uint8_t* map2_end; test_assert(map1 != (void*)-1); atomic_printf("map1 = [%p, %p)\n", map1, map1_end); mprotect(map1 + page_size, page_size, PROT_NONE); map2 = mmap(map1_end, 2 * page_size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); map2_end = map2 + page_size; test_assert(map2 != (void*)-1); test_assert(map2 == map1_end); atomic_printf("map2 = [%p, %p)\n", map2, map2_end); mprotect(map2, page_size, PROT_NONE); atomic_puts("EXIT-SUCCESS"); return 0; }
static int child_runner(void) { char ch = 0; pthread_t threads[10]; int i; write_tid(); for (i = 0; i < 10; ++i) { pthread_create(&threads[i], NULL, child_thread, NULL); } atomic_printf("Waiting on ready_pipe\n"); test_assert(1 == read(ready_pipe[0], &ch, 1)); test_assert(ch == 'R'); for (i = 0; i < 10; ++i) { char ch2 = 'W'; test_assert(1 == write(thread_wait_pipe[1], &ch2, 1)); } for (i = 0; i < 10; ++i) { atomic_printf("Joining thread %d\n", i); pthread_join(threads[i], NULL); } char ok = 'K'; test_assert(1 == write(status_pipe[1], &ok, 1)); return 77; }
int main(void) { int filefd; int filefd_out; loff_t off = 0; filefd = open(token_file, O_RDWR | O_CREAT | O_TRUNC, 0600); filefd_out = open(token_file, O_RDWR | O_CREAT | O_TRUNC, 0600); write(filefd, TOKEN, TOKEN_SIZE); sendfile64(filefd_out, filefd, &off, TOKEN_SIZE); atomic_printf( "sendfile %zu bytes from %d to %d; off changed from 0 to %" PRId64 "\n", TOKEN_SIZE, filefd, filefd_out, off); lseek(filefd_out, 0, SEEK_SET); verify_token(filefd_out); lseek(filefd, 0, SEEK_SET); sendfile64(filefd_out, filefd, NULL, TOKEN_SIZE); atomic_printf("sendfile %zu bytes from %d to %d\n", TOKEN_SIZE, filefd, filefd_out); lseek(filefd_out, 0, SEEK_SET); verify_token(filefd_out); /* The test driver will clean up after us if the test failed * before this. */ unlink(token_file); unlink(token_file_out); atomic_puts("EXIT-SUCCESS"); return 0; }
static void read_all_chunks(int sock, char* buf, ssize_t num_sockbuf_bytes, char token) { ssize_t nread = 0; while (nread < num_sockbuf_bytes) { char* this_buf = buf + nread; ssize_t this_read = read(sock, this_buf, num_sockbuf_bytes - nread); int i; atomic_printf("M: read %zd bytes this time,\n", this_read); test_assert(this_read > 0); /* XXX: we would like to assert that the written data * was read in more than one chunk, which should imply * that at least one write() from the other thread * blocked, but it's possible for multiple write()s to * complete and fill the read buffer here before the * reader returns. */ /*test_assert(this_read < num_sockbuf_bytes);*/ for (i = nread; i < nread + this_read; ++i) { if (token != buf[i]) { atomic_printf("M: byte %d should be '%c', but is '%c'\n", i, token, buf[i]); } } nread += this_read; atomic_printf("M: %zd total so far\n", nread); } }
int main(void) { int fd = timerfd_create(CLOCK_MONOTONIC, 0); struct itimerspec spec, old; uint64_t num_expirations; atomic_printf("created timerfd %d\n", fd); test_assert(fd >= 0); memset(&spec, 0, sizeof(spec)); spec.it_value.tv_nsec = 100000000; atomic_printf("setting timer to expire in {sec:%ld,nsec:%ld}\n", spec.it_value.tv_sec, spec.it_value.tv_nsec); timerfd_settime(fd, 0, &spec, &old); atomic_printf(" (old expiration was {sec:%ld,nsec:%ld})\n", old.it_value.tv_sec, old.it_value.tv_nsec); test_assert(0 == old.it_value.tv_sec && 0 == old.it_value.tv_nsec); atomic_puts("sleeping 50ms ..."); usleep(50000); timerfd_gettime(fd, &old); atomic_printf(" expiration now in {sec:%ld,nsec:%ld})\n", old.it_value.tv_sec, old.it_value.tv_nsec); test_assert(0 == old.it_value.tv_sec && old.it_value.tv_nsec <= 50000000); atomic_puts("waiting for timer to expire ..."); read(fd, &num_expirations, sizeof(num_expirations)); atomic_printf(" timer expired %" PRIu64 " times\n", num_expirations); test_assert(1 == num_expirations); atomic_puts("EXIT-SUCCESS"); return 0; }
/** * Fetch and print the ifconfig for this machine. Fill in * |req.ifr_name| with the first non-loopback interface name found. */ static void get_ifconfig(int sockfd, struct ifreq* req) { struct ifreq ifaces[100]; struct ifconf ifconf; int ret; ssize_t num_ifaces; int i; int set_req_iface = 0; ifconf.ifc_len = sizeof(ifaces); ifconf.ifc_req = ifaces; ret = ioctl(sockfd, SIOCGIFCONF, &ifconf); num_ifaces = ifconf.ifc_len / sizeof(ifaces[0]); atomic_printf("SIOCGIFCONF(ret %d): %zd ifaces (%d bytes of ifreq)\n", ret, num_ifaces, ifconf.ifc_len); test_assert(0 == ret); test_assert(0 == (ifconf.ifc_len % sizeof(ifaces[0]))); for (i = 0; i < num_ifaces; ++i) { const struct ifreq* ifc = &ifconf.ifc_req[i]; atomic_printf(" iface %d: name:%s addr:%s\n", i, ifc->ifr_name, sockaddr_name(&ifc->ifr_addr)); if (!set_req_iface && strcmp("lo", ifc->ifr_name)) { strcpy(req->ifr_name, ifc->ifr_name); set_req_iface = 1; } } if (!set_req_iface) { atomic_puts("Only loopback interface found\n"); atomic_puts("EXIT-SUCCESS"); exit(0); } }
int main(int argc, char *argv[]) { char token = start_token; struct timeval ts; /* (Kick on the syscallbuf if it's enabled.) */ gettimeofday(&ts, NULL); socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfds); 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: (longer nap)"); usleep(500000); atomic_printf("M: finishing level 2 reader by writing '%c' to socket ...\n", token); write(sockfds[0], &token, sizeof(token)); ++token; usleep(500000); atomic_printf("M: finishing level 1 reader by writing '%c' to socket ...\n", token); write(sockfds[0], &token, sizeof(token)); ++token; usleep(500000); atomic_printf("M: finishing original reader by writing '%c' to socket ...\n", token); write(sockfds[0], &token, sizeof(token)); ++token; atomic_puts("M: ... done"); pthread_join(reader, NULL); atomic_puts("EXIT-SUCCESS"); return 0; }
static void* thread(void* idp) { int tid = (intptr_t)idp; int i; atomic_printf("thread %d starting ...\n", tid); for (i = 0; i < NUM_TRIALS; ++i) { pthread_mutex_lock(&lock); sched_yield(); pthread_mutex_unlock(&lock); } atomic_printf(" ... thread %d done.\n", tid); return NULL; }
int main(void) { long pagesize = sysconf(_SC_PAGESIZE); long ncpus = sysconf(_SC_NPROCESSORS_ONLN); atomic_printf("sysconf says page size is %ld bytes\n", pagesize); test_assert(4096 == pagesize); atomic_printf("sysconf says %ld processors are online\n", ncpus); /* TODO: change this when rr supports parallel recording. */ test_assert(1 == ncpus); atomic_puts("EXIT-SUCCESS"); return 0; }
int main(int argc, char* argv[]) { gid_t groups[1024]; int num_groups = getgroups(ALEN(groups), groups); int i; atomic_printf("User %d belongs to %d groups:\n ", geteuid(), num_groups); for (i = 0; i < num_groups; ++i) { atomic_printf("%d,", groups[i]); } atomic_puts(""); atomic_puts("EXIT-SUCCESS"); return 0; }
int main(int argc, char* argv[]) { pid_t sid1; pid_t sid2; sid1 = getsid(0); sid2 = getsid(sid1); atomic_printf("getsid(0) session ID: %d\n", sid1); atomic_printf("getsid(getsid(0)) session ID: %d\n", sid2); if (sid1 == sid2) { atomic_puts("EXIT-SUCCESS"); } return 0; }
int main(void) { int sum; getegid(); sum = cpuid_loop(1000); atomic_printf("EXIT-SUCCESS; sum=%d\n", sum); return 0; }
int main(void) { pid_t child; int status; size_t page_size = sysconf(_SC_PAGESIZE); shmem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0); test_assert(shmem != (void*)-1); semid = semget(IPC_PRIVATE, COUNT, 0666); test_assert(semid >= 0); if ((child = fork()) == 0) { return run_child(); } atomic_printf("child %d\n", child); test_assert(child == waitpid(child, &status, __WALL)); /* delete the sem before testing status, because we want to ensure the segment is deleted even if the test failed. */ test_assert(0 == semctl(semid, 0, IPC_RMID, NULL)); test_assert(status == 0); atomic_puts("EXIT-SUCCESS"); return 0; }
static void waittermsig(int sig, const char* waiter) { struct timespec ts = {.tv_sec = 1 }; sigset_t set; siginfo_t si; sigemptyset(&set); sigaddset(&set, sig); sigtimedwait(&set, &si, &ts); atomic_printf("FAILED: %s: signal %d either not caught or didn't terminate " "process within 1 second\n", waiter, sig); } static void* kill_thread(void* dontcare) { const int termsig = SIGTERM; atomic_puts("killing..."); kill(getpid(), termsig); waittermsig(termsig, "kill_thread"); return NULL; /* not reached */ } int main(int argc, char* argv[]) { pthread_t t; pthread_create(&t, NULL, kill_thread, NULL); pthread_join(t, NULL); atomic_puts("FAILED: joined thread that should have died"); return 0; }
int main(int argc, char* argv[]) { struct tms* buf; clock_t t; ALLOCATE_GUARD(buf, -1); test_assert((t = times(buf)) != (clock_t)-1); test_assert(buf->tms_cutime == 0); test_assert(buf->tms_utime >= 0); VERIFY_GUARD(buf); atomic_printf("tms_utime = %lld\n", (long long)buf->tms_utime); atomic_printf("result = %lld\n", (long long)t); atomic_puts("EXIT-SUCCESS"); return 0; }
int main(int argc, char* argv[]) { char token = start_token; struct timeval ts; int i; /* (Kick on the syscallbuf if it's enabled.) */ gettimeofday(&ts, NULL); socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfds); pthread_barrier_init(&barrier, NULL, 2); pthread_create(&reader, NULL, reader_thread, NULL); pthread_barrier_wait(&barrier); atomic_puts("M: sleeping ..."); usleep(500000); for (i = 0; i < 4; ++i) { atomic_puts("M: killing reader ..."); pthread_kill(reader, SIGUSR1); atomic_puts("M: sleeping ..."); sleep(1); } atomic_printf("M: finishing original reader by writing '%c' to socket ...\n", token); write(sockfds[0], &token, sizeof(token)); ++token; atomic_puts("M: ... done"); pthread_join(reader, NULL); atomic_puts("EXIT-SUCCESS"); return 0; }
static int ptracer(void) { pid_t child; int status; char ready = 'R'; int i; pid_t child_tids[11]; if (0 == (child = fork())) { return child_runner(); } for (i = 0; i < 11; ++i) { child_tids[i] = read_tid(); } for (i = 0; i < 11; ++i) { int ret; test_assert(0 == ptrace(PTRACE_ATTACH, child_tids[i], NULL, NULL)); ret = waitpid(child_tids[i], &status, __WALL); atomic_printf("waitpid on %d gives %d with errno=%d\n", child_tids[i], ret, errno); test_assert(ret == child_tids[i]); test_assert(status == ((SIGSTOP << 8) | 0x7f)); } test_assert(1 == write(ready_pipe[1], &ready, 1)); /* Now just exit, and all child threads should resume */ return 44; }
int main(int argc, char* argv[]) { pid_t child; int status; depth = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0); test_assert(depth != MAP_FAILED); child = fork(); if (!child) { struct sigaction act; int* fake_sp = &argc; act.sa_sigaction = SEGV_handler; act.sa_flags = SA_SIGINFO; sigemptyset(&act.sa_mask); test_assert(0 == sigaction(SIGSEGV, &act, NULL)); void* p = (void*)((size_t)(fake_sp - 8 * PAGE_SIZE) & ~(size_t)(PAGE_SIZE - 1)); test_assert(mmap(p, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0) == p); return recurse(); } test_assert(wait(&status) == child); test_assert(WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV); atomic_printf("depth = %d\n", *depth); atomic_puts("EXIT-SUCCESS"); return 0; }
static void assert_prname_is(const char* tag, const char* name) { char prname[PRNAME_NUM_BYTES] = ""; test_assert(0 == prctl(PR_GET_NAME, prname)); atomic_printf("%s: prname is '%s'; expecting '%s'\n", tag, prname, name); test_assert(!strcmp(prname, name)); }
int main(int argc, char* argv[]) { ssize_t pagesize = sysconf(_SC_PAGESIZE); ssize_t two_pages_size = 2 * pagesize; void* two_pages = mmap(NULL, two_pages_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); void* two_pages_end = two_pages + two_pages_size; char* cwd; char* expected_cwd; test_assert(argc == 2); expected_cwd = argv[1]; test_assert(two_pages != (void*)-1); /* Make the value returned into |path| overlap two physical * pages. */ cwd = two_pages + pagesize - 3; /* Fill pages with non-zeroes to ensure the returned string is * properly null-terminated */ memset(two_pages, 0xFF, two_pages_size); test_assert(cwd == getcwd(cwd, two_pages_end - (void*)cwd)); atomic_printf("current working directory is %s; should be %s\n", cwd, expected_cwd); test_assert(!strcmp(cwd, expected_cwd)); /* Make sure we didn't write too many bytes */ test_assert((unsigned char)cwd[strlen(cwd) + 1] == 0xFF); atomic_puts("EXIT-SUCCESS"); return 0; }
void print_nums(void) { int i; for (i = 1; i <= 5; ++i) { atomic_printf("%d ", i); } atomic_puts(""); }
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; }
int main(void) { size_t page_size = sysconf(_SC_PAGESIZE); int fd = open(FILENAME, O_CREAT | O_EXCL | O_RDWR, 0600); int* wpage; size_t i; int* rpage; unlink(FILENAME); test_assert(fd >= 0); ftruncate(fd, page_size); wpage = mmap(NULL, page_size, PROT_WRITE, MAP_SHARED, fd, 0); test_assert(wpage != (void*)-1); for (i = 0; i < page_size / sizeof(int); ++i) { wpage[i] = i; } rpage = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0); test_assert(rpage != (void*)-1 && wpage != rpage); msync(wpage, page_size, MS_INVALIDATE); for (i = 0; i < page_size / sizeof(int); ++i) { test_assert(rpage[i] == (ssize_t)i); atomic_printf("%d,", rpage[i]); } atomic_puts("EXIT-SUCCESS"); return 0; }
int main(int argc, char* argv[]) { int fds[2]; struct pollfd pfd; int i; pipe2(fds, O_NONBLOCK); pfd.fd = fds[0]; pfd.events = POLLIN; for (i = 0; i < NUM_ITERATIONS; ++i) { char c; atomic_printf("iteration %d\n", i); if (0 == fork()) { usleep(250000); write(fds[1], "x", 1); return 0; } test_assert(1 == poll(&pfd, 1, -1)); test_assert(POLLIN & pfd.revents); test_assert(1 == read(pfd.fd, &c, 1)); } atomic_puts("EXIT-SUCCESS"); return 0; }
static void check_mapping(int* page, int magic, ssize_t nr_ints) { int i; for (i = 0; i < nr_ints; ++i) { test_assert(page[i] == magic); } atomic_printf(" %p has the correct values\n", page); }
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; }