minor bug fixes

fix a crash on a race condition during new task creation
disable scratch hw bp after use
always stop threads when change a non scratch hw bp
only change os specific data for the leader
This commit is contained in:
Stefani Seibold 2015-11-26 08:02:40 +01:00
parent 3aed8a6e6b
commit 4fe84ebf6c
5 changed files with 59 additions and 32 deletions

1
.gitignore vendored
View File

@ -35,3 +35,4 @@ mtrace-ng
debian/files
debian/mtrace-ng.substvars
debian/mtrace-ng
tags

View File

@ -171,6 +171,7 @@ void reorder_hw_bp(struct task *task)
return;
n = 0;
list_for_each(it, &leader->hw_bp_list) {
bp = container_of(it, struct breakpoint, link_list);
if (bp->enabled) {
@ -180,16 +181,19 @@ void reorder_hw_bp(struct task *task)
}
}
if (!n)
return;
qsort(bp_list, n, sizeof(*bp_list), hw_bp_sort);
for(i = 0; i < n; ++i) {
for(i = 0; i < n; ++i)
bp_list[i]->hwcnt = (i < HW_BREAKPOINTS - 1) ? BP_REORDER_THRESHOLD >> (i + 4) : 0;
}
if (n > HW_BREAKPOINTS - 1)
n = HW_BREAKPOINTS - 1;
p = bp_list;
for(i = 0; i < n; ++i) {
if (bp_list[i]->hw) {
assert(bp_list[i]->hw_bp_slot != HW_BP_SCRATCH_SLOT);
@ -201,14 +205,23 @@ void reorder_hw_bp(struct task *task)
else
*p++ = bp_list[i];
}
if (p == bp_list)
return;
*p = NULL;
stop_threads(leader);
i = HW_BP_SCRATCH_SLOT + 1;
for(p = bp_list; (bp = *p); ++p) {
p = bp_list;
do {
bp = *p;
while(hw_bp_set & (1 << i))
++i;
stop_threads(leader);
disable_sw_breakpoint(leader, bp);
if (leader->hw_bp[i])
@ -220,7 +233,8 @@ void reorder_hw_bp(struct task *task)
each_task(leader, enable_hw_bp_cb, bp);
++i;
}
++p;
} while(*p);
}
static int insert_hw_bp_slot(struct task *task, struct breakpoint *bp)
@ -233,7 +247,6 @@ static int insert_hw_bp_slot(struct task *task, struct breakpoint *bp)
break;
if (bp->type == BP_HW && leader->hw_bp[i]->type == BP_AUTO) {
stop_threads(leader);
hw2sw_bp(leader, leader->hw_bp[i]);
break;
}
@ -396,14 +409,14 @@ void breakpoint_enable(struct task *task, struct breakpoint *bp)
bp->enabled = 1;
return;
}
#endif
stop_threads(task);
#if HW_BREAKPOINTS > 1
if (bp->type >= BP_HW) {
if (!insert_hw_bp_slot(task, bp))
return;
}
#endif
#endif
stop_threads(task);
bp->hw = 0;
enable_sw_breakpoint(task, bp);
bp->enabled = 1;
@ -418,6 +431,7 @@ void breakpoint_disable(struct task *task, struct breakpoint *bp)
debug(DEBUG_PROCESS, "pid=%d, addr=%#lx", task->pid, bp->addr);
if (likely(bp->enabled)) {
stop_threads(task);
#if HW_BREAKPOINTS > 0
if (bp->hw) {
struct task *leader = task->leader;
@ -439,7 +453,6 @@ void breakpoint_disable(struct task *task, struct breakpoint *bp)
return;
}
#endif
stop_threads(task);
disable_sw_breakpoint(task, bp);
bp->enabled = 0;
}

View File

@ -240,6 +240,11 @@ static int handle_call_after(struct task *task, struct breakpoint *bp)
if (unlikely(options.verbose > 1))
start_time(&start);
#if HW_BREAKPOINTS > 0
if (bp->hw)
disable_scratch_hw_bp(task, bp);
#endif
task->libsym->func->report_out(task, task->libsym);
if (unlikely(options.verbose > 1))

View File

@ -609,10 +609,10 @@ done:
int os_task_init(struct task *task)
{
struct task *leader = task->leader;
leader->os.debug_addr = 0;
leader->os.debug_state = RT_ADD;
if (task == task->leader) {
task->os.debug_addr = 0;
task->os.debug_state = RT_ADD;
}
return 0;
}

46
task.c
View File

@ -131,6 +131,7 @@ static int leader_setup(struct task *leader)
static int task_init(struct task *task)
{
pid_t tgid;
struct task *leader;
/* Add process so that we know who the leader is. */
tgid = process_leader(task->pid);
@ -140,7 +141,26 @@ static int task_init(struct task *task)
}
if (tgid == task->pid) {
task->leader = task;
leader = task;
}
else {
leader = pid2task(tgid);
if (!leader) {
fprintf(stderr, "%s no leader for tgpid=%d\n", __FUNCTION__, tgid);
return -1;
}
}
task->leader = leader;
if (arch_task_init(task) < 0)
return -1;
if (os_task_init(task) < 0)
return -1;
if (task == leader) {
task->threads = 1;
breakpoint_setup(task);
@ -148,27 +168,14 @@ static int task_init(struct task *task)
list_add_tail(&task->leader_list, &list_of_leaders);
}
else {
task->leader = pid2task(tgid);
if (!task->leader) {
fprintf(stderr, "%s no leader for tgpid=%d\n", __FUNCTION__, tgid);
return -1;
}
task->leader->threads++;
leader->threads++;
task->breakpoints = NULL;
list_add_tail(&task->task_list, &task->leader->task_list);
list_add_tail(&task->task_list, &leader->task_list);
}
task->attached = 1;
if (arch_task_init(task) < 0)
return -1;
if (os_task_init(task) < 0)
return -1;
breakpoint_hw_destroy(task);
return 0;
@ -243,16 +250,17 @@ struct task *task_new(pid_t pid)
library_setup(task);
init_event(task);
if (task_init(task) < 0)
goto fail1;
init_event(task);
insert_pid(task);
return task;
fail1:
task_destroy(task);
free(task);
return NULL;
}