add test programs for strace
This commit is contained in:
343
test/strace/issue/943.c
Normal file
343
test/strace/issue/943.c
Normal file
@@ -0,0 +1,343 @@
|
|||||||
|
#define __BSD_SOURCE
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
343
test/strace/issue/944.c
Executable file
343
test/strace/issue/944.c
Executable file
@@ -0,0 +1,343 @@
|
|||||||
|
#define __BSD_SOURCE
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
278
test/strace/issue/945.c
Normal file
278
test/strace/issue/945.c
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
#define __BSD_SOURCE
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
320
test/strace/issue/946.c
Normal file
320
test/strace/issue/946.c
Normal file
@@ -0,0 +1,320 @@
|
|||||||
|
#define __BSD_SOURCE
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
280
test/strace/issue/960.c
Normal file
280
test/strace/issue/960.c
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
#define __BSD_SOURCE
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
450
test/strace/issue/961.c
Normal file
450
test/strace/issue/961.c
Normal file
@@ -0,0 +1,450 @@
|
|||||||
|
#define __BSD_SOURCE
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/ptrace.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
33
test/strace/issue/Makefile
Normal file
33
test/strace/issue/Makefile
Normal file
@@ -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)
|
||||||
55
test/strace/issue/result.txt
Normal file
55
test/strace/issue/result.txt
Normal file
@@ -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
|
||||||
@@ -18,11 +18,14 @@ check_timeout
|
|||||||
$TIMEOUT $MCEXEC $STRACE -df -enone / 2>&1 |
|
$TIMEOUT $MCEXEC $STRACE -df -enone / 2>&1 |
|
||||||
grep -F -x 'ptrace_setoptions = 0xe' > /dev/null ||
|
grep -F -x 'ptrace_setoptions = 0xe' > /dev/null ||
|
||||||
fail_ 'strace -f failed to recognize proper kernel PTRACE_O_TRACECLONE support'
|
fail_ 'strace -f failed to recognize proper kernel PTRACE_O_TRACECLONE support'
|
||||||
|
echo ptrace_setoptions-1 OK
|
||||||
|
|
||||||
$TIMEOUT $MCEXEC $STRACE -df -enone / 2>&1 |
|
$TIMEOUT $MCEXEC $STRACE -df -enone / 2>&1 |
|
||||||
grep -F -x 'ptrace_setoptions = 0x1f' > /dev/null ||
|
grep -F -x 'ptrace_setoptions = 0x1f' > /dev/null ||
|
||||||
fail_ 'strace -f failed to recognize proper kernel PTRACE_O_TRACESYSGOOD support'
|
fail_ 'strace -f failed to recognize proper kernel PTRACE_O_TRACESYSGOOD support'
|
||||||
|
echo ptrace_setoptions-2 OK
|
||||||
|
|
||||||
$TIMEOUT $MCEXEC $STRACE -d -enone / 2>&1 |
|
$TIMEOUT $MCEXEC $STRACE -d -enone / 2>&1 |
|
||||||
grep -F -x 'ptrace_setoptions = 0x11' > /dev/null ||
|
grep -F -x 'ptrace_setoptions = 0x11' > /dev/null ||
|
||||||
fail_ 'strace failed to recognize proper kernel PTRACE_O_TRACESYSGOOD support'
|
fail_ 'strace failed to recognize proper kernel PTRACE_O_TRACESYSGOOD support'
|
||||||
|
echo ptrace_setoptions-3 OK
|
||||||
|
|||||||
@@ -12,16 +12,20 @@ check_prog grep
|
|||||||
$TIMEOUT $MCEXEC $STRACE -e execve ls > /dev/null 2> check.log &&
|
$TIMEOUT $MCEXEC $STRACE -e execve ls > /dev/null 2> check.log &&
|
||||||
grep '^execve(' check.log > /dev/null ||
|
grep '^execve(' check.log > /dev/null ||
|
||||||
{ cat check.log; fail_ 'strace -e execve does not work'; }
|
{ cat check.log; fail_ 'strace -e execve does not work'; }
|
||||||
|
echo qual_syscall-1 OK
|
||||||
|
|
||||||
grep -v '^execve(' check.log |
|
grep -v '^execve(' check.log |
|
||||||
LC_ALL=C grep '^[[:alnum:]_]*(' > /dev/null &&
|
LC_ALL=C grep '^[[:alnum:]_]*(' > /dev/null &&
|
||||||
{ cat check.log; fail_ 'strace -e execve does not work properly'; }
|
{ 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 &&
|
$TIMEOUT $MCEXEC $STRACE -e trace=process ls > /dev/null 2> check.log &&
|
||||||
grep '^execve(' check.log > /dev/null ||
|
grep '^execve(' check.log > /dev/null ||
|
||||||
{ cat check.log; fail_ 'strace -e trace=process does not work'; }
|
{ cat check.log; fail_ 'strace -e trace=process does not work'; }
|
||||||
|
echo qual_syscall-3 OK
|
||||||
|
|
||||||
grep '^open' check.log > /dev/null &&
|
grep '^open' check.log > /dev/null &&
|
||||||
{ cat check.log; fail_ 'strace -e trace=process does not work properly'; }
|
{ cat check.log; fail_ 'strace -e trace=process does not work properly'; }
|
||||||
|
echo qual_syscall-4 OK
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
20
test/strace/strace-bundle/result.txt
Normal file
20
test/strace/strace-bundle/result.txt
Normal file
@@ -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
|
||||||
@@ -20,17 +20,21 @@ rm -f sample
|
|||||||
$TIMEOUT $MCEXEC $STRACE -edesc $truncate_cmd 2>&1 > /dev/null 2> check.log &&
|
$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 ||
|
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'; }
|
{ 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 ||
|
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'; }
|
{ 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 &&
|
$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 ||
|
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'; }
|
{ 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 &&
|
$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 ||
|
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'; }
|
{ cat check.log; fail_ 'strace -efile failed to trace fstatat/fstatat64 properly'; }
|
||||||
|
echo stat-4 OK
|
||||||
|
|
||||||
rm -f sample
|
rm -f sample
|
||||||
|
|
||||||
|
|||||||
@@ -11,3 +11,4 @@ check_prog $time
|
|||||||
|
|
||||||
$TIMEOUT $MCEXEC $STRACE -f $time /bin/ls > check.log 2>&1 ||
|
$TIMEOUT $MCEXEC $STRACE -f $time /bin/ls > check.log 2>&1 ||
|
||||||
{ cat check.log; fail_ 'strace -f does not work'; }
|
{ cat check.log; fail_ 'strace -f does not work'; }
|
||||||
|
echo strace-f-1 OK
|
||||||
|
|||||||
@@ -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 ?[K$?
|
|
||||||
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
|
|
||||||
に終了しました
|
|
||||||
30
test/strace/strace-bundle/test.sh
Executable file
30
test/strace/strace-bundle/test.sh
Executable file
@@ -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
|
||||||
Reference in New Issue
Block a user