diff --git a/test/strace/issue/943.c b/test/strace/issue/943.c new file mode 100644 index 00000000..e280fb60 --- /dev/null +++ b/test/strace/issue/943.c @@ -0,0 +1,343 @@ +#define __BSD_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +long +_ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data) +{ + long rc; + + rc = ptrace(request, pid, addr, data); + if (rc == -1) { + printf("ptrace(%d, %d, %016x, %016x): %d\n", request, pid, + (long)addr, (long)data, errno); + exit(1); + } + return rc; +} + +typedef struct user_regs_struct syscall_args; + +static inline int +get_syscall_args(int pid, syscall_args *args) +{ + return _ptrace(PTRACE_GETREGS, pid, NULL, args); +} + +static inline unsigned long +get_syscall_number(syscall_args *args) +{ + return args->orig_rax; +} + +static inline unsigned long +get_syscall_return(syscall_args *args) +{ + return args->rax; +} + +static char *syscalls[512]; + +char * +trim(char *buf) +{ + char *p; + char *q; + + for (p = buf; *p && (isspace(*p)); p++); + if (!*p) + return p; + for (q = strchr(p, '\0') - 1; isspace(*q); q--) + *q = '\0'; + return p; +} + +char ** +split(char *buf, char dlm) +{ + int n; + char *t; + char **r; + char **p; + + for (n = 0, t = buf; *t; t++) + if (*t == dlm) + n++; + p = r = malloc(sizeof(char *) * (n + 2) + strlen(buf) + 1); + t = (char *)(r + n + 2); + strcpy(t, buf); + t = trim(t); + if (*t) { + *(p++) = t; + for (; *t; t++) + if (*t == dlm) { + *(t++) = '\0'; + t = trim(t); + trim(p[-1]); + if (!*t) + break; + *(p++) = t; + } + } + *p = NULL; + return r; +} + +void +init_syscalls() +{ + char buf[1024]; + FILE *f; + + f = fopen("/usr/include/asm/unistd_64.h", "r"); + if (!f) { + perror("open(unistd_64.h)"); + return; + } + while (fgets(buf, 1024, f)) { + char *t; + char **a; + + if (strncmp(buf, "#define", 7)) + continue; + for (t = buf; *t; t++) + if (isspace(*t)) + *t = ' '; + a = split(buf, ' '); + if (a[0] && a[1] && !strncmp(a[1], "__NR_", 5) && + a[2] && *(a[2]) >= '0' && *(a[2]) <= '9') { + int num = atoi(a[2]); + syscalls[num] = strdup(a[1] + 5); + } + free(a); + } + fclose(f); +} + +const char * +get_syscall(int n, char *buf) +{ + if (n < 0 || n >= 512 || !syscalls[n]) { + sprintf(buf, "unknown(%d)", n); + return NULL; + } + return strcpy(buf, syscalls[n]); +} + +int +main(int argc, char **argv) +{ + pid_t pid; + pid_t cpid; + unsigned long msg; + int st; + int rc; + long ret; + int w; + syscall_args args; + unsigned long sig = 0; + char name[64]; + int c = 0; + int ok = 0; + int ng = 0; + + printf("#943 test start\n"); + init_syscalls(); +// printf("tracer pid=%d\n", getpid()); +// fflush(stdout); + pid = fork(); + if(pid == 0){ + if (_ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) { + printf("ptrace error %d\n", errno); + } + kill(getpid(), SIGINT); + syscall(SYS_gettid); + open("/", O_WRONLY); + syscall(-1); + exit(15); + } + rc = waitpid(-1, &st, WUNTRACED); + if (rc != pid || !WIFSTOPPED(st)) { + printf("BAD1 rc=%d st=%08x\n", rc, st); + exit(1); + } + _ptrace(PTRACE_SETOPTIONS, pid, NULL, (void *)(PTRACE_O_TRACESYSGOOD | + PTRACE_O_TRACEFORK | + PTRACE_O_TRACEVFORK | + PTRACE_O_TRACECLONE | + PTRACE_O_TRACEEXEC)); + + rc = pid; + for (;;) { + if (rc != -1) + _ptrace(PTRACE_SYSCALL, rc, NULL, (void *)sig); + sig = 0; + rc = waitpid(-1, &st, WUNTRACED); + if (rc == -1) { + printf("wait error %d\n", errno); + exit(1); + } + if (WIFEXITED(st)) { + if (WEXITSTATUS(st) != 15) { + printf("tracee BAD status %08x\n", st); + ng++; + } + break; + } + if (WIFSIGNALED(st)) { + printf("tracee BAD signaled %08x\n", st); + ng++; + break; + } + if (!WIFSTOPPED(st)) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("unrecognized status rc=%d st=%08x\n", rc, st); + fflush(stdout); + continue; + } + if ((w = (st >> 16) & 255) == PTRACE_EVENT_FORK || + w == PTRACE_EVENT_VFORK || + w == PTRACE_EVENT_CLONE || + w == PTRACE_EVENT_VFORK_DONE) { + int crc; + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: fork exent ev=%d\n", rc, w); + fflush(stdout); + _ptrace(PTRACE_GETEVENTMSG, pid, NULL, &msg); + cpid = msg; + printf("child pid=%d\n", cpid); + fflush(stdout); + crc = waitpid(-1, &st, WUNTRACED); + if (crc != cpid || !WIFSTOPPED(st)) { + printf("BAD4 rc=%d st=%08x\n", crc, st); + exit(1); + } + printf("wait(2) rc=%d st=%08x\n", crc, st); + fflush(stdout); + _ptrace(PTRACE_SYSCALL, cpid, NULL, (void *)0); + continue; + } + if (w == PTRACE_EVENT_EXEC) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exec event\n", rc); + fflush(stdout); + continue; + } + if (w == PTRACE_EVENT_EXIT) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exit event\n", rc); + fflush(stdout); + continue; + } + if (WSTOPSIG(st) & 0x80) { // syscall + int num; + get_syscall_args(rc, &args); + num = get_syscall_number(&args); + ret = get_syscall_return(&args); + c++; + switch (c) { + case 1: // gettid in + if (num == SYS_gettid && + ret == -ENOSYS) { + printf("#943-1 gettid in OK\n"); + ok++; + } + else { + printf("#943-1 gettid in NG\n"); + ng++; + } + continue; + case 2: // gettid out + if (num == SYS_gettid && + ret != -ENOSYS) { + printf("#943-2 gettid out OK\n"); + ok++; + } + else { + printf("#943-2 gettid out NG\n"); + ng++; + } + continue; + case 3: // open in + if (num == SYS_open && + ret == -ENOSYS) { + printf("#943-3 open in OK\n"); + ok++; + } + else { + printf("#943-3 open in NG\n"); + ng++; + } + continue; + case 4: // open out + if (num == SYS_open && + ret != -ENOSYS) { + printf("#943-4 open out OK\n"); + ok++; + } + else { + printf("#943-4 open out NG\n"); + ng++; + } + continue; + case 5: // err_syscall in + if (num == -1 && + ret == -ENOSYS) { + printf("#943-5 bad syscall in OK\n"); + ok++; + } + else { + printf("#943-5 bad syscall in NG\n"); + ng++; + } + continue; + case 6: // err_syscall out + if (num == -1 && + ret == -ENOSYS) { + printf("#943-6 bad syscall out OK\n"); + ok++; + } + else { + printf("#943-6 bad syscall out NG\n"); + ng++; + } + continue; + } +// if (num == __NR_open || +// num == __NR_access || +// num == __NR_stat) +// continue; +// printf("wait(1) rc=%d st=%08x\n", rc, st); +// fflush(stdout); +// if (get_syscall_return(&args) == -ENOSYS) { +// get_syscall(num, name); +// printf("%d: syscall=%s\n", rc, name); +// } +// else { +// get_syscall(num, name); +// printf("%d: syscall=%s rc=%ld\n", rc, name, +// get_syscall_return(&args)); +// } +// fflush(stdout); + } + else { // signal +// printf("wait(1) rc=%d st=%08x\n", rc, st); + sig = WSTOPSIG(st) & 0x7f; + printf("tracee receive signal %d\n", sig); + fflush(stdout); + ng++; + } + } + printf("#943 test terminated ok=%d ng=%d\n", ok, ng); + fflush(stdout); + exit(0); +} diff --git a/test/strace/issue/944.c b/test/strace/issue/944.c new file mode 100755 index 00000000..39bba7ce --- /dev/null +++ b/test/strace/issue/944.c @@ -0,0 +1,343 @@ +#define __BSD_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +long +_ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data) +{ + long rc; + + rc = ptrace(request, pid, addr, data); + if (rc == -1) { + printf("ptrace(%d, %d, %016x, %016x): %d\n", request, pid, + (long)addr, (long)data, errno); + exit(1); + } + return rc; +} + +typedef struct user_regs_struct syscall_args; + +static inline int +get_syscall_args(int pid, syscall_args *args) +{ + return _ptrace(PTRACE_GETREGS, pid, NULL, args); +} + +static inline unsigned long +get_syscall_number(syscall_args *args) +{ + return args->orig_rax; +} + +static inline unsigned long +get_syscall_return(syscall_args *args) +{ + return args->rax; +} + +static char *syscalls[512]; + +char * +trim(char *buf) +{ + char *p; + char *q; + + for (p = buf; *p && (isspace(*p)); p++); + if (!*p) + return p; + for (q = strchr(p, '\0') - 1; isspace(*q); q--) + *q = '\0'; + return p; +} + +char ** +split(char *buf, char dlm) +{ + int n; + char *t; + char **r; + char **p; + + for (n = 0, t = buf; *t; t++) + if (*t == dlm) + n++; + p = r = malloc(sizeof(char *) * (n + 2) + strlen(buf) + 1); + t = (char *)(r + n + 2); + strcpy(t, buf); + t = trim(t); + if (*t) { + *(p++) = t; + for (; *t; t++) + if (*t == dlm) { + *(t++) = '\0'; + t = trim(t); + trim(p[-1]); + if (!*t) + break; + *(p++) = t; + } + } + *p = NULL; + return r; +} + +void +init_syscalls() +{ + char buf[1024]; + FILE *f; + + f = fopen("/usr/include/asm/unistd_64.h", "r"); + if (!f) { + perror("open(unistd_64.h)"); + return; + } + while (fgets(buf, 1024, f)) { + char *t; + char **a; + + if (strncmp(buf, "#define", 7)) + continue; + for (t = buf; *t; t++) + if (isspace(*t)) + *t = ' '; + a = split(buf, ' '); + if (a[0] && a[1] && !strncmp(a[1], "__NR_", 5) && + a[2] && *(a[2]) >= '0' && *(a[2]) <= '9') { + int num = atoi(a[2]); + syscalls[num] = strdup(a[1] + 5); + } + free(a); + } + fclose(f); +} + +const char * +get_syscall(int n, char *buf) +{ + if (n < 0 || n >= 512 || !syscalls[n]) { + sprintf(buf, "unknown(%d)", n); + return NULL; + } + return strcpy(buf, syscalls[n]); +} + +int +main(int argc, char **argv) +{ + pid_t pid; + pid_t cpid; + unsigned long msg; + int st; + int rc; + long ret; + int w; + syscall_args args; + unsigned long sig = 0; + char name[64]; + int c = 0; + int ok = 0; + int ng = 0; + + printf("#944 test start\n"); + init_syscalls(); +// printf("tracer pid=%d\n", getpid()); +// fflush(stdout); + pid = fork(); + if(pid == 0){ + if (_ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) { + printf("ptrace error %d\n", errno); + } + kill(getpid(), SIGINT); + syscall(SYS_gettid); + open("/", O_WRONLY); + syscall(-1); + exit(15); + } + rc = waitpid(-1, &st, WUNTRACED); + if (rc != pid || !WIFSTOPPED(st)) { + printf("BAD1 rc=%d st=%08x\n", rc, st); + exit(1); + } + _ptrace(PTRACE_SETOPTIONS, pid, NULL, (void *)(PTRACE_O_TRACESYSGOOD | + PTRACE_O_TRACEFORK | + PTRACE_O_TRACEVFORK | + PTRACE_O_TRACECLONE | + PTRACE_O_TRACEEXEC)); + + rc = pid; + for (;;) { + if (rc != -1) + _ptrace(PTRACE_SYSCALL, rc, NULL, (void *)sig); + sig = 0; + rc = waitpid(-1, &st, WUNTRACED); + if (rc == -1) { + printf("wait error %d\n", errno); + exit(1); + } + if (WIFEXITED(st)) { + if (WEXITSTATUS(st) != 15) { + printf("tracee BAD status %08x\n", st); + ng++; + } + break; + } + if (WIFSIGNALED(st)) { + printf("tracee BAD signaled %08x\n", st); + ng++; + break; + } + if (!WIFSTOPPED(st)) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("unrecognized status rc=%d st=%08x\n", rc, st); + fflush(stdout); + continue; + } + if ((w = (st >> 16) & 255) == PTRACE_EVENT_FORK || + w == PTRACE_EVENT_VFORK || + w == PTRACE_EVENT_CLONE || + w == PTRACE_EVENT_VFORK_DONE) { + int crc; + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: fork exent ev=%d\n", rc, w); + fflush(stdout); + _ptrace(PTRACE_GETEVENTMSG, pid, NULL, &msg); + cpid = msg; + printf("child pid=%d\n", cpid); + fflush(stdout); + crc = waitpid(-1, &st, WUNTRACED); + if (crc != cpid || !WIFSTOPPED(st)) { + printf("BAD4 rc=%d st=%08x\n", crc, st); + exit(1); + } + printf("wait(2) rc=%d st=%08x\n", crc, st); + fflush(stdout); + _ptrace(PTRACE_SYSCALL, cpid, NULL, (void *)0); + continue; + } + if (w == PTRACE_EVENT_EXEC) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exec event\n", rc); + fflush(stdout); + continue; + } + if (w == PTRACE_EVENT_EXIT) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exit event\n", rc); + fflush(stdout); + continue; + } + if (WSTOPSIG(st) & 0x80) { // syscall + int num; + get_syscall_args(rc, &args); + num = get_syscall_number(&args); + ret = get_syscall_return(&args); + c++; + switch (c) { + case 1: // gettid in + if (num == SYS_gettid && + ret == -ENOSYS) { + printf("#944-1 gettid in OK\n"); + ok++; + } + else { + printf("#944-1 gettid in NG\n"); + ng++; + } + continue; + case 2: // gettid out + if (num == SYS_gettid && + ret == pid) { + printf("#944-2 gettid out OK\n"); + ok++; + } + else { + printf("#944-2 gettid out NG\n"); + ng++; + } + continue; + case 3: // open in + if (num == SYS_open && + ret == -ENOSYS) { + printf("#944-3 open in OK\n"); + ok++; + } + else { + printf("#944-3 open in NG\n"); + ng++; + } + continue; + case 4: // open out + if (num == SYS_open && + ret == -EISDIR) { + printf("#944-4 open out OK\n"); + ok++; + } + else { + printf("#944-4 open out NG\n"); + ng++; + } + continue; + case 5: // err_syscall in + if (num == -1 && + ret == -ENOSYS) { + printf("#944-5 bad syscall in OK\n"); + ok++; + } + else { + printf("#944-5 bad syscall in NG\n"); + ng++; + } + continue; + case 6: // err_syscall out + if (num == -1 && + ret == -ENOSYS) { + printf("#944-6 bad syscall out OK\n"); + ok++; + } + else { + printf("#944-6 bad syscall out NG\n"); + ng++; + } + continue; + } +// if (num == __NR_open || +// num == __NR_access || +// num == __NR_stat) +// continue; +// printf("wait(1) rc=%d st=%08x\n", rc, st); +// fflush(stdout); +// if (get_syscall_return(&args) == -ENOSYS) { +// get_syscall(num, name); +// printf("%d: syscall=%s\n", rc, name); +// } +// else { +// get_syscall(num, name); +// printf("%d: syscall=%s rc=%ld\n", rc, name, +// get_syscall_return(&args)); +// } +// fflush(stdout); + } + else { // signal +// printf("wait(1) rc=%d st=%08x\n", rc, st); + sig = WSTOPSIG(st) & 0x7f; + printf("tracee receive signal %d\n", sig); + fflush(stdout); + ng++; + } + } + printf("#944 test terminated ok=%d ng=%d\n", ok, ng); + fflush(stdout); + exit(0); +} diff --git a/test/strace/issue/945.c b/test/strace/issue/945.c new file mode 100644 index 00000000..0667428e --- /dev/null +++ b/test/strace/issue/945.c @@ -0,0 +1,278 @@ +#define __BSD_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +long +_ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data) +{ + long rc; + + rc = ptrace(request, pid, addr, data); + if (rc == -1) { + printf("ptrace(%d, %d, %016x, %016x): %d\n", request, pid, + (long)addr, (long)data, errno); + exit(1); + } + return rc; +} + +typedef struct user_regs_struct syscall_args; + +static inline int +get_syscall_args(int pid, syscall_args *args) +{ + return _ptrace(PTRACE_GETREGS, pid, NULL, args); +} + +static inline unsigned long +get_syscall_number(syscall_args *args) +{ + return args->orig_rax; +} + +static inline unsigned long +get_syscall_return(syscall_args *args) +{ + return args->rax; +} + +static char *syscalls[512]; + +char * +trim(char *buf) +{ + char *p; + char *q; + + for (p = buf; *p && (isspace(*p)); p++); + if (!*p) + return p; + for (q = strchr(p, '\0') - 1; isspace(*q); q--) + *q = '\0'; + return p; +} + +char ** +split(char *buf, char dlm) +{ + int n; + char *t; + char **r; + char **p; + + for (n = 0, t = buf; *t; t++) + if (*t == dlm) + n++; + p = r = malloc(sizeof(char *) * (n + 2) + strlen(buf) + 1); + t = (char *)(r + n + 2); + strcpy(t, buf); + t = trim(t); + if (*t) { + *(p++) = t; + for (; *t; t++) + if (*t == dlm) { + *(t++) = '\0'; + t = trim(t); + trim(p[-1]); + if (!*t) + break; + *(p++) = t; + } + } + *p = NULL; + return r; +} + +void +init_syscalls() +{ + char buf[1024]; + FILE *f; + + f = fopen("/usr/include/asm/unistd_64.h", "r"); + if (!f) { + perror("open(unistd_64.h)"); + return; + } + while (fgets(buf, 1024, f)) { + char *t; + char **a; + + if (strncmp(buf, "#define", 7)) + continue; + for (t = buf; *t; t++) + if (isspace(*t)) + *t = ' '; + a = split(buf, ' '); + if (a[0] && a[1] && !strncmp(a[1], "__NR_", 5) && + a[2] && *(a[2]) >= '0' && *(a[2]) <= '9') { + int num = atoi(a[2]); + syscalls[num] = strdup(a[1] + 5); + } + free(a); + } + fclose(f); +} + +const char * +get_syscall(int n, char *buf) +{ + if (n < 0 || n >= 512 || !syscalls[n]) { + sprintf(buf, "unknown(%d)", n); + return NULL; + } + return strcpy(buf, syscalls[n]); +} + +int +main(int argc, char **argv) +{ + pid_t pid; + pid_t cpid; + unsigned long msg; + int st; + int rc; + int w; + syscall_args args; + unsigned long sig = 0; + char name[64]; + int ok = 0; + int ng = 0; + int execev = 0; + int c = 0; + + init_syscalls(); + printf("#945 start\n"); + fflush(stdout); + pid = fork(); + if(pid == 0){ + _ptrace(PTRACE_TRACEME, 0, NULL, NULL); + kill(getpid(), SIGINT); + execl("/bin/sleep", "/bin/sleep", "0", NULL); + exit(32); + } + rc = waitpid(-1, &st, WUNTRACED); + if (rc != pid || !WIFSTOPPED(st)) { + printf("BAD1 rc=%d st=%08x\n", rc, st); + exit(1); + } + _ptrace(PTRACE_SETOPTIONS, pid, NULL, (void *)(PTRACE_O_TRACESYSGOOD | + PTRACE_O_TRACEFORK | + PTRACE_O_TRACEVFORK | + PTRACE_O_TRACECLONE | + PTRACE_O_TRACEEXEC)); + + rc = pid; + for (;;) { + if (rc != -1) + _ptrace(PTRACE_SYSCALL, rc, NULL, (void *)sig); + sig = 0; + rc = waitpid(-1, &st, WUNTRACED); + if (WIFEXITED(st)) { + if (WEXITSTATUS(st) != 0) { + printf("tracee BAD status %08x\n", st); + ng++; + } + break; + } + if (WIFEXITED(st) || WIFSIGNALED(st)) { + printf("tracee BAD signaled %08x\n", st); + ng++; + break; + } + if (!WIFSTOPPED(st)) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("unrecognized status rc=%d st=%08x\n", rc, st); + fflush(stdout); + continue; + } + if ((w = (st >> 16) & 255) == PTRACE_EVENT_FORK || + w == PTRACE_EVENT_VFORK || + w == PTRACE_EVENT_CLONE || + w == PTRACE_EVENT_VFORK_DONE) { + int crc; + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: fork exent ev=%d\n", rc, w); + fflush(stdout); + _ptrace(PTRACE_GETEVENTMSG, pid, NULL, &msg); + cpid = msg; + printf("child pid=%d\n", cpid); + fflush(stdout); + crc = waitpid(-1, &st, WUNTRACED); + if (crc != cpid || !WIFSTOPPED(st)) { + printf("BAD4 rc=%d st=%08x\n", crc, st); + exit(1); + } + printf("wait(2) rc=%d st=%08x\n", crc, st); + fflush(stdout); + _ptrace(PTRACE_SYSCALL, cpid, NULL, (void *)0); + continue; + } + if (w == PTRACE_EVENT_EXEC) { + execev++; + ok++; + printf("#945-2 PTRACE_EVENT_EXEC OK\n"); + continue; + } + if (w == PTRACE_EVENT_EXIT) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exit event\n", rc); + fflush(stdout); + continue; + } + if (WSTOPSIG(st) & 0x80) { // syscall + int num; + long ret; + + get_syscall_args(rc, &args); + num = get_syscall_number(&args); + ret = get_syscall_return(&args); + c++; + switch(c) { + case 1: + if (num == SYS_execve && + ret == -ENOSYS) { + printf("#945-1 execve in OK\n"); + ok++; + } + else { + printf("#945-1 execve in NG\n"); + ng++; + } + break; + case 2: + if (num == SYS_execve && + ret == 0) { + printf("#945-3 execve out OK\n"); + ok++; + } + else { + printf("#945-3 execve out NG\n"); + ng++; + } + break; + } + fflush(stdout); + } + else { // signal + sig = WSTOPSIG(st) & 0x7f; + printf("tracee receive signal %d\n", sig); + fflush(stdout); + } + } + if (execev != 1) { + ng++; + printf("#945-2 NO PTRACE_EVENT_EXEC NG\n"); + } + printf("#945 test terminated ok=%d ng=%d\n", ok, ng); + fflush(stdout); + exit(0); +} diff --git a/test/strace/issue/946.c b/test/strace/issue/946.c new file mode 100644 index 00000000..6ed9f406 --- /dev/null +++ b/test/strace/issue/946.c @@ -0,0 +1,320 @@ +#define __BSD_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +long +_ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data) +{ + long rc; + + rc = ptrace(request, pid, addr, data); + if (rc == -1) { + printf("ptrace(%d, %d, %016x, %016x): %d\n", request, pid, + (long)addr, (long)data, errno); + exit(1); + } + return rc; +} + +typedef struct user_regs_struct syscall_args; + +static inline int +get_syscall_args(int pid, syscall_args *args) +{ + return _ptrace(PTRACE_GETREGS, pid, NULL, args); +} + +static inline unsigned long +get_syscall_number(syscall_args *args) +{ + return args->orig_rax; +} + +static inline unsigned long +get_syscall_return(syscall_args *args) +{ + return args->rax; +} + +static char *syscalls[512]; + +char * +trim(char *buf) +{ + char *p; + char *q; + + for (p = buf; *p && (isspace(*p)); p++); + if (!*p) + return p; + for (q = strchr(p, '\0') - 1; isspace(*q); q--) + *q = '\0'; + return p; +} + +char ** +split(char *buf, char dlm) +{ + int n; + char *t; + char **r; + char **p; + + for (n = 0, t = buf; *t; t++) + if (*t == dlm) + n++; + p = r = malloc(sizeof(char *) * (n + 2) + strlen(buf) + 1); + t = (char *)(r + n + 2); + strcpy(t, buf); + t = trim(t); + if (*t) { + *(p++) = t; + for (; *t; t++) + if (*t == dlm) { + *(t++) = '\0'; + t = trim(t); + trim(p[-1]); + if (!*t) + break; + *(p++) = t; + } + } + *p = NULL; + return r; +} + +void +init_syscalls() +{ + char buf[1024]; + FILE *f; + + f = fopen("/usr/include/asm/unistd_64.h", "r"); + if (!f) { + perror("open(unistd_64.h)"); + return; + } + while (fgets(buf, 1024, f)) { + char *t; + char **a; + + if (strncmp(buf, "#define", 7)) + continue; + for (t = buf; *t; t++) + if (isspace(*t)) + *t = ' '; + a = split(buf, ' '); + if (a[0] && a[1] && !strncmp(a[1], "__NR_", 5) && + a[2] && *(a[2]) >= '0' && *(a[2]) <= '9') { + int num = atoi(a[2]); + syscalls[num] = strdup(a[1] + 5); + } + free(a); + } + fclose(f); +} + +const char * +get_syscall(int n, char *buf) +{ + if (n < 0 || n >= 512 || !syscalls[n]) { + sprintf(buf, "unknown(%d)", n); + return NULL; + } + return strcpy(buf, syscalls[n]); +} + +int +main(int argc, char **argv) +{ + pid_t pid; + pid_t cpid; + unsigned long msg; + int st; + int rc; + int w; + syscall_args args; + unsigned long sig = 0; + char name[64]; + int pipefds[2]; + char ch = ' '; + int ok = 0; + int ng = 0; + int procs = 0; + + init_syscalls(); + printf("#946 start\n"); + fflush(stdout); + pipe(pipefds); + pid = fork(); + if(pid == 0){ + close(pipefds[0]); + _ptrace(PTRACE_TRACEME, 0, NULL, NULL); + kill(getpid(), SIGINT); + pid = fork(); + if (pid == 0) { + exit(16); + } + sleep(1); + rc = wait(&st); + if (rc == pid && + WIFEXITED(st) && + WEXITSTATUS(st) == 16) { + printf("#946-1 exit after wait OK\n"); + write(pipefds[1], "0", 1); + } + else { + printf("#946-1 exit after wait NG\n"); + write(pipefds[1], "1", 1); + } + pid = fork(); + if (pid == 0) { + sleep(1); + exit(32); + } + rc = wait(&st); + if (rc == pid && + WIFEXITED(st) && + WEXITSTATUS(st) == 32) { + printf("#946-2 exit before wait OK\n"); + write(pipefds[1], "0", 1); + } + else { + printf("#946-2 exit before wait NG\n"); + write(pipefds[1], "1", 1); + } + close(pipefds[1]); + fflush(stdout); + exit(64); + } + close(pipefds[1]); + rc = waitpid(-1, &st, WUNTRACED); + if (rc != pid || !WIFSTOPPED(st)) { + printf("BAD1 rc=%d st=%08x\n", rc, st); + exit(1); + } + _ptrace(PTRACE_SETOPTIONS, pid, NULL, (void *)(PTRACE_O_TRACESYSGOOD | + PTRACE_O_TRACEFORK | + PTRACE_O_TRACEVFORK | + PTRACE_O_TRACECLONE | + PTRACE_O_TRACEEXEC)); + + rc = pid; + procs = 1; + for (;;) { + if (rc != -1) + _ptrace(PTRACE_SYSCALL, rc, NULL, (void *)sig); + sig = 0; + rc = waitpid(-1, &st, WUNTRACED); + if (WIFEXITED(st) || WIFSIGNALED(st)) { +// printf("wait(1) rc=%d st=%08x\n", rc, st); + procs--; +// printf("%d: terminate procs=%d\n", rc, procs); +// fflush(stdout); + if (rc == pid) + pid = -1; + else if (rc == cpid) + cpid = -1; + rc = -1; + if (!procs) { + break; + } + continue; + } + if (!WIFSTOPPED(st)) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("unrecognized status rc=%d st=%08x\n", rc, st); + fflush(stdout); + continue; + } + if ((w = (st >> 16) & 255) == PTRACE_EVENT_FORK || + w == PTRACE_EVENT_VFORK || + w == PTRACE_EVENT_CLONE || + w == PTRACE_EVENT_VFORK_DONE) { + int crc; +// printf("wait(1) rc=%d st=%08x\n", rc, st); +// printf("%d: fork exent ev=%d\n", rc, w); +// fflush(stdout); + _ptrace(PTRACE_GETEVENTMSG, pid, NULL, &msg); + cpid = msg; +// printf("child pid=%d\n", cpid); +// fflush(stdout); + crc = waitpid(-1, &st, WUNTRACED); + if (crc != cpid || !WIFSTOPPED(st)) { + printf("BAD4 rc=%d st=%08x\n", crc, st); + exit(1); + } +// printf("wait(2) rc=%d st=%08x\n", crc, st); +// fflush(stdout); + procs++; + _ptrace(PTRACE_SYSCALL, cpid, NULL, (void *)0); + continue; + } + if (w == PTRACE_EVENT_EXEC) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exec event\n", rc); + fflush(stdout); + continue; + } + if (w == PTRACE_EVENT_EXIT) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exit event\n", rc); + fflush(stdout); + continue; + } + if (WSTOPSIG(st) & 0x80) { // syscall + int num; + get_syscall_args(rc, &args); + num = get_syscall_number(&args); +// if (num == __NR_open || +// num == __NR_access || +// num == __NR_stat) +// continue; +// printf("wait(1) rc=%d st=%08x\n", rc, st); +// fflush(stdout); +// if (get_syscall_return(&args) == -ENOSYS) { +// get_syscall(num, name); +// printf("%d: syscall=%s\n", rc, name); +// } +// else { +// get_syscall(num, name); +// printf("%d: syscall=%s rc=%ld\n", rc, name, +// get_syscall_return(&args)); +// } +// fflush(stdout); + } + else { // signal +// printf("wait(1) rc=%d st=%08x\n", rc, st); +// sig = WSTOPSIG(st) & 0x7f; +// printf("%d: sig=%d\n", rc, sig); +// fflush(stdout); + } + } + for (;;) { + int len; + len = read(pipefds[0], &ch, 1); + if (len == 1) { + if (ch == '0') { + ok++; + } + else { + ng++; + } + } + else { + break; + } + } + close(pipefds[0]); + printf("#946 terminated ok=%d ng=%d\n", ok, ng); + fflush(stdout); + exit(0); +} diff --git a/test/strace/issue/960.c b/test/strace/issue/960.c new file mode 100644 index 00000000..846cbbb6 --- /dev/null +++ b/test/strace/issue/960.c @@ -0,0 +1,280 @@ +#define __BSD_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +long +_ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data) +{ + long rc; + + rc = ptrace(request, pid, addr, data); + if (rc == -1) { + printf("ptrace(%d, %d, %016x, %016x): %d\n", request, pid, + (long)addr, (long)data, errno); + exit(1); + } + return rc; +} + +typedef struct user_regs_struct syscall_args; + +static inline int +get_syscall_args(int pid, syscall_args *args) +{ + return _ptrace(PTRACE_GETREGS, pid, NULL, args); +} + +static inline unsigned long +get_syscall_number(syscall_args *args) +{ + return args->orig_rax; +} + +static inline unsigned long +get_syscall_return(syscall_args *args) +{ + return args->rax; +} + +static char *syscalls[512]; + +char * +trim(char *buf) +{ + char *p; + char *q; + + for (p = buf; *p && (isspace(*p)); p++); + if (!*p) + return p; + for (q = strchr(p, '\0') - 1; isspace(*q); q--) + *q = '\0'; + return p; +} + +char ** +split(char *buf, char dlm) +{ + int n; + char *t; + char **r; + char **p; + + for (n = 0, t = buf; *t; t++) + if (*t == dlm) + n++; + p = r = malloc(sizeof(char *) * (n + 2) + strlen(buf) + 1); + t = (char *)(r + n + 2); + strcpy(t, buf); + t = trim(t); + if (*t) { + *(p++) = t; + for (; *t; t++) + if (*t == dlm) { + *(t++) = '\0'; + t = trim(t); + trim(p[-1]); + if (!*t) + break; + *(p++) = t; + } + } + *p = NULL; + return r; +} + +void +init_syscalls() +{ + char buf[1024]; + FILE *f; + + f = fopen("/usr/include/asm/unistd_64.h", "r"); + if (!f) { + perror("open(unistd_64.h)"); + return; + } + while (fgets(buf, 1024, f)) { + char *t; + char **a; + + if (strncmp(buf, "#define", 7)) + continue; + for (t = buf; *t; t++) + if (isspace(*t)) + *t = ' '; + a = split(buf, ' '); + if (a[0] && a[1] && !strncmp(a[1], "__NR_", 5) && + a[2] && *(a[2]) >= '0' && *(a[2]) <= '9') { + int num = atoi(a[2]); + syscalls[num] = strdup(a[1] + 5); + } + free(a); + } + fclose(f); +} + +const char * +get_syscall(int n, char *buf) +{ + if (n < 0 || n >= 512 || !syscalls[n]) { + sprintf(buf, "unknown(%d)", n); + return NULL; + } + return strcpy(buf, syscalls[n]); +} + +int +main(int argc, char **argv) +{ + pid_t pid; + pid_t cpid; + unsigned long msg; + int st; + int rc; + int w; + syscall_args args; + unsigned long sig = 0; + char name[64]; + char ch = ' '; + int ok = 0; + int ng = 0; + int procs = 0; + int c = 0; + + init_syscalls(); + printf("#960 start\n"); + fflush(stdout); + pid = fork(); + if(pid == 0){ + _ptrace(PTRACE_TRACEME, 0, NULL, NULL); + kill(getpid(), SIGINT); + pid = fork(); + if (pid == 0) { + exit(16); + } + rc = wait(&st); + exit(64); + } + rc = waitpid(-1, &st, WUNTRACED); + if (rc != pid || !WIFSTOPPED(st)) { + printf("BAD1 rc=%d st=%08x\n", rc, st); + exit(1); + } + _ptrace(PTRACE_SETOPTIONS, pid, NULL, (void *)(PTRACE_O_TRACESYSGOOD | + PTRACE_O_TRACEFORK | + PTRACE_O_TRACEVFORK | + PTRACE_O_TRACECLONE | + PTRACE_O_TRACEEXEC)); + + rc = pid; + procs = 1; + for (;;) { + if (rc != -1) + _ptrace(PTRACE_SYSCALL, rc, NULL, (void *)sig); + sig = 0; + rc = waitpid(-1, &st, WUNTRACED); + if (WIFEXITED(st) || WIFSIGNALED(st)) { + procs--; + if (rc == pid) + pid = -1; + else if (rc == cpid) + cpid = -1; + rc = -1; + if (!procs) { + break; + } + continue; + } + if (!WIFSTOPPED(st)) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("unrecognized status rc=%d st=%08x\n", rc, st); + fflush(stdout); + continue; + } + if ((w = (st >> 16) & 255) == PTRACE_EVENT_FORK || + w == PTRACE_EVENT_VFORK || + w == PTRACE_EVENT_CLONE || + w == PTRACE_EVENT_VFORK_DONE) { + int crc; + _ptrace(PTRACE_GETEVENTMSG, pid, NULL, &msg); + cpid = msg; + crc = waitpid(-1, &st, WUNTRACED); + if (crc != cpid || !WIFSTOPPED(st)) { + printf("BAD4 rc=%d st=%08x\n", crc, st); + exit(1); + } + procs++; + _ptrace(PTRACE_SYSCALL, cpid, NULL, (void *)0); + continue; + } + if (w == PTRACE_EVENT_EXEC) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exec event\n", rc); + fflush(stdout); + continue; + } + if (w == PTRACE_EVENT_EXIT) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exit event\n", rc); + fflush(stdout); + continue; + } + if (WSTOPSIG(st) & 0x80) { // syscall + int num; + long ret; + get_syscall_args(rc, &args); + num = get_syscall_number(&args); + ret = get_syscall_return(&args); + if (num == SYS_wait4 && + ret == -ENOSYS) { + c++; + printf("#960-1 wait in OK\n"); + ok++; + } + else if (num == SYS_wait4 && + ret != -ENOSYS) { + c++; + if (c == 2) { + printf("#960-2 wait out OK\n"); + ok++; + } + else { + printf("#960-2 wait out NG\n"); + ng++; + } + } + } + else { // signal + sig = WSTOPSIG(st) & 0x7f; + if (sig == SIGCHLD) { + c++; + if (c == 3) { + printf("#960-3 SIGCHLD OK\n"); + ok++; + } + else { + printf("#960-3 SIGCHLD NG\n"); + ng++; + } + } + else { + printf("%d: sig=%d\n", rc, sig); + fflush(stdout); + ng++; + } + } + } + + printf("#960 terminated ok=%d ng=%d\n", ok, ng); + fflush(stdout); + exit(0); +} diff --git a/test/strace/issue/961.c b/test/strace/issue/961.c new file mode 100644 index 00000000..df89325d --- /dev/null +++ b/test/strace/issue/961.c @@ -0,0 +1,450 @@ +#define __BSD_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +long +_ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data) +{ + long rc; + + rc = ptrace(request, pid, addr, data); + if (rc == -1) { + printf("ptrace(%d, %d, %016x, %016x): %d\n", request, pid, + (long)addr, (long)data, errno); + exit(1); + } + return rc; +} + +typedef struct user_regs_struct syscall_args; + +static inline int +get_syscall_args(int pid, syscall_args *args) +{ + return _ptrace(PTRACE_GETREGS, pid, NULL, args); +} + +static inline unsigned long +get_syscall_number(syscall_args *args) +{ + return args->orig_rax; +} + +static inline unsigned long +get_syscall_return(syscall_args *args) +{ + return args->rax; +} + +static char *syscalls[512]; + +char * +trim(char *buf) +{ + char *p; + char *q; + + for (p = buf; *p && (isspace(*p)); p++); + if (!*p) + return p; + for (q = strchr(p, '\0') - 1; isspace(*q); q--) + *q = '\0'; + return p; +} + +char ** +split(char *buf, char dlm) +{ + int n; + char *t; + char **r; + char **p; + + for (n = 0, t = buf; *t; t++) + if (*t == dlm) + n++; + p = r = malloc(sizeof(char *) * (n + 2) + strlen(buf) + 1); + t = (char *)(r + n + 2); + strcpy(t, buf); + t = trim(t); + if (*t) { + *(p++) = t; + for (; *t; t++) + if (*t == dlm) { + *(t++) = '\0'; + t = trim(t); + trim(p[-1]); + if (!*t) + break; + *(p++) = t; + } + } + *p = NULL; + return r; +} + +void +init_syscalls() +{ + char buf[1024]; + FILE *f; + + f = fopen("/usr/include/asm/unistd_64.h", "r"); + if (!f) { + perror("open(unistd_64.h)"); + return; + } + while (fgets(buf, 1024, f)) { + char *t; + char **a; + + if (strncmp(buf, "#define", 7)) + continue; + for (t = buf; *t; t++) + if (isspace(*t)) + *t = ' '; + a = split(buf, ' '); + if (a[0] && a[1] && !strncmp(a[1], "__NR_", 5) && + a[2] && *(a[2]) >= '0' && *(a[2]) <= '9') { + int num = atoi(a[2]); + syscalls[num] = strdup(a[1] + 5); + } + free(a); + } + fclose(f); +} + +const char * +get_syscall(int n, char *buf) +{ + if (n < 0 || n >= 512 || !syscalls[n]) { + sprintf(buf, "unknown(%d)", n); + return NULL; + } + return strcpy(buf, syscalls[n]); +} + +int +main(int argc, char **argv) +{ + pid_t pid; + pid_t cpid; + unsigned long msg; + int st; + int rc; + long ret; + int w; + syscall_args args; + unsigned long sig = 0; + char name[64]; + int c = 0; + int ok = 0; + int ng = 0; + int procs = 0; + int forkev = 0; + int childfork = 0; + + printf("#961 test start\n"); + init_syscalls(); + +// printf("tracer pid=%d\n", getpid()); +// fflush(stdout); + pid = fork(); + if(pid == 0){ + if (_ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) { + printf("ptrace error %d\n", errno); + } + kill(getpid(), SIGINT); + + cpid = fork(); + if (cpid == 0) { + exit(1); + } + wait(&st); + exit(15); + } + rc = waitpid(-1, &st, WUNTRACED); + if (rc != pid || !WIFSTOPPED(st)) { + printf("BAD1 rc=%d st=%08x\n", rc, st); + exit(1); + } + _ptrace(PTRACE_SETOPTIONS, pid, NULL, (void *)(PTRACE_O_TRACESYSGOOD | + PTRACE_O_TRACEFORK | + PTRACE_O_TRACEVFORK | + PTRACE_O_TRACECLONE | + PTRACE_O_TRACEEXEC)); + + rc = pid; + procs = 1; + for (;;) { + if (rc != -1) + _ptrace(PTRACE_SYSCALL, rc, NULL, (void *)sig); + sig = 0; + rc = waitpid(-1, &st, WUNTRACED); + if (rc == -1) { + printf("wait error %d\n", errno); + exit(1); + } + if (WIFEXITED(st)) { +// printf("terminate %d st=%08x\n", rc, st); + procs--; + if (procs == 0) + break; + rc = -1; + continue; + } + if (WIFSIGNALED(st)) { + printf("tracee BAD signaled %08x\n", st); + ng++; + break; + } + if (!WIFSTOPPED(st)) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("unrecognized status rc=%d st=%08x\n", rc, st); + fflush(stdout); + continue; + } + if ((w = (st >> 16) & 255) == PTRACE_EVENT_FORK || + w == PTRACE_EVENT_VFORK || + w == PTRACE_EVENT_CLONE || + w == PTRACE_EVENT_VFORK_DONE) { + int crc; +// printf("wait(1) rc=%d st=%08x\n", rc, st); +// printf("%d: fork exent ev=%d\n", rc, w); +// fflush(stdout); + _ptrace(PTRACE_GETEVENTMSG, pid, NULL, &msg); + cpid = msg; +// printf("child pid=%d\n", cpid); +// fflush(stdout); + crc = waitpid(-1, &st, WUNTRACED); + if (crc != cpid || !WIFSTOPPED(st)) { + printf("BAD4 rc=%d st=%08x\n", crc, st); + exit(1); + } +// printf("wait(2) rc=%d st=%08x\n", crc, st); +// fflush(stdout); + printf("#961-2 PTRACE_EVENT_FORK OK\n"); + ok++; + forkev = 1; + procs++; + _ptrace(PTRACE_SYSCALL, cpid, NULL, (void *)0); + continue; + } + if (w == PTRACE_EVENT_EXEC) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exec event\n", rc); + fflush(stdout); + continue; + } + if (w == PTRACE_EVENT_EXIT) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exit event\n", rc); + fflush(stdout); + continue; + } + if (WSTOPSIG(st) & 0x80) { // syscall + int num; + get_syscall_args(rc, &args); + num = get_syscall_number(&args); + ret = get_syscall_return(&args); + if (num == SYS_clone) { + c++; + if (ret == -ENOSYS) { + ok++; + printf("#961-1 fork in OK\n"); + } + else if (ret == 0) { + childfork = 1; + ng++; + printf("#961-4 fork child side called NG\n"); + } + else { + printf("#961-3 fork out OK\n"); + ok++; + } + } + } + else { // signal +// printf("wait(1) rc=%d st=%08x\n", rc, st); + sig = WSTOPSIG(st) & 0x7f; + if (sig == SIGCHLD) { + printf("#961-5 tracee receive SIGCHLD OK\n"); + fflush(stdout); + ok++; + } + else if (sig == SIGSTOP) { +// printf("#961-6 tracee receive SIGSTOP OK %d\n", rc); +// fflush(stdout); +// ok++; + } + else { + ng++; + printf("tracee receive signal %d\n", sig); + fflush(stdout); + } + } + } + if (!childfork) { + ok++; + printf("#961-4 fork child side didnot be called OK\n"); + } + if (!forkev) { + ng++; + printf("#961-2 didnot receive PTRACE_EVENT_FORK NG\n"); + } + + pid = fork(); + if(pid == 0){ + if (_ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) { + printf("ptrace error %d\n", errno); + } + kill(getpid(), SIGINT); + + cpid = fork(); + if (cpid == 0) { + exit(1); + } + wait(&st); + exit(15); + } + rc = waitpid(-1, &st, WUNTRACED); + if (rc != pid || !WIFSTOPPED(st)) { + printf("BAD1 rc=%d st=%08x\n", rc, st); + exit(1); + } + _ptrace(PTRACE_SETOPTIONS, pid, NULL, (void *)(PTRACE_O_TRACESYSGOOD | + PTRACE_O_TRACEEXEC)); + + rc = pid; + forkev = 0; + childfork = 0; + procs = 1; + for (;;) { + if (rc != -1) + _ptrace(PTRACE_SYSCALL, rc, NULL, (void *)sig); + sig = 0; + rc = waitpid(-1, &st, WUNTRACED); + if (rc == -1) { + printf("wait error %d\n", errno); + exit(1); + } + if (WIFEXITED(st)) { +// printf("terminate %d st=%08x\n", rc, st); + procs--; + if (procs == 0) + break; + rc = -1; + continue; + } + if (WIFSIGNALED(st)) { + printf("tracee BAD signaled %08x\n", st); + ng++; + break; + } + if (!WIFSTOPPED(st)) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("unrecognized status rc=%d st=%08x\n", rc, st); + fflush(stdout); + continue; + } + if ((w = (st >> 16) & 255) == PTRACE_EVENT_FORK || + w == PTRACE_EVENT_VFORK || + w == PTRACE_EVENT_CLONE || + w == PTRACE_EVENT_VFORK_DONE) { + int crc; +// printf("wait(1) rc=%d st=%08x\n", rc, st); +// printf("%d: fork exent ev=%d\n", rc, w); +// fflush(stdout); + _ptrace(PTRACE_GETEVENTMSG, pid, NULL, &msg); + cpid = msg; +// printf("child pid=%d\n", cpid); +// fflush(stdout); + crc = waitpid(-1, &st, WUNTRACED); + if (crc != cpid || !WIFSTOPPED(st)) { + printf("BAD4 rc=%d st=%08x\n", crc, st); + exit(1); + } +// printf("wait(2) rc=%d st=%08x\n", crc, st); +// fflush(stdout); + printf("#961-7 PTRACE_EVENT_FORK NG\n"); + ng++; + forkev = 1; + procs++; + _ptrace(PTRACE_SYSCALL, cpid, NULL, (void *)0); + continue; + } + if (w == PTRACE_EVENT_EXEC) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exec event\n", rc); + fflush(stdout); + continue; + } + if (w == PTRACE_EVENT_EXIT) { + printf("wait(1) rc=%d st=%08x\n", rc, st); + printf("%d: exit event\n", rc); + fflush(stdout); + continue; + } + if (WSTOPSIG(st) & 0x80) { // syscall + int num; + get_syscall_args(rc, &args); + num = get_syscall_number(&args); + ret = get_syscall_return(&args); + if (num == SYS_clone) { + c++; + if (ret == -ENOSYS) { + ok++; + printf("#961-6 fork in OK\n"); + } + else if (ret == 0) { + childfork = 1; + ng++; + printf("#961-9 fork child side called NG\n"); + } + else { + printf("#961-8 fork out OK\n"); + ok++; + } + } + } + else { // signal +// printf("wait(1) rc=%d st=%08x\n", rc, st); + sig = WSTOPSIG(st) & 0x7f; + if (sig == SIGCHLD) { + printf("#961-10 tracee receive SIGCHLD OK %d\n", rc); + fflush(stdout); + ok++; + } + else if (sig == SIGSTOP) { +// printf("#961-6 tracee receive SIGSTOP OK %d\n", rc); +// fflush(stdout); +// ok++; + } + else { + ng++; + printf("$961-10 tracee receive signal %d\n", sig); + fflush(stdout); + } + } + } + if (!childfork) { + ok++; + printf("#961-9 fork child side didnot be called OK\n"); + } + if (!forkev) { + ok++; + printf("#961-7 didnot receive PTRACE_EVENT_FORK OK\n"); + } + printf("#961 test terminated ok=%d ng=%d\n", ok, ng); + fflush(stdout); + exit(0); +} diff --git a/test/strace/issue/Makefile b/test/strace/issue/Makefile new file mode 100644 index 00000000..ff90e743 --- /dev/null +++ b/test/strace/issue/Makefile @@ -0,0 +1,33 @@ +CC=gcc +MCEXEC=../../../../mic/mcexec +TARGET=943 944 945 946 960 961 +all:: $(TARGET) + +943: 943.c + $(CC) -o 943 $< + +944: 944.c + $(CC) -o 944 $< + +945: 945.c + $(CC) -o 945 $< + +946: 946.c + $(CC) -o 946 $< + +960: 960.c + $(CC) -o 960 $< + +961: 961.c + $(CC) -o 961 $< + +test:: $(TARGET) + -$(MCEXEC) ./943 + -$(MCEXEC) ./944 + -$(MCEXEC) ./945 + -$(MCEXEC) ./946 + -$(MCEXEC) ./960 + -$(MCEXEC) ./961 + +clean:: + rm -f $(TARGET) diff --git a/test/strace/issue/result.txt b/test/strace/issue/result.txt new file mode 100644 index 00000000..bcd3ab49 --- /dev/null +++ b/test/strace/issue/result.txt @@ -0,0 +1,55 @@ +../../../../mic/mcexec ./943 +#943 test start +#943 test start +#943-1 gettid in OK +#943-2 gettid out OK +#943-3 open in OK +#943-4 open out OK +#943-5 bad syscall in OK +#943-6 bad syscall out OK +#943 test terminated ok=6 ng=0 +../../../../mic/mcexec ./944 +#944 test start +#944 test start +#944-1 gettid in OK +#944-2 gettid out OK +#944-3 open in OK +#944-4 open out OK +#944-5 bad syscall in OK +#944-6 bad syscall out OK +#944 test terminated ok=6 ng=0 +../../../../mic/mcexec ./945 +#945 start +#945-1 execve in OK +#945-3 execve out OK +#945-2 PTRACE_EVENT_EXEC OK +#945 test terminated ok=3 ng=0 +../../../../mic/mcexec ./946 +#946 start +#946-1 exit after wait OK +#946-1 exit after wait OK +#946-2 exit before wait OK +#946 terminated ok=2 ng=0 +../../../../mic/mcexec ./960 +#960 start +#960-1 wait in OK +#960-2 wait out OK +#960-3 SIGCHLD OK +#960 terminated ok=3 ng=0 +../../../../mic/mcexec ./961 +#961 test start +#961 test start +#961-1 fork in OK +#961-2 PTRACE_EVENT_FORK OK +#961-3 fork out OK +#961-5 tracee receive SIGCHLD OK +#961 test start +#961-4 fork child side didnot be called OK +#961-4 fork child side didnot be called OK +#961-6 fork in OK +#961-8 fork out OK +#961-10 tracee receive SIGCHLD OK 27454 +#961-4 fork child side didnot be called OK +#961-9 fork child side didnot be called OK +#961-7 didnot receive PTRACE_EVENT_FORK OK +#961 test terminated ok=10 ng=0 diff --git a/test/strace/strace-bundle/ptrace_setoptions b/test/strace/strace-bundle/ptrace_setoptions index cf51deac..a0491db3 100755 --- a/test/strace/strace-bundle/ptrace_setoptions +++ b/test/strace/strace-bundle/ptrace_setoptions @@ -18,11 +18,14 @@ check_timeout $TIMEOUT $MCEXEC $STRACE -df -enone / 2>&1 | grep -F -x 'ptrace_setoptions = 0xe' > /dev/null || fail_ 'strace -f failed to recognize proper kernel PTRACE_O_TRACECLONE support' +echo ptrace_setoptions-1 OK $TIMEOUT $MCEXEC $STRACE -df -enone / 2>&1 | grep -F -x 'ptrace_setoptions = 0x1f' > /dev/null || fail_ 'strace -f failed to recognize proper kernel PTRACE_O_TRACESYSGOOD support' +echo ptrace_setoptions-2 OK $TIMEOUT $MCEXEC $STRACE -d -enone / 2>&1 | grep -F -x 'ptrace_setoptions = 0x11' > /dev/null || fail_ 'strace failed to recognize proper kernel PTRACE_O_TRACESYSGOOD support' +echo ptrace_setoptions-3 OK diff --git a/test/strace/strace-bundle/qual_syscall b/test/strace/strace-bundle/qual_syscall index 6f93fee7..c7a2eafa 100755 --- a/test/strace/strace-bundle/qual_syscall +++ b/test/strace/strace-bundle/qual_syscall @@ -12,16 +12,20 @@ check_prog grep $TIMEOUT $MCEXEC $STRACE -e execve ls > /dev/null 2> check.log && grep '^execve(' check.log > /dev/null || { cat check.log; fail_ 'strace -e execve does not work'; } +echo qual_syscall-1 OK grep -v '^execve(' check.log | LC_ALL=C grep '^[[:alnum:]_]*(' > /dev/null && { cat check.log; fail_ 'strace -e execve does not work properly'; } +echo qual_syscall-2 OK $TIMEOUT $MCEXEC $STRACE -e trace=process ls > /dev/null 2> check.log && grep '^execve(' check.log > /dev/null || { cat check.log; fail_ 'strace -e trace=process does not work'; } +echo qual_syscall-3 OK grep '^open' check.log > /dev/null && { cat check.log; fail_ 'strace -e trace=process does not work properly'; } +echo qual_syscall-4 OK exit 0 diff --git a/test/strace/strace-bundle/result.txt b/test/strace/strace-bundle/result.txt new file mode 100644 index 00000000..c881868d --- /dev/null +++ b/test/strace/strace-bundle/result.txt @@ -0,0 +1,20 @@ +*** ptrace_setoptions start +ptrace_setoptions-1 OK +ptrace_setoptions-2 OK +ptrace_setoptions-3 OK +*** ptrace_setoptions OK +*** qual_syscall start +qual_syscall-1 OK +qual_syscall-2 OK +qual_syscall-3 OK +qual_syscall-4 OK +*** qual_syscall OK +*** stat start +stat-1 OK +stat-2 OK +stat-3 OK +stat-4 OK +*** stat OK +*** strace-f start +strace-f-1 OK +*** strace-f OK diff --git a/test/strace/strace-bundle/stat b/test/strace/strace-bundle/stat index 34bec48a..111d5f23 100755 --- a/test/strace/strace-bundle/stat +++ b/test/strace/strace-bundle/stat @@ -20,17 +20,21 @@ rm -f sample $TIMEOUT $MCEXEC $STRACE -edesc $truncate_cmd 2>&1 > /dev/null 2> check.log && LC_ALL=C grep -E -x 'ftruncate(64)?\(1, 46118400000\) += 0' check.log > /dev/null || { cat check.log; fail_ 'strace -edesc failed to trace ftruncate/ftruncate64 properly'; } +echo stat-1 OK LC_ALL=C grep -E -x 'lseek\(1, 46118400000, SEEK_CUR\) += 46118400000|_llseek\(1, 46118400000, \[46118400000\], SEEK_CUR\) += 0' check.log > /dev/null || { cat check.log; fail_ 'strace -edesc failed to trace lseek/_llseek properly'; } +echo stat-2 OK $TIMEOUT $MCEXEC $STRACE -efile find -L sample > /dev/null 2> check.log && LC_ALL=C grep -E -x 'stat(64)?\("sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}\) += 0|(new)?fstatat(64)?\(AT_FDCWD, "sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}, 0\) += 0' check.log > /dev/null || { cat check.log; fail_ 'strace -efile failed to trace stat/stat64 properly'; } +echo stat-3 OK $TIMEOUT $MCEXEC $STRACE -efile find sample > /dev/null 2> check.log && LC_ALL=C grep -E -x 'lstat(64)?\("sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}\) += 0|(new)?fstatat(64)?\(AT_FDCWD, "sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}, AT_SYMLINK_NOFOLLOW\) += 0' check.log > /dev/null || { cat check.log; fail_ 'strace -efile failed to trace fstatat/fstatat64 properly'; } +echo stat-4 OK rm -f sample diff --git a/test/strace/strace-bundle/strace-f b/test/strace/strace-bundle/strace-f index cc6a7dda..06324591 100755 --- a/test/strace/strace-bundle/strace-f +++ b/test/strace/strace-bundle/strace-f @@ -11,3 +11,4 @@ check_prog $time $TIMEOUT $MCEXEC $STRACE -f $time /bin/ls > check.log 2>&1 || { cat check.log; fail_ 'strace -f does not work'; } +echo strace-f-1 OK diff --git a/test/strace/strace-bundle/test-result.txt b/test/strace/strace-bundle/test-result.txt deleted file mode 100644 index d6a4dbbf..00000000 --- a/test/strace/strace-bundle/test-result.txt +++ /dev/null @@ -1,216 +0,0 @@ -スクリプトは Mon Nov 20 13:34:02 2017 - に開始しました[?1034hbash-4.2$ export MCEXEC=$HOME/wallaby11-smp-x86/development/mic/mcexec -bash-4.2$ cat ptrace_setoptions -#!/bin/sh - -# Ensure that strace tests kernel PTRACE_O_TRACECLONE -# and PTRACE_O_TRACESYSGOOD support properly. - -. "${srcdir=.}/init.sh" - -[ "$(uname -s)" = Linux ] || - skip_ 'The kernel is not a Linux kernel' -case "$(uname -r)" in - 2.[6-9]*|2.[1-5][0-9]*|[3-9].*|[12][0-9]*) ;; - *) skip_ 'The kernel is not Linux 2.6.* or newer' ;; -esac - -check_strace -check_timeout - -$TIMEOUT $MCEXEC $STRACE -df -enone / 2>&1 | - grep -F -x 'ptrace_setoptions = 0xe' > /dev/null || - fail_ 'strace -f failed to recognize proper kernel PTRACE_O_TRACECLONE support' - -$TIMEOUT $MCEXEC $STRACE -df -enone / 2>&1 | - grep -F -x 'ptrace_setoptions = 0x1f' > /dev/null || - fail_ 'strace -f failed to recognize proper kernel PTRACE_O_TRACESYSGOOD support' - -$TIMEOUT $MCEXEC $STRACE -d -enone / 2>&1 | - grep -F -x 'ptrace_setoptions = 0x11' > /dev/null || - fail_ 'strace failed to recognize proper kernel PTRACE_O_TRACESYSGOOD support' -bash-4.2$ sh -x ptrace_setoptions -+ . ./init.sh -++ ME_=ptrace_setoptions -++ timeout_duration=60 -++ uname -s -+ '[' Linux = Linux ']' -+ case "$(uname -r)" in -++ uname -r -+ check_strace -+ STRACE=../strace -+ ../strace -V -+ check_timeout -+ TIMEOUT='timeout -s 9 60' -+ timeout -s 9 60 true -+ timeout -s 9 60 /home/shirasawa/wallaby11-smp-x86/development/mic/mcexec ../strace -df -enone / -+ grep -F -x 'ptrace_setoptions = 0xe' -+ timeout -s 9 60 /home/shirasawa/wallaby11-smp-x86/development/mic/mcexec ../strace -df -enone / -+ grep -F -x 'ptrace_setoptions = 0x1f' -+ timeout -s 9 60 /home/shirasawa/wallaby11-smp-x86/development/mic/mcexec ../strace -d -enone / -+ grep -F -x 'ptrace_setoptions = 0x11' -bash-4.2$ echo $? -0 -bash-4.2$ cat strace-f -#!/bin/sh - -# Ensure that strace -f works. - -. "${srcdir=.}/init.sh" - -check_strace -check_timeout -time=/usr/bin/time -check_prog $time - -$TIMEOUT $MCEXEC $STRACE -f $time /bin/ls > check.log 2>&1 || - { cat check.log; fail_ 'strace -f does not work'; } -bash-4.2$ sh -x strace-f -+ . ./init.sh -++ ME_=strace-f -++ timeout_duration=60 -+ check_strace -+ STRACE=../strace -+ ../strace -V -+ check_timeout -+ TIMEOUT='timeout -s 9 60' -+ timeout -s 9 60 true -+ time=/usr/bin/time -+ check_prog /usr/bin/time -+ type /usr/bin/time -+ timeout -s 9 60 /home/shirasawa/wallaby11-smp-x86/development/mic/mcexec ../strace -f /usr/bin/time /bin/ls -bash-4.2$ echo ?$? -0 -bash-4.2$ cat qual_syscall -#!/bin/sh - -# Ensure that strace -e trace=set works. - -. "${srcdir=.}/init.sh" - -check_strace -check_timeout -check_prog ls -check_prog grep - -$TIMEOUT $MCEXEC $STRACE -e execve ls > /dev/null 2> check.log && -grep '^execve(' check.log > /dev/null || - { cat check.log; fail_ 'strace -e execve does not work'; } - -grep -v '^execve(' check.log | -LC_ALL=C grep '^[[:alnum:]_]*(' > /dev/null && - { cat check.log; fail_ 'strace -e execve does not work properly'; } - -$TIMEOUT $MCEXEC $STRACE -e trace=process ls > /dev/null 2> check.log && -grep '^execve(' check.log > /dev/null || - { cat check.log; fail_ 'strace -e trace=process does not work'; } - -grep '^open' check.log > /dev/null && - { cat check.log; fail_ 'strace -e trace=process does not work properly'; } - -exit 0 -bash-4.2$ sh -x qual_syscall -+ . ./init.sh -++ ME_=qual_syscall -++ timeout_duration=60 -+ check_strace -+ STRACE=../strace -+ ../strace -V -+ check_timeout -+ TIMEOUT='timeout -s 9 60' -+ timeout -s 9 60 true -+ check_prog ls -+ type ls -+ check_prog grep -+ type grep -+ timeout -s 9 60 /home/shirasawa/wallaby11-smp-x86/development/mic/mcexec ../strace -e execve ls -+ grep '^execve(' check.log -+ grep -v '^execve(' check.log -+ LC_ALL=C -+ grep '^[[:alnum:]_]*(' -+ timeout -s 9 60 /home/shirasawa/wallaby11-smp-x86/development/mic/mcexec ../strace -e trace=process ls -+ grep '^execve(' check.log -+ grep '^open' check.log -+ exit 0 -bash-4.2$ echo $? -0 -bash-4.2$ cat stat -#!/bin/sh - -# Check how ftruncate, lseek and stat family syscalls are traced. - -. "${srcdir=.}/init.sh" - -check_strace -check_timeout -check_prog dd -check_prog find -check_prog grep -check_prog rm - -umask 022 -truncate_cmd='dd seek=46118400000 obs=1 count=0 if=/dev/null of=sample' -$truncate_cmd > check.log 2>&1 || - { cat check.log; framework_skip_ 'failed to create a large sparse file'; } -rm -f sample - -$TIMEOUT $MCEXEC $STRACE -edesc $truncate_cmd 2>&1 > /dev/null 2> check.log && -LC_ALL=C grep -E -x 'ftruncate(64)?\(1, 46118400000\) += 0' check.log > /dev/null || - { cat check.log; fail_ 'strace -edesc failed to trace ftruncate/ftruncate64 properly'; } - -LC_ALL=C grep -E -x 'lseek\(1, 46118400000, SEEK_CUR\) += 46118400000|_llseek\(1, 46118400000, \[46118400000\], SEEK_CUR\) += 0' check.log > /dev/null || - { cat check.log; fail_ 'strace -edesc failed to trace lseek/_llseek properly'; } - -$TIMEOUT $MCEXEC $STRACE -efile find -L sample > /dev/null 2> check.log && -LC_ALL=C grep -E -x 'stat(64)?\("sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}\) += 0|(new)?fstatat(64)?\(AT_FDCWD, "sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}, 0\) += 0' check.log > /dev/null || - { cat check.log; fail_ 'strace -efile failed to trace stat/stat64 properly'; } - -$TIMEOUT $MCEXEC $STRACE -efile find sample > /dev/null 2> check.log && -LC_ALL=C grep -E -x 'lstat(64)?\("sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}\) += 0|(new)?fstatat(64)?\(AT_FDCWD, "sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}, AT_SYMLINK_NOFOLLOW\) += 0' check.log > /dev/null || - { cat check.log; fail_ 'strace -efile failed to trace fstatat/fstatat64 properly'; } - -rm -f sample - -exit 0 -bash-4.2$ sh -x stat -+ . ./init.sh -++ ME_=stat -++ timeout_duration=60 -+ check_strace -+ STRACE=../strace -+ ../strace -V -+ check_timeout -+ TIMEOUT='timeout -s 9 60' -+ timeout -s 9 60 true -+ check_prog dd -+ type dd -+ check_prog find -+ type find -+ check_prog grep -+ type grep -+ check_prog rm -+ type rm -+ umask 022 -+ truncate_cmd='dd seek=46118400000 obs=1 count=0 if=/dev/null of=sample' -+ dd seek=46118400000 obs=1 count=0 if=/dev/null of=sample -+ rm -f sample -+ timeout -s 9 60 /home/shirasawa/wallaby11-smp-x86/development/mic/mcexec ../strace -edesc dd seek=46118400000 obs=1 count=0 if=/dev/null of=sample -+ LC_ALL=C -+ grep -E -x 'ftruncate(64)?\(1, 46118400000\) += 0' check.log -+ LC_ALL=C -+ grep -E -x 'lseek\(1, 46118400000, SEEK_CUR\) += 46118400000|_llseek\(1, 46118400000, \[46118400000\], SEEK_CUR\) += 0' check.log -+ timeout -s 9 60 /home/shirasawa/wallaby11-smp-x86/development/mic/mcexec ../strace -efile find -L sample -+ LC_ALL=C -+ grep -E -x 'stat(64)?\("sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}\) += 0|(new)?fstatat(64)?\(AT_FDCWD, "sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}, 0\) += 0' check.log -+ timeout -s 9 60 /home/shirasawa/wallaby11-smp-x86/development/mic/mcexec ../strace -efile find sample -+ LC_ALL=C -+ grep -E -x 'lstat(64)?\("sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}\) += 0|(new)?fstatat(64)?\(AT_FDCWD, "sample", \{st_mode=S_IFREG\|0644, st_size=46118400000, \.\.\.\}, AT_SYMLINK_NOFOLLOW\) += 0' check.log -+ rm -f sample -+ exit 0 -bash-4.2$ echo $? -0 -bash-4.2$ シェルから脱出するには "exit" を使用してください。 -bash-4.2$ exit - -スクリプトは Mon Nov 20 13:36:26 2017 - に終了しました \ No newline at end of file diff --git a/test/strace/strace-bundle/test.sh b/test/strace/strace-bundle/test.sh new file mode 100755 index 00000000..959bb839 --- /dev/null +++ b/test/strace/strace-bundle/test.sh @@ -0,0 +1,30 @@ +#!/bin/sh +export MCEXEC=../../../../mic/mcexec +echo '*** ptrace_setoptions start' +./ptrace_setoptions +if [ $? = 0 ]; then + echo '*** ptrace_setoptions OK' +else + echo '*** ptrace_setoptions NG' +fi +echo '*** qual_syscall start' +./qual_syscall +if [ $? = 0 ]; then + echo '*** qual_syscall OK' +else + echo '*** qual_syscall NG' +fi +echo '*** stat start' +./stat +if [ $? = 0 ]; then + echo '*** stat OK' +else + echo '*** stat NG' +fi +echo '*** strace-f start' +./strace-f +if [ $? = 0 ]; then + echo '*** strace-f OK' +else + echo '*** strace-f NG' +fi