diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c index 9aa02d67..8cb028c0 100644 --- a/arch/x86_64/kernel/syscall.c +++ b/arch/x86_64/kernel/syscall.c @@ -537,23 +537,32 @@ void ptrace_report_signal(struct thread *thread, int sig) dkprintf("ptrace_report_signal, tid=%d, pid=%d\n", thread->tid, thread->proc->pid); mcs_rwlock_writer_lock(&proc->update_lock, &lock); - if(!(proc->ptrace & PT_TRACED)){ + if (!(thread->ptrace & PT_TRACED)) { mcs_rwlock_writer_unlock(&proc->update_lock, &lock); return; } - thread->exit_status = sig; + /* Transition thread state */ - proc->status = PS_DELAY_TRACED; + thread->exit_status = sig; thread->status = PS_TRACED; - proc->ptrace &= ~PT_TRACE_SYSCALL; - if (sig == SIGSTOP || sig == SIGTSTP || - sig == SIGTTIN || sig == SIGTTOU) { - proc->signal_flags |= SIGNAL_STOP_STOPPED; - } else { - proc->signal_flags &= ~SIGNAL_STOP_STOPPED; - } - parent_pid = proc->parent->pid; + thread->ptrace &= ~PT_TRACE_SYSCALL; save_debugreg(thread->ptrace_debugreg); + if (sig == SIGSTOP || sig == SIGTSTP || + sig == SIGTTIN || sig == SIGTTOU) { + thread->signal_flags |= SIGNAL_STOP_STOPPED; + } + else { + thread->signal_flags &= ~SIGNAL_STOP_STOPPED; + } + + if (thread == proc->main_thread) { + proc->status = PS_DELAY_TRACED; + parent_pid = proc->parent->pid; + } + else { + parent_pid = thread->report_proc->pid; + waitq_wakeup(&thread->report_proc->waitpid_q); + } mcs_rwlock_writer_unlock(&proc->update_lock, &lock); memset(&info, '\0', sizeof info); @@ -574,9 +583,8 @@ ptrace_arch_prctl(int pid, long code, long addr) { long rc = -EIO; struct thread *child; - struct mcs_rwlock_node_irqsave lock; - child = find_thread(pid, pid, &lock); + child = find_thread(pid, pid); if (!child) return -ESRCH; if (child->proc->status & (PS_TRACED | PS_STOPPED)) { @@ -618,7 +626,7 @@ ptrace_arch_prctl(int pid, long code, long addr) break; } } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -690,9 +698,9 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi dkprintf("do_signal(): tid=%d, pid=%d, sig=%d\n", thread->tid, proc->pid, sig); orgsig = sig; - if((proc->ptrace & PT_TRACED) && - pending->ptracecont == 0 && - sig != SIGKILL) { + if ((thread->ptrace & PT_TRACED) && + pending->ptracecont == 0 && + sig != SIGKILL) { ptraceflag = 1; sig = SIGSTOP; } @@ -835,6 +843,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi else { int coredumped = 0; siginfo_t info; + int ptc = pending->ptracecont; if(ptraceflag){ if(thread->ptrace_recvsig) @@ -861,22 +870,37 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi info.si_code = CLD_STOPPED; info._sifields._sigchld.si_pid = thread->proc->pid; info._sifields._sigchld.si_status = (sig << 8) | 0x7f; - do_kill(cpu_local_var(current), thread->proc->parent->pid, -1, SIGCHLD, &info, 0); - dkprintf("do_signal,SIGSTOP,changing state\n"); + if (ptc == 2 && + thread != thread->proc->main_thread) { + thread->signal_flags = + SIGNAL_STOP_STOPPED; + thread->status = PS_STOPPED; + thread->exit_status = SIGSTOP; + do_kill(thread, + thread->report_proc->pid, -1, + SIGCHLD, &info, 0); + waitq_wakeup( + &thread->report_proc->waitpid_q); + } + else { + /* Update thread state in fork tree */ + mcs_rwlock_writer_lock( + &proc->update_lock, &lock); + proc->group_exit_status = SIGSTOP; - /* Update thread state in fork tree */ - mcs_rwlock_writer_lock(&proc->update_lock, &lock); - proc->group_exit_status = SIGSTOP; + /* Reap and set new signal_flags */ + proc->main_thread->signal_flags = + SIGNAL_STOP_STOPPED; - /* Reap and set new signal_flags */ - proc->signal_flags = SIGNAL_STOP_STOPPED; + proc->status = PS_DELAY_STOPPED; + thread->status = PS_STOPPED; + mcs_rwlock_writer_unlock( + &proc->update_lock, &lock); - proc->status = PS_DELAY_STOPPED; - thread->status = PS_STOPPED; - mcs_rwlock_writer_unlock(&proc->update_lock, &lock); - - dkprintf("do_signal(): pid: %d, tid: %d SIGSTOP, sleeping\n", - proc->pid, thread->tid); + do_kill(thread, + thread->proc->parent->pid, -1, + SIGCHLD, &info, 0); + } /* Sleep */ schedule(); dkprintf("SIGSTOP(): woken up\n"); @@ -884,16 +908,28 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi break; case SIGTRAP: dkprintf("do_signal,SIGTRAP\n"); - if(!(proc->ptrace & PT_TRACED)) { + if (!(thread->ptrace & PT_TRACED)) { goto core; } /* Update thread state in fork tree */ - mcs_rwlock_writer_lock(&proc->update_lock, &lock); thread->exit_status = SIGTRAP; - proc->status = PS_DELAY_TRACED; thread->status = PS_TRACED; - mcs_rwlock_writer_unlock(&proc->update_lock, &lock); + if (thread == proc->main_thread) { + mcs_rwlock_writer_lock(&proc->update_lock, + &lock); + proc->group_exit_status = SIGTRAP; + proc->status = PS_DELAY_TRACED; + mcs_rwlock_writer_unlock(&proc->update_lock, + &lock); + do_kill(thread, thread->proc->parent->pid, -1, + SIGCHLD, &info, 0); + } + else { + do_kill(thread, thread->report_proc->pid, -1, + SIGCHLD, &info, 0); + waitq_wakeup(&thread->report_proc->waitpid_q); + } /* Sleep */ dkprintf("do_signal,SIGTRAP,sleeping\n"); @@ -908,7 +944,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi info._sifields._sigchld.si_pid = proc->pid; info._sifields._sigchld.si_status = 0x0000ffff; do_kill(cpu_local_var(current), proc->parent->pid, -1, SIGCHLD, &info, 0); - proc->signal_flags = SIGNAL_STOP_CONTINUED; + proc->main_thread->signal_flags = SIGNAL_STOP_CONTINUED; proc->status = PS_RUNNING; dkprintf("do_signal,SIGCONT,do nothing\n"); break; @@ -958,10 +994,12 @@ getsigpending(struct thread *thread, int delflag){ lock = &thread->sigcommon->lock; head = &thread->sigcommon->sigpending; for(;;) { - if (delflag) + if (delflag) { mcs_rwlock_writer_lock(lock, &mcs_rw_node); - else + } + else { mcs_rwlock_reader_lock(lock, &mcs_rw_node); + } list_for_each_entry_safe(pending, next, head, list){ for(x = pending->sigmask.__val[0], sig = 0; x; sig++, x >>= 1); @@ -974,19 +1012,23 @@ getsigpending(struct thread *thread, int delflag){ if(delflag) list_del(&pending->list); - if (delflag) + if (delflag) { mcs_rwlock_writer_unlock(lock, &mcs_rw_node); - else + } + else { mcs_rwlock_reader_unlock(lock, &mcs_rw_node); + } return pending; } } } - if (delflag) + if (delflag) { mcs_rwlock_writer_unlock(lock, &mcs_rw_node); - else + } + else { mcs_rwlock_reader_unlock(lock, &mcs_rw_node); + } if(lock == &thread->sigpendinglock) return NULL; @@ -1177,7 +1219,7 @@ repeat: continue; } - if (thread->proc->exit_status & 0x0000000100000000L) { + if (thread->proc->group_exit_status & 0x0000000100000000L) { continue; } @@ -1404,10 +1446,10 @@ done: in check_signal */ rc = 0; k = tthread->sigcommon->action + sig - 1; - if((sig != SIGKILL && (tproc->ptrace & PT_TRACED)) || - (k->sa.sa_handler != (void *)1 && - (k->sa.sa_handler != NULL || - (sig != SIGCHLD && sig != SIGURG)))){ + if ((sig != SIGKILL && (tthread->ptrace & PT_TRACED)) || + (k->sa.sa_handler != (void *)1 && + (k->sa.sa_handler != NULL || + (sig != SIGCHLD && sig != SIGURG)))) { struct sig_pending *pending = NULL; if (sig < 33) { // SIGRTMIN - SIGRTMAX list_for_each_entry(pending, head, list){ diff --git a/kernel/host.c b/kernel/host.c index 90ee0944..3ec76f96 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -576,7 +576,6 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, struct ikc_scd_packet pckt; struct ihk_ikc_channel_desc *resp_channel = cpu_local_var(ikc2linux); int rc; - struct mcs_rwlock_node_irqsave lock; struct thread *thread; struct process *proc; struct mcctrl_signal { @@ -637,14 +636,14 @@ static int syscall_packet_handler(struct ihk_ikc_channel_desc *c, * the waiting thread */ case SCD_MSG_WAKE_UP_SYSCALL_THREAD: - thread = find_thread(0, packet->ttid, &lock); + thread = find_thread(0, packet->ttid); if (!thread) { kprintf("%s: WARNING: no thread for SCD reply? TID: %d\n", __FUNCTION__, packet->ttid); ret = -EINVAL; break; } - thread_unlock(thread, &lock); + thread_unlock(thread); dkprintf("%s: SCD_MSG_WAKE_UP_SYSCALL_THREAD: waking up tid %d\n", __FUNCTION__, packet->ttid); diff --git a/kernel/include/process.h b/kernel/include/process.h index 24acf1fb..4b0f6472 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -464,6 +464,14 @@ struct process { // threads and children struct list_head threads_list; + struct list_head report_threads_list; + + /* + * main_thread is used to refer to thread information using process ID. + * 1) signal related state in signal_flags + * 2) status of trace + */ + struct thread *main_thread; mcs_rwlock_lock_t threads_lock; // lock for threads_list /* TID set of proxy process */ struct mcexec_tid *tids; @@ -492,7 +500,6 @@ struct process { // V +---- | // PS_STOPPED -----+ // (PS_TRACED) - unsigned long exit_status; // only for zombie /* Store exit_status for a group of threads when stopped by SIGSTOP. exit_status can't be used because values of exit_status of threads @@ -524,22 +531,6 @@ struct process { long saved_cmdline_len; cpu_set_t cpu_set; - /* Store ptrace flags. - * The lower 8 bits are PTRACE_O_xxx of the PTRACE_SETOPTIONS request. - * Other bits are for inner use of the McKernel. - */ - int ptrace; - - /* Store ptrace event message. - * PTRACE_O_xxx will store event message here. - * PTRACE_GETEVENTMSG will get from here. - */ - unsigned long ptrace_eventmsg; - - /* Store event related to signal. For example, - it represents that the proceess has been resumed by SIGCONT. */ - int signal_flags; - /* Store signal sent to parent when the process terminates. */ int termsig; @@ -610,7 +601,7 @@ struct thread { // thread info int cpu_id; int tid; - int status; // PS_RUNNING -> PS_EXITED + int status; // PS_RUNNING -> PS_EXITED (-> ZOMBIE / ptrace) // | ^ ^ // | | | // V | | @@ -620,6 +611,14 @@ struct thread { // PS_UNINTERRUPTIBLE int exit_status; + /* + * Store event related to signal. For example, + * it represents that the proceess has been resumed by SIGCONT. + */ + int signal_flags; + + int termsig; + // process vm struct process_vm *vm; @@ -639,6 +638,22 @@ struct thread { ihk_spinlock_t spin_sleep_lock; int spin_sleep; + // for ptrace + struct process *report_proc; + struct list_head report_siblings_list; // lock process + + /* Store ptrace flags. + * The lower 8 bits are PTRACE_O_xxx of the PTRACE_SETOPTIONS request. + * Other bits are for inner use of the McKernel. + */ + int ptrace; + + /* Store ptrace event message. + * PTRACE_O_xxx will store event message here. + * PTRACE_GETEVENTMSG will get from here. + */ + unsigned long ptrace_eventmsg; + ihk_atomic_t refcount; int *clear_child_tid; @@ -830,8 +845,8 @@ void cpu_clear_and_set(int c_cpu, int s_cpu, void release_cpuid(int cpuid); -struct thread *find_thread(int pid, int tid, struct mcs_rwlock_node_irqsave *lock); -void thread_unlock(struct thread *thread, struct mcs_rwlock_node_irqsave *lock); +struct thread *find_thread(int pid, int tid); +void thread_unlock(struct thread *thread); struct process *find_process(int pid, struct mcs_rwlock_node_irqsave *lock); void process_unlock(struct process *proc, struct mcs_rwlock_node_irqsave *lock); void chain_process(struct process *); @@ -846,6 +861,7 @@ extern unsigned long do_kill(struct thread *thread, int pid, int tid, int sig, struct siginfo *info, int ptracecont); extern void set_signal(int sig, void *regs, struct siginfo *info); extern void check_sig_pending(void); +void clear_single_step(struct thread *thread); void release_fp_regs(struct thread *proc); void save_fp_regs(struct thread *proc); diff --git a/kernel/process.c b/kernel/process.c index fad3e910..58537f72 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -125,6 +125,7 @@ init_process(struct process *proc, struct process *parent) INIT_LIST_HEAD(&proc->ptraced_siblings_list); mcs_rwlock_init(&proc->update_lock); #endif /* POSTK_DEBUG_ARCH_DEP_63 */ + INIT_LIST_HEAD(&proc->report_threads_list); INIT_LIST_HEAD(&proc->threads_list); INIT_LIST_HEAD(&proc->children_list); INIT_LIST_HEAD(&proc->ptraced_children_list); @@ -349,6 +350,7 @@ struct thread *create_thread(unsigned long user_pc, thread->vm = vm; thread->proc = proc; proc->vm = vm; + proc->main_thread = thread; if(init_process_vm(proc, asp, vm) != 0){ goto err; @@ -466,6 +468,7 @@ clone_thread(struct thread *org, unsigned long pc, unsigned long sp, thread->proc = proc; thread->vm = proc->vm; + proc->main_thread = thread; memcpy(&proc->vm->region, &org->vm->region, sizeof(struct vm_regions)); @@ -570,29 +573,47 @@ ptrace_traceme(void) struct thread *thread = cpu_local_var(current); struct process *proc = thread->proc; struct process *parent = proc->parent; - struct mcs_rwlock_node_irqsave lock; struct mcs_rwlock_node child_lock; + struct resource_set *resource_set = cpu_local_var(resource_set); + struct process *pid1 = resource_set->pid1; dkprintf("ptrace_traceme,pid=%d,proc->parent=%p\n", proc->pid, proc->parent); - if (proc->ptrace & PT_TRACED) { + if (thread->ptrace & PT_TRACED) { + return -EPERM; + } + if (parent == pid1) { return -EPERM; } dkprintf("ptrace_traceme,parent->pid=%d\n", proc->parent->pid); - mcs_rwlock_writer_lock(&proc->update_lock, &lock); - mcs_rwlock_writer_lock_noirq(&parent->children_lock, &child_lock); - list_add_tail(&proc->ptraced_siblings_list, &parent->ptraced_children_list); - mcs_rwlock_writer_unlock_noirq(&parent->children_lock, &child_lock); - proc->ptrace = PT_TRACED | PT_TRACE_EXEC; - mcs_rwlock_writer_unlock(&proc->update_lock, &lock); + if (thread == proc->main_thread) { + mcs_rwlock_writer_lock_noirq(&parent->children_lock, + &child_lock); + list_add_tail(&proc->ptraced_siblings_list, + &parent->ptraced_children_list); + mcs_rwlock_writer_unlock_noirq(&parent->children_lock, + &child_lock); + } + if (!thread->report_proc) { + mcs_rwlock_writer_lock_noirq(&parent->threads_lock, + &child_lock); + list_add_tail(&thread->report_siblings_list, + &parent->report_threads_list); + mcs_rwlock_writer_unlock_noirq(&parent->threads_lock, + &child_lock); + thread->report_proc = parent; + } + + thread->ptrace = PT_TRACED | PT_TRACE_EXEC; if (thread->ptrace_debugreg == NULL) { error = alloc_debugreg(thread); } clear_single_step(thread); + hold_thread(thread); dkprintf("ptrace_traceme,returning,error=%d\n", error); return error; @@ -2430,6 +2451,11 @@ void free_process_memory_ranges(struct process_vm *vm) ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock); } +static void free_thread_pages(struct thread *thread) +{ + ihk_mc_free_pages(thread, KERNEL_STACK_NR_PAGES); +} + void hold_process(struct process *proc) { @@ -2462,13 +2488,6 @@ release_process(struct process *proc) list_del(&proc->siblings_list); mcs_rwlock_writer_unlock(&parent->children_lock, &lock); - if(proc->ptrace & PT_TRACED){ - parent = proc->ppid_parent; - mcs_rwlock_writer_lock(&parent->children_lock, &lock); - list_del(&proc->ptraced_siblings_list); - mcs_rwlock_writer_unlock(&parent->children_lock, &lock); - } - if (proc->tids) kfree(proc->tids); #ifdef PROFILE_ENABLE if (proc->profile) { @@ -2481,6 +2500,7 @@ release_process(struct process *proc) } profile_dealloc_proc_events(proc); #endif // PROFILE_ENABLE + free_thread_pages(proc->main_thread); kfree(proc); } @@ -2574,8 +2594,8 @@ out: int hold_thread(struct thread *thread) { if (thread->status == PS_EXITED) { - kprintf("hold_thread: ERROR: already exited process,tid=%d\n", thread->tid); - return -ESRCH; + kprintf("hold_thread: WARNING: already exited process,tid=%d\n", + thread->tid); } ihk_atomic_inc(&thread->refcount); @@ -2657,17 +2677,16 @@ void destroy_thread(struct thread *thread) ts_add(&thread->proc->stime, &ats); tsc_to_ts(thread->user_tsc, &ats); ts_add(&thread->proc->utime, &ats); + mcs_rwlock_writer_unlock(&proc->update_lock, &updatelock); mcs_rwlock_writer_lock(&proc->threads_lock, &lock); list_del(&thread->siblings_list); if (thread->uti_state == UTI_STATE_EPILOGUE) { __find_and_replace_tid(proc, thread, thread->uti_refill_tid); - } else { + } + else if (thread != proc->main_thread) { __release_tid(proc, thread); } - mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); - - mcs_rwlock_writer_unlock(&proc->update_lock, &updatelock); cpu_clear(thread->cpu_id, &thread->vm->address_space->cpu_set, &thread->vm->address_space->cpu_set_lock); @@ -2691,7 +2710,9 @@ void destroy_thread(struct thread *thread) release_sigcommon(thread->sigcommon); - ihk_mc_free_pages(thread, KERNEL_STACK_NR_PAGES); + if (thread != proc->main_thread) + free_thread_pages(thread); + mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); } void release_thread(struct thread *thread) @@ -2713,20 +2734,6 @@ void release_thread(struct thread *thread) destroy_thread(thread); release_process_vm(vm); - rusage_num_threads_dec(); - -#ifdef RUSAGE_DEBUG - if (rusage->num_threads == 0) { - int i; - kprintf("total_memory_usage=%ld\n", rusage->total_memory_usage); - for(i = 0; i < IHK_MAX_NUM_PGSIZES; i++) { - kprintf("memory_stat_rss[%d]=%ld\n", i, rusage->memory_stat_rss[i]); - } - for(i = 0; i < IHK_MAX_NUM_PGSIZES; i++) { - kprintf("memory_stat_mapped_file[%d]=%ld\n", i, rusage->memory_stat_mapped_file[i]); - } - } -#endif } void cpu_set(int cpu, cpu_set_t *cpu_set, ihk_spinlock_t *lock) @@ -3287,6 +3294,25 @@ void schedule(void) if ((last != NULL) && (last->status == PS_EXITED)) { release_thread(last); + rusage_num_threads_dec(); +#ifdef RUSAGE_DEBUG + if (rusage->num_threads == 0) { + int i; + + kprintf("total_memory_usage=%ld\n", + rusage->total_memory_usage); + for (i = 0; i < IHK_MAX_NUM_PGSIZES; i++) { + kprintf("memory_stat_rss[%d]=%ld\n", i, + rusage->memory_stat_rss[i]); + } + for (i = 0; i < IHK_MAX_NUM_PGSIZES; i++) { + kprintf( + "memory_stat_mapped_file[%d]=%ld\n", + i, + rusage->memory_stat_mapped_file[i]); + } + } +#endif } /* Have we migrated to another core meanwhile? */ @@ -3535,22 +3561,26 @@ void runq_del_thread(struct thread *thread, int cpu_id) } struct thread * -find_thread(int pid, int tid, struct mcs_rwlock_node_irqsave *lock) +find_thread(int pid, int tid) { struct thread *thread; struct thread_hash *thash = cpu_local_var(resource_set)->thread_hash; int hash = thread_hash(tid); + struct mcs_rwlock_node_irqsave lock; if(tid <= 0) return NULL; - mcs_rwlock_reader_lock(&thash->lock[hash], lock); + mcs_rwlock_reader_lock(&thash->lock[hash], &lock); retry: list_for_each_entry(thread, &thash->list[hash], hash_list){ if(thread->tid == tid){ - if(pid <= 0) - return thread; - if(thread->proc->pid == pid) + if (pid <= 0 || + thread->proc->pid == pid) { + hold_thread(thread); + mcs_rwlock_reader_unlock(&thash->lock[hash], + &lock); return thread; + } } } /* If no thread with pid == tid was found, then we may be looking for a @@ -3560,20 +3590,16 @@ retry: pid = 0; goto retry; } - mcs_rwlock_reader_unlock(&thash->lock[hash], lock); + mcs_rwlock_reader_unlock(&thash->lock[hash], &lock); return NULL; } void -thread_unlock(struct thread *thread, struct mcs_rwlock_node_irqsave *lock) +thread_unlock(struct thread *thread) { - struct thread_hash *thash = cpu_local_var(resource_set)->thread_hash; - int hash; - if(!thread) return; - hash = thread_hash(thread->tid); - mcs_rwlock_reader_unlock(&thash->lock[hash], lock); + release_thread(thread); } struct process * @@ -3628,8 +3654,9 @@ debug_log(unsigned long arg) if (p == pid1) continue; found++; - kprintf("pid=%d ppid=%d status=%d\n", - p->pid, p->ppid_parent->pid, p->status); + kprintf("pid=%d ppid=%d status=%d ref=%d\n", + p->pid, p->ppid_parent->pid, p->status, + p->refcount.counter); } __mcs_rwlock_reader_unlock(&phash->lock[i], &lock); } @@ -3640,9 +3667,11 @@ debug_log(unsigned long arg) __mcs_rwlock_reader_lock(&thash->lock[i], &lock); list_for_each_entry(t, &thash->list[i], hash_list){ found++; - kprintf("cpu=%d pid=%d tid=%d status=%d offload=%d\n", - t->cpu_id, t->proc->pid, t->tid, - t->status, t->in_syscall_offload); + kprintf("cpu=%d pid=%d tid=%d status=%d " + "offload=%d ref=%d ptrace=%08x\n", + t->cpu_id, t->proc->pid, t->tid, + t->status, t->in_syscall_offload, + t->refcount.counter, t->ptrace); } __mcs_rwlock_reader_unlock(&thash->lock[i], &lock); } diff --git a/kernel/syscall.c b/kernel/syscall.c index 466ca890..e59c19bc 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -449,9 +449,9 @@ static int wait_zombie(struct thread *thread, struct process *child, int *status dkprintf("wait_zombie,found PS_ZOMBIE process: %d\n", child->pid); - if (status) { - *status = child->exit_status; - } + if (status) { + *status = child->group_exit_status; + } if(child->ppid_parent->pid != thread->proc->pid || child->nowait) return child->pid; @@ -477,9 +477,17 @@ static int wait_stopped(struct thread *thread, struct process *child, struct thr int ret; /* Copy exit_status created in do_signal */ - int *exit_status = (child->status == PS_STOPPED || !c_thread) ? - &child->group_exit_status : - &c_thread->exit_status; + int *exit_status; + + if (c_thread) { + exit_status = &c_thread->exit_status; + } + else if (child->status & (PS_STOPPED | PS_DELAY_STOPPED)) { + exit_status = &child->group_exit_status; + } + else { + exit_status = &child->main_thread->exit_status; + } /* Skip this process because exit_status has been reaped. */ if (!*exit_status) { @@ -500,12 +508,14 @@ static int wait_stopped(struct thread *thread, struct process *child, struct thr dkprintf("wait_stopped,child->pid=%d,status=%08x\n", child->pid, status ? *status : -1); - ret = child->pid; + ret = c_thread ? c_thread->tid : child->pid; out: return ret; } -static int wait_continued(struct thread *thread, struct process *child, int *status, int options) { +static int wait_continued(struct thread *thread, struct process *child, + struct thread *c_thread, int *status, int options) +{ int ret; if (status) { @@ -514,40 +524,50 @@ static int wait_continued(struct thread *thread, struct process *child, int *sta /* Reap signal_flags */ if(!(options & WNOWAIT)) { - child->signal_flags &= ~SIGNAL_STOP_CONTINUED; + if (c_thread) + c_thread->signal_flags &= ~SIGNAL_STOP_CONTINUED; + else + child->main_thread->signal_flags &= + ~SIGNAL_STOP_CONTINUED; } dkprintf("wait4,SIGNAL_STOP_CONTINUED,pid=%d,status=%08x\n", child->pid, status ? *status : -1); - ret = child->pid; + ret = c_thread ? c_thread->tid : child->pid; return ret; } -struct thread *find_thread_of_process(struct process *child, int pid) -{ - int c_found = 0; - struct mcs_rwlock_node c_lock; - struct thread *c_thread = NULL; - - mcs_rwlock_reader_lock_noirq(&child->threads_lock, &c_lock); - list_for_each_entry(c_thread, &child->threads_list, siblings_list) { - if (c_thread->tid == pid) { - c_found = 1; - break; - } - } - mcs_rwlock_reader_unlock_noirq(&child->threads_lock, &c_lock); - if (!c_found) c_thread = NULL; - - return c_thread; -} - static void -set_process_rusage(struct process *proc, struct rusage *usage) +thread_exit_signal(struct thread *thread) { - ts_to_tv(&usage->ru_utime, &proc->utime); - ts_to_tv(&usage->ru_stime, &proc->stime); - usage->ru_maxrss = proc->maxrss / 1024; + int sig; + struct siginfo info; + int error; + struct timespec ats; + + if (thread->report_proc == NULL) { + return; + } + + if (thread->ptrace) + sig = SIGCHLD; + else + sig = thread->termsig; + memset(&info, '\0', sizeof(info)); + info.si_signo = sig; + info.si_code = (thread->exit_status & 0x7f) ? + ((thread->exit_status & 0x80) ? + CLD_DUMPED : CLD_KILLED) : CLD_EXITED; + info._sifields._sigchld.si_pid = thread->tid; + info._sifields._sigchld.si_status = thread->exit_status; + tsc_to_ts(thread->user_tsc, &ats); + info._sifields._sigchld.si_utime = timespec_to_jiffy(&ats); + tsc_to_ts(thread->system_tsc, &ats); + info._sifields._sigchld.si_stime = timespec_to_jiffy(&ats); + error = do_kill(NULL, thread->report_proc->pid, -1, sig, &info, 0); + dkprintf("terminate,klll %d,error=%d\n", sig, error); + /* Wake parent (if sleeping in wait4()) */ + waitq_wakeup(&thread->report_proc->waitpid_q); } static void @@ -555,7 +575,7 @@ finalize_process(struct process *proc) { struct resource_set *resource_set = cpu_local_var(resource_set); struct process *pid1 = resource_set->pid1; - int exit_status = proc->exit_status; + int exit_status = proc->group_exit_status; // Send signal to parent if (proc->parent == pid1) { @@ -592,185 +612,421 @@ finalize_process(struct process *proc) } } -/* +static void +ptrace_detach_thread(struct thread *thread, int data) +{ + struct resource_set *resource_set = cpu_local_var(resource_set); + struct process *pid1 = resource_set->pid1; + struct thread *mythread = cpu_local_var(current); + struct process *proc = mythread->proc; + struct process *report_proc = NULL; + struct mcs_rwlock_node_irqsave lock; + struct process *term_proc = NULL; + + if (thread == thread->proc->main_thread) { + struct process *tracee_proc = thread->proc; + struct process *parent = tracee_proc->ppid_parent; + + if (thread->proc->status == PS_ZOMBIE && + thread->proc->parent != parent) { + term_proc = thread->proc; + } + mcs_rwlock_reader_lock(&proc->children_lock, &lock); + + list_del(&tracee_proc->siblings_list); + mcs_rwlock_reader_unlock(&proc->children_lock, &lock); + + mcs_rwlock_reader_lock(&tracee_proc->children_lock, &lock); + list_del(&tracee_proc->ptraced_siblings_list); + list_add_tail(&tracee_proc->siblings_list, + &parent->children_list); + tracee_proc->parent = parent; + + mcs_rwlock_reader_unlock(&tracee_proc->children_lock, &lock); + } + if (thread->termsig && + thread->termsig != SIGCHLD && + thread->proc != pid1) { + report_proc = thread->proc; + } + thread->report_proc = report_proc; + mcs_rwlock_reader_lock(&proc->threads_lock, &lock); + list_del(&thread->report_siblings_list); + mcs_rwlock_reader_unlock(&proc->threads_lock, &lock); + thread->ptrace = 0; + kfree(thread->ptrace_debugreg); + thread->ptrace_debugreg = NULL; + + clear_single_step(thread); + if (report_proc) { + mcs_rwlock_reader_lock(&report_proc->threads_lock, &lock); + list_add_tail(&thread->report_siblings_list, + &report_proc->report_threads_list); + mcs_rwlock_reader_unlock(&report_proc->threads_lock, &lock); + if (thread->status == PS_EXITED || + thread->status == PS_ZOMBIE) { + /* + * Traced thread reports to the original parent with + * the termination signal in addition to the report + * to the tracer. + */ + thread_exit_signal(thread); + } + } + + if (data) { + struct siginfo info; + + memset(&info, '\0', sizeof(info)); + info.si_signo = data; + info.si_code = SI_USER; + info._sifields._kill.si_pid = proc->pid; + do_kill(mythread, thread->proc->pid, thread->tid, + data, &info, 1); + } + sched_wakeup_thread(thread, PS_TRACED | PS_STOPPED); + release_thread(thread); + if (term_proc) { + finalize_process(term_proc); + } +} + +static void +set_process_rusage(struct process *proc, struct rusage *usage) +{ + ts_to_tv(&usage->ru_utime, &proc->utime); + ts_to_tv(&usage->ru_stime, &proc->stime); + usage->ru_maxrss = proc->maxrss / 1024; +} + +static int +wait_proc(int pid, int *status, int options, void *rusage, int *empty) +{ + struct thread *thread = cpu_local_var(current); + struct process *proc = thread->proc; + struct process *child, *next; + int pgid = proc->pgid; + int ret = 0; + struct mcs_rwlock_node lock; + struct mcs_rwlock_node child_lock; + struct thread *c_thread = NULL; + + mcs_rwlock_writer_lock_noirq(&proc->children_lock, &lock); + list_for_each_entry_safe(child, next, &proc->children_list, + siblings_list) { + /* + * Find thread with pid == tid, this will be either the main + * thread or the one we are looking for specifically when + * __WCLONE is passed + */ + if ((pid >= 0 || -pid != child->pgid) && + pid != -1 && + (pid != 0 || pgid != child->pgid) && + (pid <= 0 || pid != child->pid)) + continue; + + *empty = 0; + + if ((options & WEXITED) && + child->status == PS_ZOMBIE) { + ret = wait_zombie(thread, child, status, options); + if (!(options & WNOWAIT) && + child->parent == child->ppid_parent) { + struct mcs_rwlock_node updatelock; + struct mcs_rwlock_node childlock; + struct process *pid1; + + pid1 = cpu_local_var(resource_set)->pid1; + + mcs_rwlock_writer_lock_noirq(&proc->update_lock, + &updatelock); + ts_add(&proc->stime_children, &child->stime); + ts_add(&proc->utime_children, &child->utime); + ts_add(&proc->stime_children, + &child->stime_children); + ts_add(&proc->utime_children, + &child->utime_children); + if (child->maxrss > proc->maxrss_children) + proc->maxrss_children = child->maxrss; + if (child->maxrss_children > + proc->maxrss_children) + proc->maxrss_children = + child->maxrss_children; + set_process_rusage(child, rusage); + mcs_rwlock_writer_unlock_noirq( + &proc->update_lock, &updatelock); + list_del(&child->siblings_list); + mcs_rwlock_writer_unlock_noirq( + &proc->children_lock, &lock); + + mcs_rwlock_writer_lock_noirq( + &child->update_lock, &updatelock); + child->parent = pid1; + child->ppid_parent = pid1; + mcs_rwlock_writer_lock_noirq( + &pid1->children_lock, &childlock); + list_add_tail(&child->siblings_list, + &pid1->children_list); + mcs_rwlock_writer_unlock_noirq( + &pid1->children_lock, &childlock); + mcs_rwlock_writer_unlock_noirq( + &child->update_lock, &updatelock); + mcs_rwlock_writer_lock_noirq( + &child->threads_lock, &child_lock); + c_thread = child->main_thread; + if (c_thread && + (c_thread->ptrace & PT_TRACED)) { + mcs_rwlock_writer_unlock_noirq( + &child->threads_lock, &child_lock); + ptrace_detach_thread(c_thread, 0); + } + else { + mcs_rwlock_writer_unlock_noirq( + &child->threads_lock, &child_lock); + } + release_process(child); + } + else{ + mcs_rwlock_writer_lock_noirq( + &child->threads_lock, &child_lock); + c_thread = child->main_thread; + if (c_thread && !(options & WNOWAIT) && + (c_thread->ptrace & PT_TRACED)) { + mcs_rwlock_writer_unlock_noirq( + &child->threads_lock, &child_lock); + mcs_rwlock_writer_unlock_noirq( + &proc->children_lock, &lock); + ptrace_detach_thread(c_thread, 0); + } + else { + mcs_rwlock_writer_unlock_noirq( + &child->threads_lock, &child_lock); + mcs_rwlock_writer_unlock_noirq( + &proc->children_lock, &lock); + } + } + + goto out_found; + } + + mcs_rwlock_writer_lock_noirq(&child->threads_lock, &child_lock); + c_thread = child->main_thread; + + if (!(c_thread->ptrace & PT_TRACED) && + (c_thread->signal_flags & SIGNAL_STOP_STOPPED) && + (options & WUNTRACED)) { + /* + * Not ptraced and in stopped state and WUNTRACED is + * specified + */ + ret = wait_stopped(thread, child, NULL, status, + options); + if (!(options & WNOWAIT)) { + c_thread->signal_flags &= ~SIGNAL_STOP_STOPPED; + } + mcs_rwlock_writer_unlock_noirq(&proc->children_lock, + &lock); + mcs_rwlock_writer_unlock_noirq(&child->threads_lock, + &child_lock); + goto out_found; + } + + if ((c_thread->ptrace & PT_TRACED) && + (child->status & (PS_STOPPED | PS_TRACED))) { + ret = wait_stopped(thread, child, NULL, status, + options); + if (ret == child->pid) { + /* Are we looking for a specific thread? */ + if (pid == c_thread->tid) { + ret = c_thread->tid; + } + if (!(options & WNOWAIT)) { + c_thread->signal_flags &= + ~SIGNAL_STOP_STOPPED; + } + mcs_rwlock_writer_unlock_noirq( + &proc->children_lock, &lock); + mcs_rwlock_writer_unlock_noirq( + &child->threads_lock, &child_lock); + goto out_found; + } + } + + if ((c_thread->signal_flags & SIGNAL_STOP_CONTINUED) && + (options & WCONTINUED)) { + ret = wait_continued(thread, child, NULL, status, + options); + if (!(options & WNOWAIT)) { + c_thread->signal_flags &= + ~SIGNAL_STOP_CONTINUED; + } + mcs_rwlock_writer_unlock_noirq(&proc->children_lock, + &lock); + mcs_rwlock_writer_unlock_noirq(&child->threads_lock, + &child_lock); + goto out_found; + } + mcs_rwlock_writer_unlock_noirq(&child->threads_lock, + &child_lock); + } + + if (*empty) { + list_for_each_entry(child, &proc->ptraced_children_list, + ptraced_siblings_list) { + if ((pid < 0 && -pid == child->pgid) || + pid == -1 || + (pid == 0 && pgid == child->pgid) || + (pid > 0 && pid == child->pid)) { + *empty = 0; + break; + } + } + } + mcs_rwlock_writer_unlock_noirq(&proc->children_lock, &lock); +out_found: + + return ret; +} + +static int +wait_thread(int tid, int *status, int options, void *rusage, int *empty) +{ + struct thread *thread = cpu_local_var(current); + struct process *proc = thread->proc; + struct thread *child, *next; + int ret = 0; + struct mcs_rwlock_node lock; + + mcs_rwlock_writer_lock_noirq(&thread->proc->threads_lock, &lock); + list_for_each_entry_safe(child, next, &proc->report_threads_list, + report_siblings_list) { + if (tid != -1 && child->tid != tid) + continue; + if (child == child->proc->main_thread) + continue; + *empty = 0; + if ((options & WEXITED) && + (child->status == PS_EXITED || + child->status == PS_ZOMBIE)) { + ret = child->tid; + if (!(options & WNOWAIT)) { + if (child->ptrace & PT_TRACED) { + mcs_rwlock_writer_unlock_noirq( + &thread->proc->threads_lock, &lock); + ptrace_detach_thread(child, 0); + } + else { + list_del(&child->report_siblings_list); + child->report_proc = NULL; + mcs_rwlock_writer_unlock_noirq( + &thread->proc->threads_lock, &lock); + release_thread(child); + } + } + else + mcs_rwlock_writer_unlock_noirq( + &thread->proc->threads_lock, &lock); + goto out_found; + } + + if (!(child->ptrace & PT_TRACED) && + (child->signal_flags & SIGNAL_STOP_STOPPED) && + (options & WUNTRACED)) { + /* + * Not ptraced and in stopped state and WUNTRACED is + * specified + */ + ret = wait_stopped(thread, child->proc, child, status, + options); + if (!(options & WNOWAIT)) { + child->signal_flags &= ~SIGNAL_STOP_STOPPED; + } + mcs_rwlock_writer_unlock_noirq( + &thread->proc->threads_lock, &lock); + goto out_found; + } + + if ((child->ptrace & PT_TRACED) && + (child->status & (PS_STOPPED | PS_TRACED))) { + ret = wait_stopped(thread, child->proc, child, status, + options); + if (ret == child->tid) { + /* Are we looking for a specific thread? */ + if (!(options & WNOWAIT)) { + child->signal_flags &= + ~SIGNAL_STOP_STOPPED; + } + mcs_rwlock_writer_unlock_noirq( + &thread->proc->threads_lock, &lock); + goto out_found; + } + } + + if ((child->signal_flags & SIGNAL_STOP_CONTINUED) && + (options & WCONTINUED)) { + ret = wait_continued(thread, child->proc, child, status, + options); + if (!(options & WNOWAIT)) { + child->signal_flags &= ~SIGNAL_STOP_CONTINUED; + } + mcs_rwlock_writer_unlock_noirq( + &thread->proc->threads_lock, &lock); + goto out_found; + } + } + + if (*empty) { + list_for_each_entry(child, &proc->threads_list, + siblings_list) { + if (child == child->proc->main_thread) + continue; + if (child->termsig && child->termsig != SIGCHLD) { + *empty = 0; + break; + } + } + } + mcs_rwlock_writer_unlock_noirq(&thread->proc->threads_lock, &lock); +out_found: + return ret; +} + +/* * From glibc: INLINE_SYSCALL (wait4, 4, pid, stat_loc, options, NULL); */ static int do_wait(int pid, int *status, int options, void *rusage) { struct thread *thread = cpu_local_var(current); - struct process *proc = thread->proc; - struct process *child, *next; - int pgid = proc->pgid; int ret; struct waitq_entry waitpid_wqe; int empty = 1; int orgpid = pid; - struct mcs_rwlock_node lock; - struct thread *c_thread = NULL; - dkprintf("wait4(): current->proc->pid: %d, pid: %d\n", thread->proc->pid, pid); + dkprintf("wait4(): current->proc->pid: %d, pid: %d\n", + thread->proc->pid, pid); rescan: -#ifdef POSTK_DEBUG_TEMP_FIX_65 /* wait4() lose infomation fix. */ waitq_init_entry(&waitpid_wqe, thread); - waitq_prepare_to_wait(&thread->proc->waitpid_q, &waitpid_wqe, PS_INTERRUPTIBLE); -#endif /* POSTK_DEBUG_TEMP_FIX_65 */ + waitq_prepare_to_wait(&thread->proc->waitpid_q, &waitpid_wqe, + PS_INTERRUPTIBLE); pid = orgpid; - mcs_rwlock_writer_lock_noirq(&thread->proc->children_lock, &lock); - list_for_each_entry_safe(child, next, &proc->children_list, siblings_list) { - /* - if (!(options & __WALL) && - !(!!(options & __WCLONE) ^ (child->termsig == SIGCHLD))) { - continue; + if (!(options & __WCLONE)) { + if ((ret = wait_proc(pid, status, options, rusage, &empty))) { + goto out_found; } - */ - - /* Find thread with pid == tid, this will be either the main thread - * or the one we are looking for specifically when __WCLONE is passed */ - //if (options & __WCLONE) - c_thread = find_thread_of_process(child, pid); - - if ((pid < 0 && -pid == child->pgid) || - pid == -1 || - (pid == 0 && pgid == child->pgid) || - (pid > 0 && pid == child->pid) || c_thread != NULL) { - - empty = 0; - - if((options & WEXITED) && - child->status == PS_ZOMBIE) { - int org_options = options; - - if ((child->ptrace & PT_TRACED) && - child->parent != child->ppid_parent) { - options |= WNOWAIT; - } - - ret = wait_zombie(thread, child, status, options); - if(!(options & WNOWAIT)){ - struct mcs_rwlock_node updatelock; - struct mcs_rwlock_node childlock; - struct process *pid1 = cpu_local_var(resource_set)->pid1; - mcs_rwlock_writer_lock_noirq(&proc->update_lock, &updatelock); - ts_add(&proc->stime_children, &child->stime); - ts_add(&proc->utime_children, &child->utime); - ts_add(&proc->stime_children, &child->stime_children); - ts_add(&proc->utime_children, &child->utime_children); - if(child->maxrss > proc->maxrss_children) - proc->maxrss_children = child->maxrss; - if(child->maxrss_children > proc->maxrss_children) - proc->maxrss_children = child->maxrss_children; - set_process_rusage(child, rusage); - mcs_rwlock_writer_unlock_noirq(&proc->update_lock, &updatelock); - list_del(&child->siblings_list); - mcs_rwlock_writer_unlock_noirq(&proc->children_lock, &lock); - - if(child->ptrace & PT_TRACED){ - struct process *parent = child->ppid_parent; - mcs_rwlock_writer_lock_noirq(&parent->children_lock, &childlock); - list_del(&child->ptraced_siblings_list); - mcs_rwlock_writer_unlock_noirq(&parent->children_lock, &childlock); - } - mcs_rwlock_writer_lock_noirq(&child->update_lock, &updatelock); - child->ptrace = 0; - child->parent = pid1; - child->ppid_parent = pid1; - mcs_rwlock_writer_lock_noirq(&pid1->children_lock, &childlock); - list_add_tail(&child->siblings_list, &pid1->children_list); - mcs_rwlock_writer_unlock_noirq(&pid1->children_lock, &childlock); - mcs_rwlock_writer_unlock_noirq(&child->update_lock, &updatelock); - release_process(child); - } - else - mcs_rwlock_writer_unlock_noirq(&proc->children_lock, &lock); - - if (!(org_options & WNOWAIT) && - (options & WNOWAIT)) { - struct process *parent; - - child->ptrace = 0; - parent = child->ppid_parent; - mcs_rwlock_writer_lock_noirq(&proc->children_lock, &lock); - list_del(&child->siblings_list); - mcs_rwlock_writer_unlock_noirq(&proc->children_lock, &lock); - mcs_rwlock_writer_lock_noirq(&parent->children_lock, &lock); - list_del(&child->ptraced_siblings_list); - list_add_tail(&child->siblings_list, &parent->children_list); - child->parent = parent; - mcs_rwlock_writer_unlock_noirq(&parent->children_lock, &lock); - - finalize_process(child); - } - - goto out_found; - } - - if(!(child->ptrace & PT_TRACED) && - (child->signal_flags & SIGNAL_STOP_STOPPED) && - (options & WUNTRACED)) { - /* Find main thread of process if pid == -1 */ - if (pid == -1) - c_thread = find_thread_of_process(child, child->pid); - /* Not ptraced and in stopped state and WUNTRACED is specified */ - ret = wait_stopped(thread, child, c_thread, status, options); - if(!(options & WNOWAIT)){ - child->signal_flags &= ~SIGNAL_STOP_STOPPED; - } - mcs_rwlock_writer_unlock_noirq(&thread->proc->children_lock, &lock); - goto out_found; - } - - if((child->ptrace & PT_TRACED) && - (child->status & (PS_STOPPED | PS_TRACED))) { - /* Find main thread of process if pid == -1 */ - if (pid == -1) - c_thread = find_thread_of_process(child, child->pid); - ret = wait_stopped(thread, child, c_thread, status, options); - if(c_thread && ret == child->pid){ - /* Are we looking for a specific thread? */ - if (pid == c_thread->tid) { - ret = c_thread->tid; - } - if(!(options & WNOWAIT)){ - child->signal_flags &= ~SIGNAL_STOP_STOPPED; - } - mcs_rwlock_writer_unlock_noirq(&thread->proc->children_lock, &lock); - goto out_found; - } - } - - if((child->signal_flags & SIGNAL_STOP_CONTINUED) && - (options & WCONTINUED)) { - ret = wait_continued(thread, child, status, options); - if(!(options & WNOWAIT)){ - child->signal_flags &= ~SIGNAL_STOP_CONTINUED; - } - mcs_rwlock_writer_unlock_noirq(&thread->proc->children_lock, &lock); - goto out_found; - } + } + if ((pid == -1 || pid > 0) && + (options & (__WCLONE | __WALL))) { + if ((ret = wait_thread(pid, status, options, rusage, &empty))) { + goto out_found; } - } if (empty) { - list_for_each_entry_safe(child, next, - &proc->ptraced_children_list, - ptraced_siblings_list) { - if ((pid < 0 && -pid == child->pgid) || - pid == -1 || - (pid == 0 && pgid == child->pgid) || - (pid > 0 && pid == child->pid) || - c_thread != NULL) { - empty = 0; - break; - } - } - if (empty) { - ret = -ECHILD; - goto out_notfound; - } + ret = -ECHILD; + goto out_notfound; } /* Don't sleep if WNOHANG requested */ @@ -782,12 +1038,7 @@ do_wait(int pid, int *status, int options, void *rusage) /* Sleep */ dkprintf("wait4,sleeping\n"); -#ifndef POSTK_DEBUG_TEMP_FIX_65 /* wait4() lose infomation fix. */ - waitq_init_entry(&waitpid_wqe, thread); - waitq_prepare_to_wait(&thread->proc->waitpid_q, &waitpid_wqe, PS_INTERRUPTIBLE); -#endif /* !POSTK_DEBUG_TEMP_FIX_65 */ - mcs_rwlock_writer_unlock_noirq(&thread->proc->children_lock, &lock); if(hassigpending(thread)){ waitq_finish_wait(&thread->proc->waitpid_q, &waitpid_wqe); return -EINTR; @@ -801,16 +1052,13 @@ do_wait(int pid, int *status, int options, void *rusage) goto rescan; exit: -#ifdef POSTK_DEBUG_TEMP_FIX_65 /* wait4() lose infomation fix. */ waitq_finish_wait(&thread->proc->waitpid_q, &waitpid_wqe); -#endif /* POSTK_DEBUG_TEMP_FIX_65 */ return ret; out_found: dkprintf("wait4,out_found\n"); goto exit; out_notfound: dkprintf("wait4,out_notfound\n"); - mcs_rwlock_writer_unlock_noirq(&thread->proc->children_lock, &lock); goto exit; } @@ -900,15 +1148,15 @@ void terminate_mcexec(int rc, int sig) struct process *proc = mythread->proc; struct syscall_request request IHK_DMA_ALIGN; - if ((old_exit_status = proc->exit_status) & 0x0000000100000000L) + if ((old_exit_status = proc->group_exit_status) & 0x0000000100000000L) return; exit_status = 0x0000000100000000L | ((rc & 0x00ff) << 8) | (sig & 0xff); - if (!__sync_bool_compare_and_swap(&proc->exit_status, + if (!__sync_bool_compare_and_swap(&proc->group_exit_status, old_exit_status, exit_status)) return; if (!proc->nohost) { request.number = __NR_exit_group; - request.args[0] = proc->exit_status; + request.args[0] = proc->group_exit_status; proc->nohost = 1; do_syscall(&request, ihk_mc_get_processor_id()); } @@ -964,6 +1212,8 @@ void terminate(int rc, int sig) int n; int *ids = NULL; int exit_status; + struct timespec ats; + int found; // sync perf info if (proc->monitoring_event) @@ -976,7 +1226,15 @@ void terminate(int rc, int sig) dkprintf("%s: PID: %d, TID: %d PS_EXITED already\n", __FUNCTION__, proc->pid, mythread->tid); preempt_disable(); + tsc_to_ts(mythread->user_tsc, &ats); + ts_add(&proc->utime, &ats); + tsc_to_ts(mythread->system_tsc, &ats); + ts_add(&proc->stime, &ats); + mythread->user_tsc = 0; + mythread->system_tsc = 0; mythread->status = PS_EXITED; + mythread->exit_status = proc->group_exit_status; + thread_exit_signal(mythread); mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); mcs_rwlock_writer_unlock_noirq(&proc->update_lock, &updatelock); release_thread(mythread); @@ -988,7 +1246,14 @@ void terminate(int rc, int sig) dkprintf("%s: PID: %d, TID: %d setting PS_EXITED\n", __FUNCTION__, proc->pid, mythread->tid); + tsc_to_ts(mythread->user_tsc, &ats); + ts_add(&proc->utime, &ats); + tsc_to_ts(mythread->system_tsc, &ats); + ts_add(&proc->stime, &ats); + mythread->user_tsc = 0; + mythread->system_tsc = 0; exit_status = ((rc & 0x00ff) << 8) | (sig & 0xff); + proc->group_exit_status = exit_status; mythread->exit_status = exit_status; proc->status = PS_EXITED; mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); @@ -1032,11 +1297,20 @@ void terminate(int rc, int sig) for (;;) { __mcs_rwlock_reader_lock(&proc->threads_lock, &lock); - if (list_empty(&proc->threads_list)) { - mcs_rwlock_reader_unlock(&proc->threads_lock, &lock); + found = 0; + list_for_each_entry(thread, &proc->threads_list, + siblings_list) { + if (thread->status != PS_EXITED && + thread->status != PS_ZOMBIE) { + found = 1; + break; + } + } + mcs_rwlock_reader_unlock(&proc->threads_lock, &lock); + if (!found) { break; } - __mcs_rwlock_reader_unlock(&proc->threads_lock, &lock); + /* We might be waiting for another thread on same CPU */ schedule(); } @@ -1052,35 +1326,31 @@ void terminate(int rc, int sig) kfree(proc->saved_cmdline); } - // check tracee and ptrace_detach - n = 0; - mcs_rwlock_reader_lock(&proc->children_lock, &lock); - list_for_each_entry(child, &proc->children_list, siblings_list) { - if (child->ptrace & PT_TRACED) - n++; - } + while (!list_empty(&proc->report_threads_list)) { + struct thread *thr; - if (n) { - ids = kmalloc(sizeof(int) * n, IHK_MC_AP_NOWAIT); - i = 0; + thr = list_first_entry(&proc->report_threads_list, + struct thread, report_siblings_list); + if (thr->ptrace) { + int release_flag = thr->proc == proc && + thr->termsig && + thr->termsig != SIGCHLD; - if (ids) { - list_for_each_entry(child, &proc->children_list, siblings_list) { - if (child->ptrace & PT_TRACED) { - ids[i] = child->pid; - i++; - } + if (release_flag) { + thr->termsig = 0; + } + ptrace_detach_thread(thr, 0); + if (release_flag) { + release_thread(thr); } } - } - mcs_rwlock_reader_unlock(&proc->children_lock, &lock); - - if (ids) { - for (i = 0; i < n; i++) { - ptrace_detach(ids[i], 0); + else { + mcs_rwlock_writer_lock(&proc->threads_lock, &lock); + list_del(&thr->report_siblings_list); + thr->report_proc = NULL; + mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); + release_thread(thr); } - kfree(ids); - ids = NULL; } if (!list_empty(&proc->children_list) || @@ -1973,7 +2243,7 @@ SYSCALL_DECLARE(gettid) extern void ptrace_report_signal(struct thread *thread, int sig); static int ptrace_report_exec(struct thread *thread) { - int ptrace = thread->proc->ptrace; + int ptrace = thread->ptrace; if (ptrace & (PT_TRACE_EXEC|PTRACE_O_TRACEEXEC)) { ihk_mc_kernel_context_t ctx; @@ -1990,7 +2260,7 @@ static int ptrace_report_exec(struct thread *thread) static void ptrace_syscall_event(struct thread *thread) { - int ptrace = thread->proc->ptrace; + int ptrace = thread->ptrace; if (ptrace & PT_TRACE_SYSCALL) { int sig = (SIGTRAP | ((ptrace & PTRACE_O_TRACESYSGOOD) ? 0x80 : 0)); @@ -2004,20 +2274,20 @@ static int ptrace_check_clone_event(struct thread *thread, int clone_flags) if (clone_flags & CLONE_VFORK) { /* vfork */ - if (thread->proc->ptrace & PTRACE_O_TRACEVFORK) { + if (thread->ptrace & PTRACE_O_TRACEVFORK) { event = PTRACE_EVENT_VFORK; } - if (thread->proc->ptrace & PTRACE_O_TRACEVFORKDONE) { + if (thread->ptrace & PTRACE_O_TRACEVFORKDONE) { event = PTRACE_EVENT_VFORK_DONE; } } else if ((clone_flags & CSIGNAL) == SIGCHLD) { /* fork */ - if (thread->proc->ptrace & PTRACE_O_TRACEFORK) { + if (thread->ptrace & PTRACE_O_TRACEFORK) { event = PTRACE_EVENT_FORK; } } else { /* clone */ - if (thread->proc->ptrace & PTRACE_O_TRACECLONE) { + if (thread->ptrace & PTRACE_O_TRACECLONE) { event = PTRACE_EVENT_CLONE; } } @@ -2025,6 +2295,56 @@ static int ptrace_check_clone_event(struct thread *thread, int clone_flags) return event; } +static int ptrace_attach_thread(struct thread *thread, struct process *proc) +{ + struct process *child; + struct process *parent; + struct mcs_rwlock_node_irqsave lock; + int error = 0; + + if (thread->report_proc) { + mcs_rwlock_writer_lock(&thread->report_proc->threads_lock, + &lock); + list_del(&thread->report_siblings_list); + mcs_rwlock_writer_unlock(&thread->report_proc->threads_lock, + &lock); + } + + mcs_rwlock_writer_lock(&proc->threads_lock, &lock); + list_add_tail(&thread->report_siblings_list, + &proc->report_threads_list); + thread->report_proc = proc; + mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); + + child = thread->proc; + if (thread == child->main_thread) { + parent = child->parent; + dkprintf("ptrace_attach() parent->pid=%d\n", parent->pid); + mcs_rwlock_writer_lock(&parent->children_lock, &lock); + list_del(&child->siblings_list); + list_add_tail(&child->ptraced_siblings_list, + &parent->ptraced_children_list); + mcs_rwlock_writer_unlock(&parent->children_lock, &lock); + + mcs_rwlock_writer_lock(&proc->children_lock, &lock); + list_add_tail(&child->siblings_list, &proc->children_list); + child->parent = proc; + mcs_rwlock_writer_unlock(&proc->children_lock, &lock); + } + + if (thread->ptrace_debugreg == NULL) { + error = alloc_debugreg(thread); + if (error < 0) { + goto out; + } + } + hold_thread(thread); + + clear_single_step(thread); +out: + return error; +} + static int ptrace_report_clone(struct thread *thread, struct thread *new, int event) { dkprintf("ptrace_report_clone,enter\n"); @@ -2041,8 +2361,8 @@ static int ptrace_report_clone(struct thread *thread, struct thread *new, int ev /* Transition process state */ thread->proc->status = PS_TRACED; thread->status = PS_TRACED; - thread->proc->ptrace_eventmsg = new->tid; - thread->proc->ptrace &= ~PT_TRACE_SYSCALL; /** ??? **/ + thread->ptrace_eventmsg = new->tid; + thread->ptrace &= ~PT_TRACE_SYSCALL; parent_pid = thread->proc->parent->pid; mcs_rwlock_writer_unlock_noirq(&thread->proc->update_lock, &lock); @@ -2051,25 +2371,10 @@ static int ptrace_report_clone(struct thread *thread, struct thread *new, int ev mcs_rwlock_writer_lock_noirq(&new->proc->update_lock, &updatelock); /* set ptrace features to new process */ - new->proc->ptrace = thread->proc->ptrace; - if (event != PTRACE_EVENT_CLONE) { - new->proc->ppid_parent = new->proc->parent; /* maybe proc */ - } + new->ptrace = thread->ptrace; - if ((new->proc->ptrace & PT_TRACED) && new->ptrace_debugreg == NULL) { - alloc_debugreg(new); - } + ptrace_attach_thread(new, thread->proc->parent); - if (event != PTRACE_EVENT_CLONE) { - mcs_rwlock_writer_lock_noirq(&new->proc->parent->children_lock, &lock); - list_del(&new->proc->siblings_list); - list_add_tail(&new->proc->ptraced_siblings_list, &new->proc->parent->ptraced_children_list); - mcs_rwlock_writer_unlock_noirq(&new->proc->parent->children_lock, &lock); - new->proc->parent = thread->proc->parent; /* new ptracing parent */ - mcs_rwlock_writer_lock_noirq(&new->proc->parent->children_lock, &lock); - list_add_tail(&new->proc->siblings_list, &new->proc->parent->children_list); - mcs_rwlock_writer_unlock_noirq(&new->proc->parent->children_lock, &lock); - } /* trace and SIGSTOP */ new->exit_status = SIGSTOP; new->proc->status = PS_TRACED; @@ -2225,7 +2530,7 @@ SYSCALL_DECLARE(execve) goto end; } - if (thread->proc->ptrace) { + if (thread->ptrace) { ihk_mc_syscall_ret(ctx) = 0; ptrace_syscall_event(thread); } @@ -2590,7 +2895,7 @@ retry_tid: chain_process(newproc); } - if (oldproc->ptrace) { + if (old->ptrace) { ptrace_event = ptrace_check_clone_event(old, clone_flags); if (ptrace_event) { ptrace_report_clone(old, new, ptrace_event); @@ -2608,6 +2913,17 @@ retry_tid: request1.args[1] = new->tid; do_syscall(&request1, ihk_mc_get_processor_id()); } + else if (termsig && termsig != SIGCHLD) { + struct mcs_rwlock_node_irqsave lock; + + mcs_rwlock_writer_lock(&oldproc->threads_lock, &lock); + new->termsig = termsig; + new->report_proc = oldproc; + list_add_tail(&new->report_siblings_list, + &oldproc->report_threads_list); + mcs_rwlock_writer_unlock(&oldproc->threads_lock, &lock); + hold_thread(new); + } runq_add_thread(new, cpuid); @@ -5457,25 +5773,10 @@ do_exit(int code) int nproc; int exit_status = (code >> 8) & 255; int sig = code & 255; + struct timespec ats; dkprintf("sys_exit,pid=%d\n", proc->pid); - mcs_rwlock_reader_lock(&proc->threads_lock, &lock); - nproc = 0; - list_for_each_entry(child, &proc->threads_list, siblings_list){ - nproc++; - } - mcs_rwlock_reader_unlock(&proc->threads_lock, &lock); - - if(nproc == 1){ // process has only one thread - terminate(exit_status, sig); - return; - } - -#ifdef DCFA_KMOD - do_mod_exit((int)ihk_mc_syscall_arg0(ctx)); -#endif - /* XXX: for if all threads issued the exit(2) rather than exit_group(2), * exit(2) also should delegate. */ @@ -5489,16 +5790,42 @@ do_exit(int code) barrier(); futex((uint32_t *)thread->clear_child_tid, FUTEX_WAKE, 1, 0, NULL, 0, 0, 1, NULL); + thread->clear_child_tid = NULL; } - mcs_rwlock_writer_lock(&proc->threads_lock, &lock); + mcs_rwlock_reader_lock(&proc->threads_lock, &lock); + nproc = 0; + list_for_each_entry(child, &proc->threads_list, siblings_list) { + if (child->status != PS_EXITED && + child->status != PS_ZOMBIE) + nproc++; + } + + if (nproc == 1) { // process has only one thread + mcs_rwlock_reader_unlock(&proc->threads_lock, &lock); + terminate(exit_status, sig); + return; + } + +#ifdef DCFA_KMOD + do_mod_exit((int)ihk_mc_syscall_arg0(ctx)); +#endif + if(proc->status == PS_EXITED){ mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); terminate(exit_status, 0); return; } preempt_disable(); + thread->exit_status = code; thread->status = PS_EXITED; + tsc_to_ts(thread->user_tsc, &ats); + ts_add(&proc->utime, &ats); + tsc_to_ts(thread->system_tsc, &ats); + ts_add(&proc->stime, &ats); + thread->user_tsc = 0; + thread->system_tsc = 0; + thread_exit_signal(thread); sync_child_event(thread->proc->monitoring_event); mcs_rwlock_writer_unlock(&proc->threads_lock, &lock); release_thread(thread); @@ -5511,7 +5838,7 @@ do_exit(int code) SYSCALL_DECLARE(exit) { - int exit_status = (int)ihk_mc_syscall_arg0(ctx); + int exit_status = ((int)ihk_mc_syscall_arg0(ctx)) & 255; do_exit(exit_status << 8); return 0; @@ -5714,7 +6041,6 @@ SYSCALL_DECLARE(getrusage) } extern int ptrace_traceme(void); -extern void clear_single_step(struct thread *thread); extern void set_single_step(struct thread *thread); static int ptrace_wakeup_sig(int pid, long request, long data) { @@ -5725,13 +6051,11 @@ static int ptrace_wakeup_sig(int pid, long request, long data) { struct mcs_rwlock_node_irqsave lock; struct thread *thread = cpu_local_var(current); - child = find_thread(pid, pid, &lock); + child = find_thread(pid, pid); if (!child) { error = -ESRCH; goto out; } - hold_thread(child); - thread_unlock(child, &lock); if (data > 64 || data < 0) { error = -EINVAL; @@ -5754,9 +6078,9 @@ static int ptrace_wakeup_sig(int pid, long request, long data) { set_single_step(child); } mcs_rwlock_writer_lock(&child->proc->update_lock, &lock); - child->proc->ptrace &= ~PT_TRACE_SYSCALL; + child->ptrace &= ~PT_TRACE_SYSCALL; if (request == PTRACE_SYSCALL) { - child->proc->ptrace |= PT_TRACE_SYSCALL; + child->ptrace |= PT_TRACE_SYSCALL; } mcs_rwlock_writer_unlock(&child->proc->update_lock, &lock); if(data != 0 && data != SIGSTOP) { @@ -5792,7 +6116,7 @@ static int ptrace_wakeup_sig(int pid, long request, long data) { sched_wakeup_thread(child, PS_TRACED | PS_STOPPED); out: if(child) - release_thread(child); + thread_unlock(child); return error; } @@ -5803,17 +6127,16 @@ static long ptrace_pokeuser(int pid, long addr, long data) { long rc = -EIO; struct thread *child; - struct mcs_rwlock_node_irqsave lock; if(addr > sizeof(struct user) - 8 || addr < 0) return -EFAULT; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) return -ESRCH; if(child->status & (PS_STOPPED | PS_TRACED)){ rc = ptrace_write_user(child, addr, (unsigned long)data); } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -5822,12 +6145,11 @@ static long ptrace_peekuser(int pid, long addr, long data) { long rc = -EIO; struct thread *child; - struct mcs_rwlock_node_irqsave lock; unsigned long *p = (unsigned long *)data; if(addr > sizeof(struct user) - 8|| addr < 0) return -EFAULT; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) return -ESRCH; if(child->status & (PS_STOPPED | PS_TRACED)){ @@ -5837,7 +6159,7 @@ static long ptrace_peekuser(int pid, long addr, long data) rc = copy_to_user(p, (char *)&value, sizeof(value)); } } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -5847,9 +6169,8 @@ static long ptrace_getregs(int pid, long data) struct user_regs_struct *regs = (struct user_regs_struct *)data; long rc = -EIO; struct thread *child; - struct mcs_rwlock_node_irqsave lock; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) return -ESRCH; if(child->status & (PS_STOPPED | PS_TRACED)){ @@ -5867,7 +6188,7 @@ static long ptrace_getregs(int pid, long data) rc = copy_to_user(regs, &user_regs, sizeof(struct user_regs_struct)); } } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -5877,9 +6198,8 @@ static long ptrace_setregs(int pid, long data) struct user_regs_struct *regs = (struct user_regs_struct *)data; long rc = -EIO; struct thread *child; - struct mcs_rwlock_node_irqsave lock; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) return -ESRCH; if(child->status & (PS_STOPPED | PS_TRACED)){ @@ -5898,7 +6218,7 @@ static long ptrace_setregs(int pid, long data) } } } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -5910,15 +6230,14 @@ static long ptrace_getfpregs(int pid, long data) { long rc = -EIO; struct thread *child; - struct mcs_rwlock_node_irqsave lock; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) return -ESRCH; if(child->status & (PS_STOPPED | PS_TRACED)){ rc = ptrace_read_fpregs(child, (void *)data); } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -5927,15 +6246,14 @@ static long ptrace_setfpregs(int pid, long data) { long rc = -EIO; struct thread *child; - struct mcs_rwlock_node_irqsave lock; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) return -ESRCH; if(child->status & (PS_STOPPED | PS_TRACED)){ rc = ptrace_write_fpregs(child, (void *)data); } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -5947,9 +6265,8 @@ static long ptrace_getregset(int pid, long type, long data) { long rc = -EIO; struct thread *child; - struct mcs_rwlock_node_irqsave lock; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) return -ESRCH; if(child->status & (PS_STOPPED | PS_TRACED)){ @@ -5964,7 +6281,7 @@ static long ptrace_getregset(int pid, long type, long data) &iov.iov_len, sizeof(iov.iov_len)); } } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -5973,9 +6290,8 @@ static long ptrace_setregset(int pid, long type, long data) { long rc = -EIO; struct thread *child; - struct mcs_rwlock_node_irqsave lock; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) return -ESRCH; if(child->status & (PS_STOPPED | PS_TRACED)){ @@ -5990,7 +6306,7 @@ static long ptrace_setregset(int pid, long type, long data) &iov.iov_len, sizeof(iov.iov_len)); } } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -5999,10 +6315,9 @@ static long ptrace_peektext(int pid, long addr, long data) { long rc = -EIO; struct thread *child; - struct mcs_rwlock_node_irqsave lock; unsigned long *p = (unsigned long *)data; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) return -ESRCH; if(child->status & (PS_STOPPED | PS_TRACED)){ @@ -6014,7 +6329,7 @@ static long ptrace_peektext(int pid, long addr, long data) rc = copy_to_user(p, &value, sizeof(value)); } } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -6023,9 +6338,8 @@ static long ptrace_poketext(int pid, long addr, long data) { long rc = -EIO; struct thread *child; - struct mcs_rwlock_node_irqsave lock; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) return -ESRCH; if(child->status & (PS_STOPPED | PS_TRACED)){ @@ -6034,7 +6348,7 @@ static long ptrace_poketext(int pid, long addr, long data) dkprintf("ptrace_poketext: bad address 0x%llx\n", addr); } } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -6043,7 +6357,6 @@ static int ptrace_setoptions(int pid, int flags) { int ret; struct thread *child; - struct mcs_rwlock_node_irqsave lock; /* Only supported options are enabled. * Following options are pretended to be supported for the time being: @@ -6065,19 +6378,19 @@ static int ptrace_setoptions(int pid, int flags) goto out; } - child = find_thread(pid, pid, &lock); - if (!child || !child->proc || !(child->proc->ptrace & PT_TRACED)) { + child = find_thread(0, pid); + if (!child || !child->proc || !(child->ptrace & PT_TRACED)) { ret = -ESRCH; goto unlockout; } - child->proc->ptrace &= ~PTRACE_O_MASK; /* PT_TRACE_EXEC remains */ - child->proc->ptrace |= flags; + child->ptrace &= ~PTRACE_O_MASK; /* PT_TRACE_EXEC remains */ + child->ptrace |= flags; ret = 0; unlockout: if(child) - thread_unlock(child, &lock); + thread_unlock(child); out: return ret; } @@ -6088,78 +6401,37 @@ static int ptrace_attach(int pid) struct thread *thread; struct thread *mythread = cpu_local_var(current); struct process *proc = mythread->proc; - struct process *child; - struct process *parent; - struct mcs_rwlock_node_irqsave lock; - struct mcs_rwlock_node childlock; - struct mcs_rwlock_node updatelock; struct siginfo info; - thread = find_thread(pid, pid, &lock); + thread = find_thread(0, pid); if (!thread) { error = -ESRCH; goto out; } if (proc->pid == pid) { - thread_unlock(thread, &lock); + thread_unlock(thread); error = -EPERM; goto out; } - child = thread->proc; - dkprintf("ptrace_attach(): pid requested:%d, thread->tid:%d, thread->proc->pid=%d, thread->proc->parent=%p\n", pid, thread->tid, thread->proc->pid, thread->proc->parent); - - mcs_rwlock_writer_lock_noirq(&child->update_lock, &updatelock); - - /* Only for the first thread of a process XXX: fix this */ - if (thread->tid == child->pid) { - if (thread->proc->ptrace & PT_TRACED) { - mcs_rwlock_writer_unlock_noirq(&child->update_lock, &updatelock); - thread_unlock(thread, &lock); - dkprintf("ptrace_attach: -EPERM\n"); - error = -EPERM; - goto out; - } + if ((thread->ptrace & PT_TRACED) || + thread->proc == proc) { + thread_unlock(thread); + error = -EPERM; + goto out; } - parent = child->parent; - dkprintf("ptrace_attach() parent->pid=%d\n", parent->pid); + thread->ptrace = PT_TRACED | PT_TRACE_EXEC; + error = ptrace_attach_thread(thread, proc); - mcs_rwlock_writer_lock_noirq(&parent->children_lock, &childlock); - list_del(&child->siblings_list); - list_add_tail(&child->ptraced_siblings_list, &parent->ptraced_children_list); - mcs_rwlock_writer_unlock_noirq(&parent->children_lock, &childlock); - - mcs_rwlock_writer_lock_noirq(&proc->children_lock, &childlock); - list_add_tail(&child->siblings_list, &proc->children_list); - child->parent = proc; - mcs_rwlock_writer_unlock_noirq(&proc->children_lock, &childlock); - - child->ptrace = PT_TRACED | PT_TRACE_EXEC; - - mcs_rwlock_writer_unlock_noirq(&thread->proc->update_lock, &updatelock); - - if (thread->ptrace_debugreg == NULL) { - error = alloc_debugreg(thread); - if (error < 0) { - thread_unlock(thread, &lock); - goto out; - } - } - - clear_single_step(thread); - - thread_unlock(thread, &lock); + thread_unlock(thread); memset(&info, '\0', sizeof info); info.si_signo = SIGSTOP; info.si_code = SI_USER; info._sifields._kill.si_pid = proc->pid; error = do_kill(mythread, -1, pid, SIGSTOP, &info, 2); - if (error < 0) { - goto out; - } out: dkprintf("ptrace_attach,returning,error=%d\n", error); @@ -6173,67 +6445,26 @@ int ptrace_detach(int pid, int data) struct thread *thread; struct thread *mythread = cpu_local_var(current); struct process *proc = mythread->proc;; - struct process *child; - struct process *parent; - struct mcs_rwlock_node_irqsave lock; - struct mcs_rwlock_node childlock; - struct mcs_rwlock_node updatelock; - struct siginfo info; if (data > 64 || data < 0) { return -EIO; } - thread = find_thread(pid, pid, &lock); + thread = find_thread(0, pid); if (!thread) { error = -ESRCH; goto out; } - child = thread->proc; - mcs_rwlock_writer_lock_noirq(&child->update_lock, &updatelock); - parent = child->ppid_parent; - if (!(child->ptrace & PT_TRACED) || child->parent != proc) { - mcs_rwlock_writer_unlock_noirq(&child->update_lock, &updatelock); - thread_unlock(thread, &lock); + if (!(thread->ptrace & PT_TRACED) || thread->report_proc != proc) { + thread_unlock(thread); error = -ESRCH; goto out; } - mcs_rwlock_writer_unlock_noirq(&child->update_lock, &updatelock); - mcs_rwlock_writer_lock_noirq(&proc->children_lock, &childlock); - list_del(&child->siblings_list); - mcs_rwlock_writer_unlock_noirq(&proc->children_lock, &childlock); + ptrace_detach_thread(thread, data); - mcs_rwlock_writer_lock_noirq(&parent->children_lock, &childlock); - list_del(&child->ptraced_siblings_list); - list_add_tail(&child->siblings_list, &parent->children_list); - child->parent = parent; - mcs_rwlock_writer_unlock_noirq(&parent->children_lock, &childlock); - - child->ptrace = 0; - - if (thread->ptrace_debugreg) { - kfree(thread->ptrace_debugreg); - thread->ptrace_debugreg = NULL; - } - - clear_single_step(thread); - - thread_unlock(thread, &lock); - - if (data != 0) { - memset(&info, '\0', sizeof info); - info.si_signo = data; - info.si_code = SI_USER; - info._sifields._kill.si_pid = proc->pid; - error = do_kill(mythread, pid, -1, data, &info, 1); - if (error < 0) { - goto out; - } - } - - sched_wakeup_thread(thread, PS_TRACED | PS_STOPPED); + thread_unlock(thread); out: return error; } @@ -6243,20 +6474,21 @@ static long ptrace_geteventmsg(int pid, long data) unsigned long *msg_p = (unsigned long *)data; long rc = -ESRCH; struct thread *child; - struct mcs_rwlock_node_irqsave lock; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) { return -ESRCH; } if(child->status & (PS_STOPPED | PS_TRACED)){ - if (copy_to_user(msg_p, &child->proc->ptrace_eventmsg, sizeof(*msg_p))) { + if (copy_to_user(msg_p, &child->ptrace_eventmsg, + sizeof(*msg_p))) { rc = -EFAULT; - } else { + } + else { rc = 0; } } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -6265,10 +6497,9 @@ static long ptrace_getsiginfo(int pid, siginfo_t *data) { struct thread *child; - struct mcs_rwlock_node_irqsave lock; int rc = 0; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) { return -ESRCH; } @@ -6284,7 +6515,7 @@ ptrace_getsiginfo(int pid, siginfo_t *data) else { rc = -ESRCH; } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -6292,10 +6523,9 @@ static long ptrace_setsiginfo(int pid, siginfo_t *data) { struct thread *child; - struct mcs_rwlock_node_irqsave lock; int rc = 0; - child = find_thread(pid, pid, &lock); + child = find_thread(0, pid); if (!child) { return -ESRCH; } @@ -6322,7 +6552,7 @@ ptrace_setsiginfo(int pid, siginfo_t *data) } } } - thread_unlock(child, &lock); + thread_unlock(child); return rc; } @@ -6467,7 +6697,6 @@ SYSCALL_DECLARE(sched_setparam) struct sched_param *uparam = (struct sched_param *)ihk_mc_syscall_arg1(ctx); struct sched_param param; struct thread *thread = cpu_local_var(current); - struct mcs_rwlock_node_irqsave lock; struct syscall_request request1 IHK_DMA_ALIGN; int other_thread = 0; @@ -6482,11 +6711,11 @@ SYSCALL_DECLARE(sched_setparam) if (thread->proc->pid != pid) { other_thread = 1; - thread = find_thread(pid, pid, &lock); + thread = find_thread(0, pid); if (!thread) { return -ESRCH; } - thread_unlock(thread, &lock); + thread_unlock(thread); /* Ask Linux about ownership.. */ request1.number = __NR_sched_setparam; @@ -6505,14 +6734,14 @@ SYSCALL_DECLARE(sched_setparam) } if (other_thread) { - thread = find_thread(pid, pid, &lock); + thread = find_thread(0, pid); if (!thread) { return -ESRCH; } } retval = setscheduler(thread, thread->sched_policy, ¶m); if (other_thread) { - thread_unlock(thread, &lock); + thread_unlock(thread); } return retval; } @@ -6523,7 +6752,6 @@ SYSCALL_DECLARE(sched_getparam) int pid = (int)ihk_mc_syscall_arg0(ctx); struct sched_param *param = (struct sched_param *)ihk_mc_syscall_arg1(ctx); struct thread *thread = cpu_local_var(current); - struct mcs_rwlock_node_irqsave lock; if (!param || pid < 0) { return -EINVAL; @@ -6533,11 +6761,11 @@ SYSCALL_DECLARE(sched_getparam) pid = thread->proc->pid; if (thread->proc->pid != pid) { - thread = find_thread(pid, pid, &lock); + thread = find_thread(0, pid); if (!thread) { return -ESRCH; } - thread_unlock(thread, &lock); + thread_unlock(thread); } retval = copy_to_user(param, &thread->sched_param, sizeof(*param)) ? -EFAULT : 0; @@ -6553,7 +6781,6 @@ SYSCALL_DECLARE(sched_setscheduler) struct sched_param *uparam = (struct sched_param *)ihk_mc_syscall_arg2(ctx); struct sched_param param; struct thread *thread = cpu_local_var(current); - struct mcs_rwlock_node_irqsave lock; struct syscall_request request1 IHK_DMA_ALIGN; @@ -6589,11 +6816,11 @@ SYSCALL_DECLARE(sched_setscheduler) pid = thread->proc->pid; if (thread->proc->pid != pid) { - thread = find_thread(pid, pid, &lock); + thread = find_thread(0, pid); if (!thread) { return -ESRCH; } - thread_unlock(thread, &lock); + thread_unlock(thread); /* Ask Linux about ownership.. */ request1.number = __NR_sched_setparam; @@ -6613,7 +6840,6 @@ SYSCALL_DECLARE(sched_getscheduler) { int pid = (int)ihk_mc_syscall_arg0(ctx); struct thread *thread = cpu_local_var(current); - struct mcs_rwlock_node_irqsave lock; if (pid < 0) { return -EINVAL; @@ -6623,11 +6849,11 @@ SYSCALL_DECLARE(sched_getscheduler) pid = thread->proc->pid; if (thread->proc->pid != pid) { - thread = find_thread(pid, pid, &lock); + thread = find_thread(0, pid); if (!thread) { return -ESRCH; } - thread_unlock(thread, &lock); + thread_unlock(thread); } return thread->sched_policy; @@ -6678,7 +6904,6 @@ SYSCALL_DECLARE(sched_rr_get_interval) struct timespec *utime = (struct timespec *)ihk_mc_syscall_arg1(ctx); struct timespec t; struct thread *thread = cpu_local_var(current); - struct mcs_rwlock_node_irqsave lock; int retval = 0; if (pid < 0) @@ -6688,11 +6913,11 @@ SYSCALL_DECLARE(sched_rr_get_interval) pid = thread->proc->pid; if (thread->proc->pid != pid) { - thread = find_thread(pid, pid, &lock); + thread = find_thread(0, pid); if (!thread) { return -ESRCH; } - thread_unlock(thread, &lock); + thread_unlock(thread); } t.tv_sec = 0; @@ -6741,10 +6966,9 @@ SYSCALL_DECLARE(sched_setaffinity) hold_thread(thread); } else { - struct mcs_rwlock_node_irqsave lock; struct thread *mythread = cpu_local_var(current); - thread = find_thread(0, tid, &lock); + thread = find_thread(0, tid); if (!thread) return -ESRCH; @@ -6752,12 +6976,12 @@ SYSCALL_DECLARE(sched_setaffinity) if (mythread->proc->euid != 0 && mythread->proc->euid != thread->proc->ruid && mythread->proc->euid != thread->proc->euid) { - thread_unlock(thread, &lock); + thread_unlock(thread); return -EPERM; } hold_thread(thread); - thread_unlock(thread, &lock); + thread_unlock(thread); cpu_id = thread->cpu_id; } @@ -6819,20 +7043,19 @@ SYSCALL_DECLARE(sched_getaffinity) hold_thread(thread); } else{ - struct mcs_rwlock_node_irqsave lock; struct thread *mythread = cpu_local_var(current); - thread = find_thread(0, tid, &lock); + thread = find_thread(0, tid); if(!thread) return -ESRCH; if(mythread->proc->euid != 0 && mythread->proc->euid != thread->proc->ruid && mythread->proc->euid != thread->proc->euid){ - thread_unlock(thread, &lock); + thread_unlock(thread); return -EPERM; } hold_thread(thread); - thread_unlock(thread, &lock); + thread_unlock(thread); } ret = copy_to_user(u_cpu_set, &thread->cpu_set, len); @@ -9450,7 +9673,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx) cpu_enable_interrupt(); - if (cpu_local_var(current)->proc->ptrace) { + if (cpu_local_var(current)->ptrace) { ihk_mc_syscall_ret(ctx) = -ENOSYS; ptrace_syscall_event(cpu_local_var(current)); num = ihk_mc_syscall_number(ctx); @@ -9497,7 +9720,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx) l = syscall_generic_forwarding(num, ctx); } - if (cpu_local_var(current)->proc->ptrace) { + if (cpu_local_var(current)->ptrace) { ihk_mc_syscall_ret(ctx) = l; ptrace_syscall_event(cpu_local_var(current)); l = ihk_mc_syscall_ret(ctx); diff --git a/test/issues/771+1179+1143/C771.sh b/test/issues/771+1179+1143/C771.sh new file mode 100755 index 00000000..95c17b3b --- /dev/null +++ b/test/issues/771+1179+1143/C771.sh @@ -0,0 +1,117 @@ +#!/bin/sh +USELTP=1 +USEOSTEST=1 +GDBBUILDDIR="$HOME/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu" + +. ../../common.sh + +#=============================================================================== +expect -c " +set timeout 60 +spawn "$MCEXEC" gdb ./C771T001 +expect \"(gdb)\" +send -- \"b thr\n\" + +expect \"(gdb)\" +send -- \"r\n\" + +expect \"(gdb)\" +send -- \"info threads\n\" + +expect \"(gdb)\" +send -- \"bt\n\" + +expect \"(gdb)\" +send -- \"n\n\" + +expect \"(gdb)\" +send -- \"thread 1\n\" + +expect \"(gdb)\" +send -- \"bt\n\" + +expect \"(gdb)\" +send -- \"thread 2\n\" + +expect \"(gdb)\" +send -- \"c\n\" + +expect \"(gdb)\" +send -- \"q\n\" + +expect eof +" | tee C771T001.txt + +echo checking result... +awk -f C771T001.awk C771T001.txt +rm -f C771T001.txt + +sleep 5 +"$SBIN"/ihkosctl 0 clear_kmsg +"$SBIN"/ihkosctl 0 ioctl 40000000 1 +"$SBIN"/ihkosctl 0 ioctl 40000000 2 +"$SBIN"/ihkosctl 0 kmsg | tee C771T012.txt +if grep ' 0 processes are found' C771T012.txt > /dev/null 2>&1 && \ + grep ' 0 threads are found' C771T012.txt > /dev/null 2>&1; then + echo "*** C771T012 no processes and threads found OK" +else + echo "*** C771T012 processes and threads are exists NG" +fi +rm -f C771T012.txt + +#=============================================================================== +if [ -x "$GDBBUILDDIR/gdb/testsuite/gdb.threads/bp_in_thread" ] ;then + if [ -d gdb-result ]; then + rm -rf gdb-result + fi + mkdir -p gdb-result/raw/linux gdb-result/raw/mck + mkdir -p gdb-result/linux gdb-result/mck + export gdb_builddir="$GDBBUILDDIR" + export MCEXEC + + id=13 + while read line; do + cat=`echo $line | awk '{print $1}'` + exp=`echo $line | awk '{print $2}'` + ./gdb_test.sh $cat $exp 2>&1 | tee $cat-$exp.txt + if grep "【PASS】" $cat-$exp.txt > /dev/null 2>&1; then + echo "*** C771T0$id: $cat-$exp OK" + else + echo "*** C771T0$id: $cat-$exp NG" + fi + rm -f $cat-$exp.txt + id=`expr $id + 1` + done < gdblist +else + echo '***' No GDB build dir. skip GDB tests >&2 +fi + +#=============================================================================== +$MCEXEC ./C771T033 + +#=============================================================================== +$MCEXEC "$TESTMCK" -s ptrace -n 19 | tee C771T036.txt +if grep "RESULT: ok" C771T036.txt > /dev/null 2>&1; then + echo "*** C771T036: ostest-ptrace-19 OK" +else + echo "*** C771T036: ostest-ptrace-19 NG" +fi +rm -f C771T036.txt + +#=============================================================================== +$MCEXEC ./C771T037 + +#=============================================================================== +id=43 +while read tp; do + sudo $MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt + ok=`grep TPASS $tp.txt | wc -l` + ng=`grep TFAIL $tp.txt | wc -l` + if [ $ng = 0 ]; then + echo "*** C771T0$id: $tp OK ($ok)" + else + echo "*** C771T0$id: $tp NG (ok=$ok ng=$ng)" + fi + rm -f $tp.txt + id=`expr $id + 1` +done < ltplist diff --git a/test/issues/771+1179+1143/C771.txt b/test/issues/771+1179+1143/C771.txt new file mode 100644 index 00000000..16a32d99 --- /dev/null +++ b/test/issues/771+1179+1143/C771.txt @@ -0,0 +1,627 @@ +Script started on Mon Sep 24 08:49:43 2018 +bash-4.2$ make test +gcc -g -Wall -o C771T001 C771T001.c -pthread +gcc -g -Wall -o C771T033 C771T033.c -pthread +gcc -g -Wall -o C771T037 C771T037.c -pthread +mcstop+release.sh ... done +mcreboot.sh -c 1-7,9-15,17-23,25-31 -m 10G@0,10G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24 ... done +spawn /home/shirasawa/wallaby11-smp-x86/issue771/mic/bin/mcexec gdb ./C771T001 +GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-94.el7 +Copyright (C) 2013 Free Software Foundation, Inc. +License GPLv3+: GNU GPL version 3 or later +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. Type "show copying" +and "show warranty" for details. +This GDB was configured as "x86_64-redhat-linux-gnu". +For bug reporting instructions, please see: +... +Reading symbols from /home/shirasawa/wallaby11-smp-x86/issue771/mckernel/test/issues/771+1179+1143/C771T001...done. +(gdb) b thr +Breakpoint 1 at 0x400989: file C771T001.c, line 20. +(gdb) r +Starting program: /home/shirasawa/wallaby11-smp-x86/issue771/mckernel/test/issues/771+1179+1143/./C771T001 +[Thread debugging using libthread_db enabled] +Using host libthread_db library "/lib64/libthread_db.so.1". +process start pid=5721 +[New Thread 0x2aaaad000700 (LWP 5750)] +pthread_create: 0 +[Switching to Thread 0x2aaaad000700 (LWP 5750)] + +Breakpoint 1, thr (arg=0x0) at C771T001.c:20 +20 fprintf(stderr, "thread start tid=%d\n", (int)syscall(SYS_gettid)); +Missing separate debuginfos, use: debuginfo-install glibc-2.17-222.el7.x86_64 libgcc-4.8.5-28.el7_5.1.x86_64 libgfortran-4.8.5-28.el7_5.1.x86_64 libquadmath-4.8.5-28.el7_5.1.x86_64 mpich-3.2-3.2-2.el7.x86_64 +(gdb) info threads + Id Target Id Frame +* 2 Thread 0x2aaaad000700 (LWP 5750) "exe" thr (arg=0x0) at C771T001.c:20 + 1 Thread 0x2aaaac735e80 (LWP 5721) "exe" 0x0000000000400b61 in main ( + argc=1, argv=0x547ffffffd08) at C771T001.c:52 +(gdb) bt +#0 thr (arg=0x0) at C771T001.c:20 +#1 0x00002aaaaae49e25 in start_thread () from /lib64/libpthread.so.0 +#2 0x00002aaaab15cbad in clone () from /lib64/libc.so.6 +(gdb) n +thread start tid=5750 +21 fflush(stderr); +(gdb) thread 1 +[Switching to thread 1 (Thread 0x2aaaac735e80 (LWP 5721))] +#0 0x0000000000400b61 in main (argc=1, argv=0x547ffffffd08) at C771T001.c:52 +52 while (!m); +(gdb) bt +#0 0x0000000000400b61 in main (argc=1, argv=0x547ffffffd08) at C771T001.c:52 +(gdb) thread 2 +[Switching to thread 2 (Thread 0x2aaaad000700 (LWP 5750))] +#0 thr (arg=0x0) at C771T001.c:21 +21 fflush(stderr); +(gdb) c +Continuing. +mmap m=0x2aaaad001000 errno=0 +update m=0x2aaaad001000 +update *m=1 +munmap rc=0, errno=0 +main done +[Thread 0x2aaaad000700 (LWP 5750) exited] +[Inferior 1 (process 5721) exited normally] +(gdb) q +checking result... +*** C771T001 gdb start OK +*** C771T002 breakpoint command OK +*** C771T003 run command OK +*** C771T004 info threads command OK +*** C771T005 backtrace command OK +*** C771T006 next command OK +*** C771T007 thread command OK +*** C771T008 thread command OK +*** C771T009 thread command OK +*** C771T010 continue command OK +*** C771T011 quit command OK +OK=11 NG=0 +[ 0]: 0 processes are found. +[ 0]: 0 threads are found. + +*** C771T012 no processes and threads found OK +======== a2-run ======== +【SAME】a2-run: Summary. +【SAME】a2-run : Log. +【PASS】a2-run +*** C771T013: base-a2-run OK +======== foll-fork ======== +【SAME】foll-fork: Summary. +【SAME】foll-fork : Log. +【PASS】foll-fork +*** C771T014: base-foll-fork OK +======== fork-detach ======== +【SAME】fork-detach: Summary. +【SAME】fork-detach : Log. +【PASS】fork-detach +*** C771T015: base-fork-detach OK +======== atomic-seq-threaded ======== +【DIFF】atomic-seq-threaded : Summary Difference --- +--- /home/shirasawa/wallaby11-smp-x86/issue771/mckernel/test/issues/771+1179+1143/gdb-result/linux/atomic-seq-threaded.sum 2018-09-24 08:52:39.889889082 +0900 ++++ /home/shirasawa/wallaby11-smp-x86/issue771/mckernel/test/issues/771+1179+1143/gdb-result/mck/atomic-seq-threaded.sum 2018-09-24 08:52:39.899889116 +0900 +@@ -11,5 +11,5 @@ + === gdb Summary === + + # of unsupported tests 2 +-/home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../../gdb/gdb version 7.6.1-110.el7.centos -nw -nx -data-directory /home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../data-directory ++/home/shirasawa/wallaby11-smp-x86/issue771/mckernel/test/issues/771+1179+1143/mcexec_gdb.sh version 7.6.1-94.el7 -nw -nx -data-directory /home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../data-directory + +【SAME】atomic-seq-threaded : Log. +【PASS】atomic-seq-threaded +*** C771T016: threads-atomic-seq-threaded OK +======== bp_in_thread ======== +【SAME】bp_in_thread: Summary. +【SAME】bp_in_thread : Log. +【PASS】bp_in_thread +*** C771T017: threads-bp_in_thread OK +======== bt-clone-stop ======== +【SAME】bt-clone-stop: Summary. +【SAME】bt-clone-stop : Log. +【PASS】bt-clone-stop +*** C771T018: threads-bt-clone-stop OK +======== corethreads ======== +【SAME】corethreads: Summary. +【SAME】corethreads : Log. +【PASS】corethreads +*** C771T019: threads-corethreads OK +======== dlopen-libpthread ======== +【SAME】dlopen-libpthread: Summary. +【SAME】dlopen-libpthread : Log. +【PASS】dlopen-libpthread +*** C771T020: threads-dlopen-libpthread OK +======== fork-child-threads ======== +【SAME】fork-child-threads: Summary. +【SAME】fork-child-threads : Log. +【PASS】fork-child-threads +*** C771T021: threads-fork-child-threads OK +======== killed ======== +【SAME】killed: Summary. +【SAME】killed : Log. +【PASS】killed +*** C771T022: threads-killed OK +======== pthread_cond_wait ======== +【SAME】pthread_cond_wait: Summary. +【SAME】pthread_cond_wait : Log. +【PASS】pthread_cond_wait +*** C771T023: threads-pthread_cond_wait OK +======== switch-threads ======== +【SAME】switch-threads: Summary. +【SAME】switch-threads : Log. +【PASS】switch-threads +*** C771T024: threads-switch-threads OK +======== thread-specific ======== +【SAME】thread-specific: Summary. +【SAME】thread-specific : Log. +【PASS】thread-specific +*** C771T025: threads-thread-specific OK +======== thread_check ======== +【SAME】thread_check: Summary. +【DIFF】thread_check : Log Difference --- +--- /home/shirasawa/wallaby11-smp-x86/issue771/mckernel/test/issues/771+1179+1143/gdb-result/linux/thread_check.log 2018-09-24 09:00:11.257427754 +0900 ++++ /home/shirasawa/wallaby11-smp-x86/issue771/mckernel/test/issues/771+1179+1143/gdb-result/mck/thread_check.log 2018-09-24 09:00:11.270427798 +0900 +@@ -13,4 +13,4 @@ + (gdb) PASS: gdb.threads/thread_check.exp: continue to tf + (gdb) PASS: gdb.threads/thread_check.exp: backtrace from thread function + (gdb) info breakpoints +-(gdb) Quitting /home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../../gdb/gdb -nw -nx -data-directory /home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../data-directory ++(gdb) Quitting mcexec_gdb.sh -nw -nx -data-directory /home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../data-directory +【PASS】thread_check +*** C771T026: threads-thread_check OK +======== thread_events ======== +【SAME】thread_events: Summary. +【DIFF】thread_events : Log Difference --- +--- /home/shirasawa/wallaby11-smp-x86/issue771/mckernel/test/issues/771+1179+1143/gdb-result/linux/thread_events.log 2018-09-24 09:01:01.132598675 +0900 ++++ /home/shirasawa/wallaby11-smp-x86/issue771/mckernel/test/issues/771+1179+1143/gdb-result/mck/thread_events.log 2018-09-24 09:01:01.141598706 +0900 +@@ -15,7 +15,7 @@ + (gdb) PASS: gdb.threads/thread_events.exp: continue to threadfunc with messages disabled + (gdb) PASS: gdb.threads/thread_events.exp: continue to after_join_func with messages disabled + (gdb) info breakpoints +-(gdb) Quitting /home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../../gdb/gdb -nw -nx -data-directory /home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../data-directory ++(gdb) Quitting mcexec_gdb.sh -nw -nx -data-directory /home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../data-directory + (gdb) GDB initialized. + (gdb) set width 0 + (gdb) set build-id-verbose 0 +@@ -33,4 +33,4 @@ + (gdb) PASS: gdb.threads/thread_events.exp: continue to threadfunc with messages enabled + (gdb) PASS: gdb.threads/thread_events.exp: continue to after_join_func with messages enabled + (gdb) info breakpoints +-(gdb) Quitting /home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../../gdb/gdb -nw -nx -data-directory /home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../data-directory ++(gdb) Quitting mcexec_gdb.sh -nw -nx -data-directory /home/shirasawa/rpmbuild/BUILD/gdb-7.6.1/build-x86_64-redhat-linux-gnu/gdb/testsuite/../data-directory +【PASS】thread_events +*** C771T027: threads-thread_events OK +======== threaded-exec ======== +【SAME】threaded-exec: Summary. +【SAME】threaded-exec : Log. +【PASS】threaded-exec +*** C771T028: threads-threaded-exec OK +======== threxit-hop-specific ======== +【SAME】threxit-hop-specific: Summary. +【SAME】threxit-hop-specific : Log. +【PASS】threxit-hop-specific +*** C771T029: threads-threxit-hop-specific OK +======== tls-nodebug ======== +【SAME】tls-nodebug: Summary. +【SAME】tls-nodebug : Log. +【PASS】tls-nodebug +*** C771T030: threads-tls-nodebug OK +======== tls-sepdebug ======== +【SAME】tls-sepdebug: Summary. +【SAME】tls-sepdebug : Log. +【PASS】tls-sepdebug +*** C771T031: threads-tls-sepdebug OK +======== tls-var ======== +【SAME】tls-var: Summary. +【SAME】tls-var : Log. +【PASS】tls-var +*** C771T032: threads-tls-var OK +tid=23026 +*** C771T033 *** ATTACH OK +*** C771T034 *** SYSCALL OK +syscall enter n=9 +*** C771T034 *** SYSCALL OK +syscall return n=9 r=46912535269376 +*** C771T035 DETACH OK +mmap m=0x2aaaad001000 errno=0 +update m=0x2aaaad001000 +update *m=1 +munmap rc=0, errno=0 +main done +TEST_SUITE: ptrace +TEST_NUMBER: 19 +ARGS: +TEST_SUITE: ptrace +TEST_NUMBER: 19 +ARGS: +child is stopped. +RESULT: ok +*** C771T036: ostest-ptrace-19 OK +pid=23121 +tid=23151 +*** C771T037 wait4(pid) OK +*** C771T038 wait4(tid) OK +*** C771T039 wait4(pid, __WCLONE) OK +*** C771T040 wait4(tid, __WCLONE) OK +*** C771T041 wait4(pid, __WALL) OK +*** C771T042 wait4(tid, __WALL) OK +clone01 1 TPASS : clone returned 23215 +*** C771T043: clone01 OK (1) +clone03 1 TPASS : Test passed +*** C771T044: clone03 OK (1) +clone04 1 TPASS : expected failure; Got EINVAL +*** C771T045: clone04 OK (1) +clone06 1 TPASS : Test Passed +*** C771T046: clone06 OK (1) +clone07 1 TPASS : Use of return() in child did not cause SIGSEGV +*** C771T047: clone07 OK (1) +exit01 1 TPASS : exit() test PASSED +*** C771T048: exit01 OK (1) +exit02 1 TPASS : exit() test PASSED +*** C771T049: exit02 OK (1) +exit_group01 1 TPASS : exit_group() succeeded +*** C771T050: exit_group01 OK (1) +fork01 1 TPASS : fork() returned 23754 +fork01 2 TPASS : child pid and fork() return agree: 23754 +*** C771T051: fork01 OK (2) +fork02 0 TINFO : Inside parent +fork02 0 TINFO : Inside child +fork02 0 TINFO : exit status of wait 0 +fork02 1 TPASS : test 1 PASSED +*** C771T052: fork02 OK (1) +fork03 0 TINFO : process id in parent of child from fork : 23896 +fork03 1 TPASS : test 1 PASSED +*** C771T053: fork03 OK (1) +fork04 1 TPASS : Env var TERM unchanged after fork(): xterm +fork04 2 TPASS : Env var NoTSetzWq unchanged after fork(): getenv() does not find variable set +fork04 3 TPASS : Env var TESTPROG unchanged after fork(): FRKTCS04 +*** C771T054: fork04 OK (3) +fork07 0 TINFO : Forking 100 children +fork07 0 TINFO : Forked all 100 children, now collecting +fork07 0 TINFO : Collected all 100 children +fork07 1 TPASS : 100/100 children read correctly from an inheritted fd +*** C771T055: fork07 OK (1) +fork08 0 TINFO : parent forksval: 1 +fork08 0 TINFO : parent forksval: 2 +fork08 0 TINFO : second child got char: b +fork08 1 TPASS : Test passed in childnumber 2 +fork08 0 TINFO : exit status of wait expected 0 got 0 +fork08 1 TPASS : parent test PASSED +fork08 0 TINFO : exit status of wait expected 0 got 0 +fork08 2 TPASS : parent test PASSED +fork08 0 TINFO : exit status of wait expected 0 got 0 +fork08 3 TPASS : parent test PASSED +fork08 0 TINFO : Number of processes forked is 2 +*** C771T056: fork08 OK (4) +fork09 0 TINFO : OPEN_MAX is 1024 +fork09 0 TINFO : first file descriptor is 12 +fork09 0 TINFO : Parent reporting 1023 files open +fork09 0 TINFO : Child opened new file #1023 +fork09 1 TPASS : test 1 PASSED +*** C771T057: fork09 OK (1) +fork10 0 TINFO : fork child A +fork10 1 TPASS : test 1 PASSED +*** C771T058: fork10 OK (1) +fork11 1 TPASS : fork test passed, 100 processes +*** C771T059: fork11 OK (1) +kill01 1 TPASS : received expected signal 9 +*** C771T060: kill01 OK (1) +kill02 1 TPASS : The signal was sent to all processes in the process group. +kill02 2 TPASS : The signal was not sent to selective processes that were not in the process group. +*** C771T061: kill02 OK (2) +kill03 1 TPASS : errno set to 22 : Invalid argument, as expected +*** C771T062: kill03 OK (1) +kill04 1 TPASS : errno set to 3 : No such process, as expected +*** C771T063: kill04 OK (1) +kill failed with EPERM +kill05 1 TPASS : received expected errno(EPERM) +*** C771T064: kill05 OK (1) +kill06 1 TPASS : received expected signal 9 +*** C771T065: kill06 OK (1) +kill07 0 TINFO : received expected signal 9 +kill07 1 TPASS : Did not catch signal as expected +*** C771T066: kill07 OK (1) +kill08 1 TPASS : received expected signal 9 +*** C771T067: kill08 OK (1) +kill09 1 TPASS : kill(31358, SIGKILL) returned 0 +*** C771T068: kill09 OK (1) +kill10 1 TPASS : All 2 pgrps received their signals +31429: All 10 children reported in +31460: All 10 children reported in +*** C771T069: kill10 OK (1) +kill11 1 TPASS : signal SIGHUP +kill11 2 TPASS : signal SIGINT +kill11 3 TPASS : signal SIGQUIT dumped core +kill11 4 TPASS : signal SIGILL dumped core +kill11 5 TPASS : signal SIGTRAP dumped core +kill11 6 TPASS : signal SIGIOT/SIGABRT dumped core +kill11 7 TPASS : signal SIGIOT/SIGABRT dumped core +kill11 8 TPASS : signal SIGBUS dumped core +kill11 9 TPASS : signal SIGFPE dumped core +kill11 10 TPASS : signal SIGKILL +kill11 11 TPASS : signal SIGUSR1 +kill11 12 TPASS : signal SIGSEGV dumped core +kill11 13 TPASS : signal SIGUSR2 +kill11 14 TPASS : signal SIGPIPE +kill11 15 TPASS : signal SIGALRM +kill11 16 TPASS : signal SIGTERM +kill11 17 TPASS : signal SIGXCPU dumped core +kill11 18 TPASS : signal SIGXFSZ dumped core +kill11 19 TPASS : signal SIGVTALRM +kill11 20 TPASS : signal SIGPROF +kill11 21 TPASS : signal SIGIO/SIGPOLL +kill11 22 TPASS : signal SIGPWR +kill11 23 TPASS : signal SIGSYS/SIGUNUSED dumped core +*** C771T070: kill11 OK (23) +kill12 1 TPASS : Test passed +*** C771T071: kill12 OK (1) +ptrace01 1 TPASS : Test Passed +ptrace01 2 TPASS : Test Passed +*** C771T072: ptrace01 OK (2) +ptrace02 1 TPASS : Test Passed +ptrace02 2 TPASS : Test Passed +*** C771T073: ptrace02 OK (2) +ptrace03 1 TCONF : ptrace03.c:137: this kernel allows to trace init +ptrace03 2 TPASS : Test Passed +ptrace03 3 TPASS : Test Passed +*** C771T074: ptrace03 OK (2) +ptrace05 0 TINFO : [child] Sending kill(.., 0) +ptrace05 1 TPASS : kill(.., 0) exited with 0, as expected. +ptrace05 0 TINFO : [child] Sending kill(.., 1) +ptrace05 2 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 2) +ptrace05 3 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 3) +ptrace05 4 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 4) +ptrace05 5 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 5) +ptrace05 6 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 6) +ptrace05 7 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 7) +ptrace05 8 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 8) +ptrace05 9 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 9) +ptrace05 10 TPASS : Killed with SIGKILL, as expected. +ptrace05 0 TINFO : [child] Sending kill(.., 10) +ptrace05 11 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 11) +ptrace05 12 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 12) +ptrace05 13 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 13) +ptrace05 14 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 14) +ptrace05 15 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 15) +ptrace05 16 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 16) +ptrace05 17 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 17) +ptrace05 18 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 18) +ptrace05 19 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 19) +ptrace05 20 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 20) +ptrace05 21 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 21) +ptrace05 22 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 22) +ptrace05 23 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 23) +ptrace05 24 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 24) +ptrace05 25 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 25) +ptrace05 26 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 26) +ptrace05 27 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 27) +ptrace05 28 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 28) +ptrace05 29 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 29) +ptrace05 30 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 30) +ptrace05 31 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 31) +ptrace05 32 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 32) +ptrace05 33 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 33) +ptrace05 34 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 34) +ptrace05 35 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 35) +ptrace05 36 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 36) +ptrace05 37 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 37) +ptrace05 38 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 38) +ptrace05 39 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 39) +ptrace05 40 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 40) +ptrace05 41 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 41) +ptrace05 42 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 42) +ptrace05 43 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 43) +ptrace05 44 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 44) +ptrace05 45 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 45) +ptrace05 46 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 46) +ptrace05 47 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 47) +ptrace05 48 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 48) +ptrace05 49 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 49) +ptrace05 50 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 50) +ptrace05 51 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 51) +ptrace05 52 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 52) +ptrace05 53 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 53) +ptrace05 54 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 54) +ptrace05 55 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 55) +ptrace05 56 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 56) +ptrace05 57 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 57) +ptrace05 58 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 58) +ptrace05 59 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 59) +ptrace05 60 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 60) +ptrace05 61 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 61) +ptrace05 62 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 62) +ptrace05 63 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 63) +ptrace05 64 TPASS : Stopped as expected +ptrace05 0 TINFO : [child] Sending kill(.., 64) +ptrace05 65 TPASS : Stopped as expected +*** C771T075: ptrace05 OK (65) +wait02 1 TPASS : wait(&status) returned 3201 +*** C771T076: wait02 OK (1) +wait401 1 TPASS : Received child pid as expected. +wait401 2 TPASS : wait401 call succeeded +*** C771T077: wait401 OK (2) +wait402 1 TPASS : received expected failure - errno = 10 - No child processes +*** C771T078: wait402 OK (1) +waitid01 0 TINFO : Process 3384 terminated: +waitid01 0 TINFO : code = 1 +waitid01 0 TINFO : exit value = 31488 +waitid01 0 TINFO : Process 3414 terminated: +waitid01 0 TINFO : code = 1 +waitid01 0 TINFO : exit value = 0 +waitid01 0 TINFO : Process 3444 terminated: +waitid01 0 TINFO : code = 2 +waitid01 0 TINFO : signal = 1 +waitid01 0 TINFO : Process 3474 terminated: +waitid01 0 TINFO : code = 1 +waitid01 0 TINFO : exit value = 31488 +waitid01 0 TINFO : Process 3504 terminated: +waitid01 0 TINFO : code = 1 +waitid01 0 TINFO : exit value = 0 +waitid01 0 TINFO : Process 3534 terminated: +waitid01 0 TINFO : code = 2 +waitid01 0 TINFO : signal = 1 +waitid01 0 TINFO : Process 3564 terminated: +waitid01 0 TINFO : code = 1 +waitid01 0 TINFO : exit value = 31488 +waitid01 0 TINFO : Process 3594 terminated: +waitid01 0 TINFO : code = 1 +waitid01 0 TINFO : exit value = 0 +waitid01 0 TINFO : Process 3624 terminated: +waitid01 0 TINFO : code = 2 +waitid01 0 TINFO : signal = 1 +waitid01 1 TPASS : waitid(): system call passed +*** C771T079: waitid01 OK (1) +waitid02 0 TINFO : WNOHANG +waitid02 0 TINFO : (3664) waitid(0, 0, 0x547ffffffcf0, 1) +waitid02 1 TPASS : exp_errno=22 +waitid02 0 TINFO : si_pid = 0 ; si_code = 0 ; si_status = 0 +waitid02 0 TINFO : WNOHANG | WEXITED no child +waitid02 0 TINFO : (3664) waitid(0, 0, 0x547ffffffcf0, 5) +waitid02 2 TPASS : exp_errno=10 +waitid02 0 TINFO : si_pid = 0 ; si_code = 0 ; si_status = 0 +waitid02 0 TINFO : WNOHANG | WEXITED with child +waitid02 0 TINFO : (3664) waitid(0, 0, 0x547ffffffcf0, 5) +waitid02 3 TPASS : ret: 0 +waitid02 0 TINFO : si_pid = 0 ; si_code = 0 ; si_status = 0 +waitid02 0 TINFO : P_PGID, WEXITED wait for child +waitid02 0 TINFO : (3664) waitid(2, 5365, 0x547ffffffcf0, 4) +waitid02 4 TPASS : ret: 0 +waitid02 0 TINFO : si_pid = 3725 ; si_code = 1 ; si_status = 0 +waitid02 0 TINFO : P_PID, WEXITED wait for child +waitid02 0 TINFO : (3664) waitid(1, 3755, 0x547ffffffcf0, 4) +waitid02 5 TPASS : ret: 0 +waitid02 0 TINFO : si_pid = 3755 ; si_code = 1 ; si_status = 0 +waitid02 0 TINFO : P_PID, WSTOPPED | WNOWAIT +waitid02 0 TINFO : (3664) waitid(1, 3785, 0x547ffffffcf0, 16777218) +waitid02 6 TPASS : ret: 0 +waitid02 0 TINFO : si_pid = 3785 ; si_code = 5 ; si_status = 4991 +waitid02 0 TINFO : P_PID, WCONTINUED +waitid02 0 TINFO : (3664) waitid(1, 3815, 0x547ffffffcf0, 8) +waitid02 7 TPASS : ret: 0 +waitid02 0 TINFO : si_pid = 3815 ; si_code = 6 ; si_status = 65535 +waitid02 0 TINFO : P_PID, WEXITED not a child of the calling process +waitid02 0 TINFO : (3664) waitid(1, 1, 0x547ffffffcf0, 4) +waitid02 8 TPASS : exp_errno=10 +waitid02 0 TINFO : si_pid = 0 ; si_code = 0 ; si_status = 0 +*** C771T080: waitid02 OK (8) +waitpid01 1 TPASS : recieved expected pid +waitpid01 2 TPASS : recieved expected signal +*** C771T081: waitpid01 OK (2) +waitpid02 1 TPASS : recieved expected pid +waitpid02 2 TPASS : recieved expected signal +waitpid02 3 TPASS : recieved expected exit value +*** C771T082: waitpid02 OK (3) +waitpid03 1 TPASS : Got correct child PID +waitpid03 2 TPASS : Condition 2 test passed +*** C771T083: waitpid03 OK (2) +waitpid04 1 TPASS : condition 1 test passed +waitpid04 2 TPASS : condition 2 test passed +waitpid04 3 TPASS : condition 3 test passed +*** C771T084: waitpid04 OK (3) +waitpid05 1 TPASS : received expected pid. +waitpid05 2 TPASS : received expected exit number. +waitpid05 3 TPASS : received expected pid. +waitpid05 4 TPASS : received expected exit number. +waitpid05 5 TPASS : received expected pid. +waitpid05 6 TPASS : received expected exit number. +waitpid05 7 TPASS : received expected pid. +waitpid05 8 TPASS : received expected exit number. +waitpid05 9 TPASS : received expected pid. +waitpid05 10 TPASS : received expected exit number. +waitpid05 11 TPASS : received expected pid. +waitpid05 12 TPASS : received expected exit number. +waitpid05 13 TPASS : received expected pid. +waitpid05 14 TPASS : received expected exit number. +waitpid05 15 TPASS : received expected pid. +waitpid05 16 TPASS : received expected exit number. +waitpid05 17 TPASS : received expected pid. +waitpid05 18 TPASS : received expected exit number. +waitpid05 19 TPASS : received expected pid. +waitpid05 20 TPASS : received expected exit number. +waitpid05 21 TPASS : received expected pid. +waitpid05 22 TPASS : received expected exit number. +waitpid05 23 TPASS : received expected pid. +waitpid05 24 TPASS : received expected exit number. +*** C771T085: waitpid05 OK (24) +waitpid06 1 TPASS : waitpid06 PASSED +*** C771T086: waitpid06 OK (1) +waitpid07 1 TPASS : waitpid07 PASSED +*** C771T087: waitpid07 OK (1) +waitpid08 1 TPASS : waitpid08 PASSED +*** C771T088: waitpid08 OK (1) +waitpid09 1 TPASS : case 1 PASSED +waitpid09 2 TPASS : case 2 PASSED +*** C771T089: waitpid09 OK (2) +waitpid10 1 TPASS : Test PASSED +*** C771T090: waitpid10 OK (1) +waitpid11 1 TPASS : Test PASSED +waitpid11 1 TPASS : waitpid11 PASSED +*** C771T091: waitpid11 OK (2) +waitpid12 1 TPASS : Test PASSED +waitpid12 1 TPASS : waitpid12 PASSED +*** C771T092: waitpid12 OK (2) +waitpid13 1 TPASS : Test PASSED +waitpid13 1 TPASS : waitpid13 PASSED +*** C771T093: waitpid13 OK (2) +bash-4.2$ exit +exit + +Script done on Mon Sep 24 09:07:34 2018 diff --git a/test/issues/771+1179+1143/C771T001.awk b/test/issues/771+1179+1143/C771T001.awk new file mode 100644 index 00000000..d2439d5d --- /dev/null +++ b/test/issues/771+1179+1143/C771T001.awk @@ -0,0 +1,176 @@ +#! /usr/bin/awk -f +BEGIN{ + ok = 0 + ng = 0 +} + +/^\(gdb\) b thr/{ + print "*** C771T001 gdb start OK" + ok++ + st = 2 + next +} + +/^\(gdb\) r/{ + st = 3 + next +} + +/^\(gdb\) info threads/{ + st = 4 + next +} + +/^\(gdb\) bt/{ + st = (bt == 0) ? 5 : 8 + bt++ + next +} + +/^\(gdb\) n/{ + st = 6 + next +} + +/^\(gdb\) thread 1/{ + st = 7 + next +} + +/^\(gdb\) thread 2/{ + if (st != 0) { + printf("*** C771T%03d backtrace command NG\n", st) + ng++ + } + st = 9 + next +} + +/^\(gdb\) c/{ + st = 10 + next +} + +/^\(gdb\) q/{ + st = 11 + next +} + +/^\(gdb\)/ { + printf("*** C771T%03d NG\n", st) + ng++ + exit(1) +} + +st == 2 { + if ($0 ~/^Breakpoint 1 at/) { + print "*** C771T002 breakpoint command OK" + ok++ + } + else { + print "*** C771T002 breakpoint command NG" + ng++ + } + st = 0 +} + +st == 3 { + if ($0 ~/^Starting program/) { + print "*** C771T003 run command OK" + ok++ + } + else { + print "*** C771T003 run command NG" + ng++ + } + st = 0 +} + +st == 4 { + if ($0 ~/^ Id /) { + print "*** C771T004 info threads command OK" + ok++ + } + else { + print "*** C771T004 info threadsrun command NG" + ng++ + } + st = 0 +} + +st == 5 { + if ($0 ~/^#0 thr/) { + print "*** C771T005 backtrace command OK" + ok++ + } + else { + print "*** C771T005 backtrace command NG" + ng++ + } + st = 0 +} + +st == 6 { + if ($0 ~/^thread start tid=/) { + print "*** C771T006 next command OK" + ok++ + } + else { + print "*** C771T006 next command NG" + ng++ + } + st = 0 +} + +st == 7 { + if ($0 ~/^\[Switching to thread 1/) { + print "*** C771T007 thread command OK" + ok++ + } + else { + print "*** C771T007 thread command NG" + ng++ + } + st = 0 +} + +st == 8 { + if ($0 ~/ in main /) { + print "*** C771T008 thread command OK" + ok++ + st = 0 + } +} + +st == 9 { + if ($0 ~/^\[Switching to thread 2/) { + print "*** C771T009 thread command OK" + ok++ + } + else { + print "*** C771T009 thread command NG" + ng++ + } + st = 0 +} + +st == 10 { + if ($0 ~/^Continuing/) { + print "*** C771T010 continue command OK" + ok++ + } + else { + print "*** C771T010 continue command NG" + ng++ + } + st = 0 +} + +END{ + if (st == 11) { + print "*** C771T011 quit command OK" + ok++ + } + print "OK=" ok " NG=" ng + exit(ng > 0 ? 1: 0) +} diff --git a/test/issues/771+1179+1143/C771T001.c b/test/issues/771+1179+1143/C771T001.c new file mode 100644 index 00000000..1cb98e02 --- /dev/null +++ b/test/issues/771+1179+1143/C771T001.c @@ -0,0 +1,63 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +volatile char *m; + +void * +thr(void *arg) +{ + int rc; + char *mm; + + fprintf(stderr, "thread start tid=%d\n", (int)syscall(SYS_gettid)); + fflush(stderr); + errno = 0; + mm = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, + -1, 0); + fprintf(stderr, "mmap m=%p errno=%d\n", mm, errno); + fflush(stderr); + memset(mm, '\0', 4096); + m = mm; + *mm = '1'; + while (*m); + rc = munmap(mm, 4096); + fprintf(stderr, "munmap rc=%d, errno=%d\n", rc, errno); + fflush(stderr); + return NULL; +} + +int +main(int argc, char **argv) +{ + pthread_t th; + int rc; + + fprintf(stderr, "process start pid=%d\n", getpid()); + fflush(stderr); + rc = pthread_create(&th, NULL, thr, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + fprintf(stderr, "pthread_create: %d\n", rc); + fflush(stderr); + while (!m); + fprintf(stderr, "update m=%p\n", m); + fflush(stderr); + while (!*m); + fprintf(stderr, "update *m=%c\n", *m); + fflush(stderr); + *m = '\0'; + pthread_join(th, NULL); + fprintf(stderr, "main done\n"); + fflush(stderr); + exit(0); +} diff --git a/test/issues/771+1179+1143/C771T033.c b/test/issues/771+1179+1143/C771T033.c new file mode 100644 index 00000000..0548544a --- /dev/null +++ b/test/issues/771+1179+1143/C771T033.c @@ -0,0 +1,175 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +volatile char *m; +volatile int *x; + +void * +thr(void *arg) +{ + int rc; + pid_t tid; + char *mm; + + tid = syscall(SYS_gettid); + *x = tid; + while (*x == tid); + + errno = 0; + mm = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, + -1, 0); + fprintf(stderr, "mmap m=%p errno=%d\n", mm, errno); + fflush(stderr); + memset(mm, '\0', 4096); + m = mm; + *mm = '1'; + while (*m); + rc = munmap(mm, 4096); + fprintf(stderr, "munmap rc=%d, errno=%d\n", rc, errno); + fflush(stderr); + return NULL; +} + +int +main(int argc, char **argv) +{ + pthread_t th; + int rc; + pid_t tid; + pid_t pid; + int sig; + int st; + + x = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, + -1, 0); + + if (x == (void *)-1) { + perror("mmap"); + exit(1); + } + *x = 0; + + rc = pthread_create(&th, NULL, thr, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + + while (*x == 0); + tid = *x; + fprintf(stderr, "tid=%d\n", tid); + + if ((pid = fork()) == 0) { + if (ptrace(PTRACE_ATTACH, tid, 0, 0) == -1) { + fprintf(stderr, "*** C771T033 *** ATTACH NG err=%d\n", + errno); + exit(1); + } + rc = waitpid(-1, &st, __WALL); + if (rc == tid) { + fprintf(stderr, "*** C771T033 *** ATTACH OK\n"); + } + else { + fprintf(stderr, "*** C771T033 *** ATTACH NG rc=%d\n", + rc); + exit(1); + } + if (ptrace(PTRACE_SETOPTIONS, tid, 0, PTRACE_O_TRACESYSGOOD) == + -1) { + fprintf(stderr, "PTRACE_SETOPTIONS errno=%d\n", errno); + exit(1); + } + *x = 0; + sig = 0; + for (;;) { + rc = ptrace(PTRACE_SYSCALL, tid, 0, sig); + if (rc == -1) { + fprintf(stderr, + "*** C771T034 *** SYSCALL NG err=%d\n", + errno); + exit(1); + } + rc = waitpid(-1, &st, __WALL); + if (rc == tid) { + fprintf(stderr, + "*** C771T034 *** SYSCALL OK\n"); + } + else { + fprintf(stderr, + "*** C771T034 *** SYSCALL NG rc=%d\n", + rc); + exit(1); + } + + if (WIFEXITED(st) || WIFSIGNALED(st)) { + fprintf(stderr, "thread terminated %08x\n", st); + exit(1); + } + if (!WIFSTOPPED(st)) { + fprintf(stderr, "warning: st=%08x\n", st); + continue; + } + if (WSTOPSIG(st) & 0x80) { // syscall + struct user_regs_struct arg; + int num; + long ret; + + if (ptrace(PTRACE_GETREGS, tid, NULL, &arg) == + -1) { + } + num = arg.orig_rax; + ret = arg.rax; + if (ret == -ENOSYS) { + fprintf(stderr, + "syscall enter n=%d\n", num); + } + else { + fprintf(stderr, + "syscall return n=%d r=%ld\n", + num, ret); + if (ptrace(PTRACE_DETACH, tid, NULL, + NULL) == -1) { + fprintf(stderr, + "*** C771T035 DETACH NG" + "err=%d\n", errno); + exit(1); + } + else { + fprintf(stderr, + "*** C771T035 DETACH OK" + "\n"); + exit(0); + } + } + } + else { // signal + sig = WSTOPSIG(st) & 0x7f; + } + } + } + + while (!m); + fprintf(stderr, "update m=%p\n", m); + fflush(stderr); + while (!*m); + fprintf(stderr, "update *m=%c\n", *m); + fflush(stderr); + *m = '\0'; + waitpid(pid, &st, 0); + pthread_join(th, NULL); + fprintf(stderr, "main done\n"); + fflush(stderr); + exit(0); +} diff --git a/test/issues/771+1179+1143/C771T037.c b/test/issues/771+1179+1143/C771T037.c new file mode 100644 index 00000000..2833b9e0 --- /dev/null +++ b/test/issues/771+1179+1143/C771T037.c @@ -0,0 +1,150 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +volatile char *m; +volatile int *x; + +void * +thr(void *arg) +{ + pid_t tid; + + tid = syscall(SYS_gettid); + *x = tid; + while (*x == tid); + return NULL; +} + +int +main(int argc, char **argv) +{ + pthread_t th; + pid_t tid; + pid_t pid; + int st; + int rc; + + x = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, + -1, 0); + + if (x == (void *)-1) { + perror("mmap"); + exit(1); + } + *x = 0; + + rc = pthread_create(&th, NULL, thr, NULL); + if (rc) { + fprintf(stderr, "pthread_create: %d\n", rc); + exit(1); + } + + while (*x == 0); + tid = *x; + fprintf(stderr, "pid=%d\n", getpid()); + fprintf(stderr, "tid=%d\n", tid); + + if ((pid = fork()) == 0) { + pid = getppid(); + if (ptrace(PTRACE_ATTACH, tid, 0, 0) == -1) { + fprintf(stderr, "*** C771T037 ATTACH NG err=%d\n", + errno); + exit(1); + } + if (ptrace(PTRACE_ATTACH, pid, 0, 0) == -1) { + fprintf(stderr, "*** C771T037 ATTACH NG err=%d\n", + errno); + exit(1); + } + + rc = wait4(pid, &st, WNOHANG, NULL); + if (rc == -1) { + fprintf(stderr, "*** C771T037 wait4(pid) NG err=%d\n", + errno); + } + else { + fprintf(stderr, "*** C771T037 wait4(pid) OK\n"); + } + + rc = wait4(tid, &st, WNOHANG, NULL); + if (rc == -1 && errno == ECHILD) { + fprintf(stderr, "*** C771T038 wait4(tid) OK\n"); + } + else { + fprintf(stderr, "*** C771T038 wait4(tid) NG err=%d\n", + errno); + } + + rc = wait4(pid, &st, WNOHANG|__WCLONE, NULL); + if (rc == -1 && errno == ECHILD) { + fprintf(stderr, + "*** C771T039 wait4(pid, __WCLONE) OK\n"); + } + else { + fprintf(stderr, + "*** C771T039 wait4(pid, __WCLONE) NG err=%d\n", + errno); + } + + rc = wait4(tid, &st, WNOHANG|__WCLONE, NULL); + if (rc == -1) { + fprintf(stderr, + "*** C771T040 wait4(tid, __WCLONE) NG err=%d\n", + errno); + } + else { + fprintf(stderr, + "*** C771T040 wait4(tid, __WCLONE) OK\n"); + } + + rc = wait4(pid, &st, WNOHANG|__WALL, NULL); + if (rc == -1) { + fprintf(stderr, + "*** C771T041 wait4(pid, __WALL) NG err=%d\n", + errno); + } + else { + fprintf(stderr, + "*** C771T041 wait4(pid, __WALL) OK\n"); + } + + rc = wait4(tid, &st, WNOHANG|__WALL, NULL); + if (rc == -1) { + fprintf(stderr, + "*** C771T042 wait4(tid, __WALL) NG err=%d\n", + errno); + } + else { + fprintf(stderr, + "*** C771T042 wait4(tid, __WALL) OK\n"); + } + + if (ptrace(PTRACE_DETACH, tid, NULL, NULL) == -1) { + fprintf(stderr, "*** C771T042 DETACH NG err=%d\n", + errno); + exit(1); + } + if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) { + fprintf(stderr, "*** C771T042 DETACH NG err=%d\n", + errno); + exit(1); + } + *x = 0; + exit(0); + } + + while (*x == tid); + exit(0); +} diff --git a/test/issues/771+1179+1143/Makefile b/test/issues/771+1179+1143/Makefile new file mode 100644 index 00000000..6621057e --- /dev/null +++ b/test/issues/771+1179+1143/Makefile @@ -0,0 +1,23 @@ +CC = gcc +TARGET= C771T001 C771T033 C771T037 + +CPPFLAGS = +LDFLAGS = + +all: $(TARGET) + +C771T001: C771T001.c + $(CC) -g -Wall -o $@ $^ -pthread + +C771T033: C771T033.c + $(CC) -g -Wall -o $@ $^ -pthread + +C771T037: C771T037.c + $(CC) -g -Wall -o $@ $^ -pthread + +test: all + @sh ./C771.sh + +clean: + rm -f $(TARGET) *.o + rm -rf gdb-result diff --git a/test/issues/771+1179+1143/README b/test/issues/771+1179+1143/README new file mode 100644 index 00000000..9c198ed7 --- /dev/null +++ b/test/issues/771+1179+1143/README @@ -0,0 +1,144 @@ +【Issue#771 Issue#1179 Issue#1143 動作確認】 +□ テスト内容 +各 Issue は以下の理由により、一括して対応した。 +・ Issue#771 は ptrace のスレッドサポートである。 +・ Issue#1179 は PTRACE_ATTACH の不具合対応であるが、スレッドの PTRACE_ATTACH + 対応が Issue#771 に含まれるため、一括して対応することにした。 +・ Issue#1143 は wait4 の __WALL フラグサポートであるが、スレッドの wait4 対応 + (__WCLONEフラグサポート) が Issue#771 に含まれるため、一括して対応すること + にした。 + +テスト内容は以下の通りである。 + +1. gdb を用いてスレッドを使用するプログラムのデバッグが行えることを確認する。 +C771T001 mcexec gdb C771T001 を実行すると、McKernelでgdbの実行を開始し、 + (gdb) のプロンプトが表示されること +C771T002 b thr を実行し、スレッドにブレークポイントを設定できること +C771T003 r コマンド実行後、スレッドに設定したブレークポイントで停止できること +C771T004 info threads コマンドで、スレッド一覧が表示できること +C771T005 bt コマンドでスレッドのバックトレースが表示できること +C771T006 n コマンドでスレッドのステップ実行ができること +C771T007 thread 1 コマンドでメインスレッドに切り替えできること +C771T008 bt コマンドでメインスレッドのバックトレースが表示できること +C771T009 thread 2 コマンドで再びスレッドに切り替えできること +C771T010 c コマンドでスレッドとメインスレッドの実行が再開されること +C771T011 q コマンドで gdb を正しく終了できること +C771T012 McKernel にスレッドとプロセスの残留が無いこと + +2. gdb のテストケースを実行し、gdb が使用する ptrace の機能が動作することを + 確認する。thread を使用するテストを中心に、以下のテストケースを選定した。 +C771T013 a2-run が PASS すること +C771T014 foll-fork が PASS すること +C771T015 fork-detach が PASS すること +C771T016 atomic-seq-threaded が PASS すること +C771T017 bp_in_thread が PASS すること +C771T018 bt-clone-stop が PASS すること +C771T019 corethreads が PASS すること +C771T020 dlopen-libpthread が PASS すること +C771T021 fork-child-threads が PASS すること +C771T022 killed が PASS すること +C771T023 pthread_cond_wait が PASS すること +C771T024 switch-threads が PASS すること +C771T025 thread-specific が PASS すること +C771T026 thread_check が PASS すること +C771T027 thread_events が PASS すること +C771T028 threaded-exec が PASS すること +C771T029 threxit-hop-specific が PASS すること +C771T030 tls-nodebug が PASS すること +C771T031 tls-sepdebug が PASS すること +C771T032 tls-var が PASS すること + +3. ptrace のスレッドサポートの基本機能を確認する。 +C771T033 スレッドに PTRACE_ATTACH できること +C771T034 PTRACE_SYSCALL により、スレッドのシステムコールを補足できること +C771T035 PTRACE_DETACH により、スレッドのトレースを中止できること + +4. Issue#1179 の指摘プログラムが正常動作することを確認する。 +CT771T036 test_mck -s ptrace -n 19 が PASS すること + +5. wait4 で __WALL フラグ、__WCLONE フラグが正しく機能することを確認する。 +CT771T037 wait4 のフラグに __WALL, __WCLONE 共に指定しないとき、pid に + 子プロセスを指定してエラーにならないこと +CT771T038 wait4 のフラグに __WALL, __WCLONE 共に指定しないとき、pid に + スレッドをを指定してエラー(ECHILD)になること +CT771T039 wait4 のフラグに __WCLONE を指定し、pid に子プロセスを指定して + エラー(ECHILD)になること +CT771T040 wait4 のフラグに __WCLONE を指定し、pid にスレッドをを指定して + エラーにならないこと +CT771T041 wait4 のフラグに __WALL を指定し、pid に子プロセスを指定して + エラーにならないこと +CT771T042 wait4 のフラグに __WALL を指定し、pid にスレッドをを指定して + エラーにならないこと + +6. LTP を用いて変更が既存処理に影響しないことを確認する。 + プロセス関連のシステムコール(clone, exit, fork, kill, ptrace, waitなど) + を中心に以下のテストプログラムを選定した。 +CT771T043 clone01 が PASS すること +CT771T044 clone03 が PASS すること +CT771T045 clone04 が PASS すること +CT771T046 clone06 が PASS すること +CT771T047 clone07 が PASS すること +CT771T048 exit01 が PASS すること +CT771T049 exit02 が PASS すること +CT771T050 exit_group01 が PASS すること +CT771T051 fork01 が PASS すること +CT771T052 fork02 が PASS すること +CT771T053 fork03 が PASS すること +CT771T054 fork04 が PASS すること +CT771T055 fork07 が PASS すること +CT771T056 fork08 が PASS すること +CT771T057 fork09 が PASS すること +CT771T058 fork10 が PASS すること +CT771T059 fork11 が PASS すること +CT771T060 kill01 が PASS すること +CT771T061 kill02 が PASS すること +CT771T062 kill03 が PASS すること +CT771T063 kill04 が PASS すること +CT771T064 kill05 が PASS すること +CT771T065 kill06 が PASS すること +CT771T066 kill07 が PASS すること +CT771T067 kill08 が PASS すること +CT771T068 kill09 が PASS すること +CT771T069 kill11 が PASS すること +CT771T070 kill12 が PASS すること +CT771T071 ptrace01 が PASS すること +CT771T072 ptrace02 が PASS すること +CT771T073 ptrace03 が PASS すること +CT771T074 ptrace04 が PASS すること +CT771T075 ptrace05 が PASS すること +CT771T076 wait02 が PASS すること +CT771T077 wait401 が PASS すること +CT771T078 wait402 が PASS すること +CT771T079 waitid01 が PASS すること +CT771T080 waitid02 が PASS すること +CT771T081 waitpid01 が PASS すること +CT771T082 waitpid02 が PASS すること +CT771T083 waitpid03 が PASS すること +CT771T084 waitpid04 が PASS すること +CT771T085 waitpid05 が PASS すること +CT771T086 waitpid06 が PASS すること +CT771T087 waitpid07 が PASS すること +CT771T088 waitpid08 が PASS すること +CT771T089 waitpid09 が PASS すること +CT771T090 waitpid10 が PASS すること +CT771T091 waitpid11 が PASS すること +CT771T092 waitpid12 が PASS すること +CT771T093 waitpid13 が PASS すること + +□ 実行手順 +$ make test + +McKernelのインストール先や、OSTEST, LTPの配置場所は、 $HOME/.mck_test_config +を参照する。.mck_test_config は、McKernel をビルドした際に生成される +mck_test_config.sample ファイルを $HOME にコピーし、適宜編集すること。 + +また、C771.sh の以下の指定を適宜変更すること。 +GDBBUILDDIR= GDB 構築したパス ($HOME にて gdb を src.rpm から構築している + 場合は変更不要) + +gdb のテストケースでは、dejagnu パッケージに含まれる runtest コマンドを使用 +する。システムにインストールされていない場合は、予めインストールすること。 + +□ 実行結果 +C771.txt 参照。 +すべての項目をPASSしていることを確認。 diff --git a/test/issues/771+1179+1143/gdb_test.sh b/test/issues/771+1179+1143/gdb_test.sh new file mode 100755 index 00000000..396866b7 --- /dev/null +++ b/test/issues/771+1179+1143/gdb_test.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +if [ $# -lt 2 ]; then + echo "$0 option error" >&2 + echo "Usage: $0 category test_exp" >&2 + exit 1 +fi + +cat=$1 +test_exp=$2 + +gdb_installdir=/usr +if [ "X$gdb_builddir" = X ];then + echo gdb_builddir was not set >&2 + exit 1 +fi +if [ "X$MCEXEC" = X ];then + echo MCEXEC was not set >&2 + exit 1 +fi + +log_dir="$gdb_builddir/gdb/testsuite" + +if ! which runtest > /dev/null 2>&1; then + echo no runtest found >&2 + exit 1 +fi + +result=`pwd`/gdb-result +result_raw=`pwd`/gdb-result/raw +export PATH=`pwd`:$PATH + +cd ${gdb_builddir} + +echo "======== ${test_exp} ========" +# exec by linux +make check RUNTESTFLAGS="--verbose gdb.${cat}/${test_exp}.exp" &> /dev/null +mv ${log_dir}/gdb.log ${result_raw}/linux/${test_exp}.log +mv ${log_dir}/gdb.sum ${result_raw}/linux/${test_exp}.sum + +# exec by mcexec +make check RUNTESTFLAGS="--verbose GDB=mcexec_gdb.sh gdb.${cat}/${test_exp}.exp" &> /dev/null +mv ${log_dir}/gdb.log ${result_raw}/mck/${test_exp}.log +mv ${log_dir}/gdb.sum ${result_raw}/mck/${test_exp}.sum + +# extract important part +sed -n '/gdb tests/,/expected passes/p' ${result_raw}/linux/${test_exp}.sum > ${result}/linux/${test_exp}.sum +sed -n '/gdb tests/,/expected passes/p' ${result_raw}/mck/${test_exp}.sum > ${result}/mck/${test_exp}.sum + +grep -e '^(gdb) [a-zA-Z0-9]' ${result_raw}/linux/${test_exp}.log > ${result}/linux/${test_exp}.log +grep -e '^(gdb) [a-zA-Z0-9]' ${result_raw}/mck/${test_exp}.log > ${result}/mck/${test_exp}.log + +diff -u ${result}/linux/${test_exp}.sum ${result}/mck/${test_exp}.sum > /dev/null +if [ $? -eq 0 ]; then + echo "【SAME】${test_exp}: Summary." +else + echo "【DIFF】${test_exp} : Summary Difference ---" + diff -u ${result}/linux/${test_exp}.sum ${result}/mck/${test_exp}.sum +fi + +diff -u ${result}/linux/${test_exp}.log ${result}/mck/${test_exp}.log > /dev/null +if [ $? -eq 0 ]; then + echo "【SAME】${test_exp} : Log." +else + echo "【DIFF】${test_exp} : Log Difference ---" + diff -u ${result}/linux/${test_exp}.log ${result}/mck/${test_exp}.log +fi + +diff -u <(grep 'of expected passes' ${result}/linux/${test_exp}.sum) <(grep 'of expected passes' ${result}/mck/${test_exp}.sum) > /dev/null +if [ $? -eq 0 ]; then + echo "【PASS】${test_exp}" +else + echo "【FAIL】${test_exp}" + diff -u <(grep 'of expected passes' ${result}/linux/${test_exp}.sum) <(grep 'of expected passes' ${result}/mck/${test_exp}.sum) > /dev/null +fi diff --git a/test/issues/771+1179+1143/gdblist b/test/issues/771+1179+1143/gdblist new file mode 100644 index 00000000..d7286eca --- /dev/null +++ b/test/issues/771+1179+1143/gdblist @@ -0,0 +1,20 @@ +base a2-run +base foll-fork +base fork-detach +threads atomic-seq-threaded +threads bp_in_thread +threads bt-clone-stop +threads corethreads +threads dlopen-libpthread +threads fork-child-threads +threads killed +threads pthread_cond_wait +threads switch-threads +threads thread-specific +threads thread_check +threads thread_events +threads threaded-exec +threads threxit-hop-specific +threads tls-nodebug +threads tls-sepdebug +threads tls-var diff --git a/test/issues/771+1179+1143/ltplist b/test/issues/771+1179+1143/ltplist new file mode 100644 index 00000000..84107844 --- /dev/null +++ b/test/issues/771+1179+1143/ltplist @@ -0,0 +1,51 @@ +clone01 +clone03 +clone04 +clone06 +clone07 +exit01 +exit02 +exit_group01 +fork01 +fork02 +fork03 +fork04 +fork07 +fork08 +fork09 +fork10 +fork11 +kill01 +kill02 +kill03 +kill04 +kill05 +kill06 +kill07 +kill08 +kill09 +kill10 +kill11 +kill12 +ptrace01 +ptrace02 +ptrace03 +ptrace05 +wait02 +wait401 +wait402 +waitid01 +waitid02 +waitpid01 +waitpid02 +waitpid03 +waitpid04 +waitpid05 +waitpid06 +waitpid07 +waitpid08 +waitpid09 +waitpid10 +waitpid11 +waitpid12 +waitpid13 diff --git a/test/issues/771+1179+1143/mcexec_gdb.sh b/test/issues/771+1179+1143/mcexec_gdb.sh new file mode 100755 index 00000000..d53e64c7 --- /dev/null +++ b/test/issues/771+1179+1143/mcexec_gdb.sh @@ -0,0 +1,8 @@ +#!/bin/sh -x + +if [ x$MCEXEC = x ]; then + echo MCEXEC was not set >&2 + exit 1 +fi + +exec $MCEXEC gdb "$@"