fix exec handling

This commit is contained in:
Stefani Seibold 2015-05-04 12:12:12 +02:00
parent 68697f0d09
commit 6bc375640c

75
task.c
View File

@ -176,21 +176,23 @@ static int task_init(struct task *task, int attached)
static void leader_cleanup(struct task *task) static void leader_cleanup(struct task *task)
{ {
assert(task->leader); if (!task->leader)
return;
task->leader->threads--; task->leader->threads--;
if (task->leader == task) { if (task->leader != task)
if (task->breakpoint) { return;
breakpoint_delete(task, task->breakpoint);
task->breakpoint = NULL;
}
library_clear_all(task); if (task->breakpoint) {
breakpoint_clear_all(task); breakpoint_delete(task, task->breakpoint);
task->breakpoint = NULL;
list_del(&task->leader_list);
} }
library_clear_all(task);
breakpoint_clear_all(task);
list_del(&task->leader_list);
} }
static void task_destroy(struct task *task) static void task_destroy(struct task *task)
@ -198,8 +200,8 @@ static void task_destroy(struct task *task)
backtrace_destroy(task); backtrace_destroy(task);
arch_task_destroy(task); arch_task_destroy(task);
os_task_destroy(task); os_task_destroy(task);
leader_cleanup(task);
detach_task(task); detach_task(task);
leader_cleanup(task);
list_del(&task->task_list); list_del(&task->task_list);
rb_erase(&task->pid_node, &pid_tree); rb_erase(&task->pid_node, &pid_tree);
free(task); free(task);
@ -237,29 +239,43 @@ fail1:
return NULL; return NULL;
} }
static void remove_task_cb(struct task *task, void *data)
{
if (task != data) {
debug(DEBUG_FUNCTION, "clear pid=%d from leader pid=%d", task->pid, task->leader->pid);
remove_task(task);
}
}
int process_exec(struct task *task) int process_exec(struct task *task)
{ {
assert(task->leader == task); struct task *leader = task->leader;
task->threads_stopped--; leader->threads_stopped--;
breakpoint_hw_destroy(task); breakpoint_disable_all(leader);
backtrace_destroy(task); each_task(leader, &remove_task_cb, leader);
os_task_destroy(task);
arch_task_destroy(task);
leader_cleanup(task);
if (task_init(task, 0) < 0) backtrace_destroy(leader);
return -1; os_task_destroy(leader);
arch_task_destroy(leader);
leader_cleanup(leader);
assert(task->leader == task); if (task_init(leader, 0) < 0)
goto fail;
task->threads_stopped++; assert(leader->leader == leader);
if (leader_setup(task) < 0) leader->threads_stopped++;
return -1;
if (leader_setup(leader) < 0)
goto fail;
return 0; return 0;
fail:
task_destroy(leader);
return -1;
} }
struct task *task_create(const char *command, char **argv) struct task *task_create(const char *command, char **argv)
@ -523,15 +539,6 @@ void remove_task(struct task *task)
task_destroy(task); task_destroy(task);
} }
static void clear_leader(struct task *task, void *data)
{
if (task != data) {
debug(DEBUG_FUNCTION, "clear pid=%d from leader pid=%d", task->pid, task->leader->pid);
remove_task(task);
}
}
void remove_proc(struct task *leader) void remove_proc(struct task *leader)
{ {
debug(DEBUG_FUNCTION, "pid=%d", leader->pid); debug(DEBUG_FUNCTION, "pid=%d", leader->pid);
@ -539,7 +546,7 @@ void remove_proc(struct task *leader)
assert(leader->leader == leader); assert(leader->leader == leader);
breakpoint_disable_all(leader); breakpoint_disable_all(leader);
each_task(leader, &clear_leader, leader); each_task(leader, &remove_task_cb, leader);
remove_task(leader); remove_task(leader);
} }