Fix manipulation of fork_tree_node for ptrace

This commit is contained in:
Masamichi Takagi
2014-09-23 14:29:09 +09:00
committed by Tomoki Shirasawa
parent 658b88fd7b
commit 013d3e95c2
5 changed files with 73 additions and 31 deletions

View File

@ -141,7 +141,7 @@ void pc_init(void)
osnum += *p++ - '0';
}
}
kprintf("osnum: %d\n", osnum);
dkprintf("osnum: %d\n", osnum);
if (!(p = find_command_line("perfctr"))) {

View File

@ -48,6 +48,11 @@ static void insert_vm_range_list(struct process_vm *vm,
static int copy_user_ranges(struct process *proc, struct process *org);
void settid(struct process *proc, int mode, int newcpuid, int oldcpuid);
int refcount_fork_tree_node(struct fork_tree_node *ftn)
{
return ihk_atomic_read(&ftn->refcount);
}
void hold_fork_tree_node(struct fork_tree_node *ftn)
{
ihk_atomic_inc(&ftn->refcount);
@ -318,23 +323,48 @@ err_free_proc:
}
int ptrace_traceme(void){
int error = 0;
struct process *proc = cpu_local_var(current);
struct fork_tree_node *ftn = proc->ftn, *parent;
struct fork_tree_node *child, *next;
dkprintf("ptrace_traceme,pid=%d,proc->ftn->parent=%p\n", proc->pid, proc->ftn->parent);
ftn->ptrace = PT_TRACED;
parent = ftn->parent;
if (parent != NULL) {
ftn->ppid_parent = parent;
ihk_mc_spinlock_lock_noirq(&parent->lock);
list_add_tail(&ftn->ptrace_siblings_list, &parent->ptrace_children);
ihk_mc_spinlock_unlock_noirq(&parent->lock);
if (proc->ftn->parent == NULL) {
error = -EPERM;
goto out;
}
return 0;
}
dkprintf("ptrace_traceme,parent->pid=%d\n", proc->ftn->parent->pid);
ihk_mc_spinlock_lock_noirq(&proc->ftn->lock);
proc->ftn->ptrace = PT_TRACED;
proc->ftn->ppid_parent = proc->ftn->parent;
ihk_mc_spinlock_lock_noirq(&proc->ftn->parent->lock);
list_for_each_entry_safe(child, next, &proc->ftn->parent->children, siblings_list) {
if(child == proc->ftn) {
list_del(&child->siblings_list);
goto found;
}
}
kprintf("ptrace_traceme,not found\n");
error = -EPERM;
goto out_notfound;
found:
list_add_tail(&proc->ftn->ptrace_siblings_list, &proc->ftn->parent->ptrace_children);
ihk_mc_spinlock_unlock_noirq(&proc->ftn->parent->lock);
ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock);
out:
dkprintf("ptrace_traceme,returning,error=%d\n", error);
return error;
out_notfound:
ihk_mc_spinlock_unlock_noirq(&proc->ftn->parent->lock);
ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock);
goto out;
}
static int copy_user_ranges(struct process *proc, struct process *org)
{

View File

@ -301,16 +301,12 @@ static int wait_zombie(struct process *proc, struct fork_tree_node *child, int *
int ret;
struct syscall_request request IHK_DMA_ALIGN;
dkprintf("wait: found PS_ZOMBIE process: %d\n", child->pid);
list_del(&child->siblings_list);
dkprintf("wait_zombie,found PS_ZOMBIE process: %d\n", child->pid);
if (status) {
*status = child->exit_status;
}
release_fork_tree_node(child);
/* Ask host to clean up exited child */
request.number = __NR_wait4;
request.args[0] = child->pid;
@ -401,7 +397,6 @@ SYSCALL_DECLARE(wait4)
pid = (int)ihk_mc_syscall_arg0(ctx);
ihk_mc_spinlock_lock_noirq(&proc->ftn->lock);
list_for_each_entry(child_iter, &proc->ftn->children, siblings_list) {
ihk_mc_spinlock_lock_noirq(&child_iter->lock);
@ -416,6 +411,8 @@ SYSCALL_DECLARE(wait4)
if(child_iter->status == PS_ZOMBIE) {
ret = wait_zombie(proc, child_iter, status, ctx);
if(ret) {
list_del(&child_iter->siblings_list);
release_fork_tree_node(child_iter);
goto out_found;
}
}
@ -440,7 +437,6 @@ SYSCALL_DECLARE(wait4)
ihk_mc_spinlock_unlock_noirq(&child_iter->lock);
}
list_for_each_entry(child_iter, &proc->ftn->ptrace_children, ptrace_siblings_list) {
ihk_mc_spinlock_lock_noirq(&child_iter->lock);
@ -455,6 +451,8 @@ SYSCALL_DECLARE(wait4)
if(child_iter->status == PS_ZOMBIE) {
ret = wait_zombie(proc, child_iter, status, ctx);
if(ret) {
list_del(&child_iter->ptrace_siblings_list);
release_fork_tree_node(child_iter);
goto out_found;
}
}
@ -510,8 +508,10 @@ SYSCALL_DECLARE(wait4)
exit:
return ret;
out_found:
dkprintf("wait4,out_found\n");
ihk_mc_spinlock_unlock_noirq(&child_iter->lock);
out_notfound:
dkprintf("wait4,out_notfound\n");
ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock);
goto exit;
}
@ -526,6 +526,7 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx)
struct process *parent_owner;
int error;
dkprintf("terminate,pid=%d\n", proc->pid);
request.number = __NR_exit_group;
request.args[0] = ((rc & 0x00ff) << 8) | (sig & 0xff);
@ -546,10 +547,14 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx)
list_del(&child->siblings_list);
release_fork_tree_node(child);
}
list_for_each_entry_safe(child, next, &ftn->ptrace_children, ptrace_siblings_list) {
list_del(&child->ptrace_siblings_list);
release_fork_tree_node(child);
}
ftn->owner = NULL;
ihk_mc_spinlock_unlock_noirq(&ftn->lock);
/* Send SIGCHILD to parent */
/* Send SIGCHLD to parent */
if (ftn->parent) {
int parent_owner_pid;
@ -584,19 +589,18 @@ terminate(int rc, int sig, ihk_mc_user_context_t *ctx)
/*
sigchld_parent(ftn->parent->owner, 0);
*/
dkprintf("terminate,klll SIGCHILD,error=%d\n",
dkprintf("terminate,klll SIGCHLD,error=%d\n",
error);
}
release_fork_tree_node(ftn->parent);
} else {
ihk_mc_spinlock_lock_noirq(&ftn->lock);
ftn->status = PS_EXITED;
ihk_mc_spinlock_unlock_noirq(&ftn->lock);
}
release_fork_tree_node(ftn);
proc->status = PS_EXITED;
release_process(proc);
@ -1565,6 +1569,7 @@ unsigned long do_fork(int clone_flags, unsigned long newsp,
cpuid = obtain_clone_cpuid();
if (cpuid == -1) {
kprintf("do_fork,core not available\n");
return -EAGAIN;
}