Skip to content
Permalink
Browse files

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
  • Loading branch information...
sstefani committed Nov 26, 2015
1 parent 3aed8a6 commit 4fe84ebf6c9cc62f36ed272a1317475a524334d1
Showing with 57 additions and 30 deletions.
  1. +1 −0 .gitignore
  2. +22 −9 breakpoint.c
  3. +5 −0 event.c
  4. +4 −4 sysdeps/linux-gnu/proc.c
  5. +25 −17 task.c
@@ -35,3 +35,4 @@ mtrace-ng
debian/files
debian/mtrace-ng.substvars
debian/mtrace-ng
tags
@@ -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;
}
@@ -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))
@@ -609,10 +609,10 @@ int process_get_entry(struct task *task, unsigned long *entryp, unsigned long *i

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;
}

42 task.c
@@ -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,35 +141,41 @@ static int task_init(struct task *task)
}

if (tgid == task->pid) {
task->leader = task;
task->threads = 1;

breakpoint_setup(task);

list_add_tail(&task->leader_list, &list_of_leaders);
leader = task;
}
else {
task->leader = pid2task(tgid);
leader = pid2task(tgid);

if (!task->leader) {
if (!leader) {
fprintf(stderr, "%s no leader for tgpid=%d\n", __FUNCTION__, tgid);
return -1;
}

task->leader->threads++;
task->breakpoints = NULL;

list_add_tail(&task->task_list, &task->leader->task_list);
}

task->attached = 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);

list_add_tail(&task->leader_list, &list_of_leaders);
}
else {
leader->threads++;
task->breakpoints = NULL;

list_add_tail(&task->task_list, &leader->task_list);
}

task->attached = 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;
}

0 comments on commit 4fe84eb

Please sign in to comment.
You can’t perform that action at this time.