mirror of
https://github.com/sstefani/mtrace.git
synced 2025-12-06 08:46:41 +08:00
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:
parent
3aed8a6e6b
commit
4fe84ebf6c
1
.gitignore
vendored
1
.gitignore
vendored
@ -35,3 +35,4 @@ mtrace-ng
|
|||||||
debian/files
|
debian/files
|
||||||
debian/mtrace-ng.substvars
|
debian/mtrace-ng.substvars
|
||||||
debian/mtrace-ng
|
debian/mtrace-ng
|
||||||
|
tags
|
||||||
|
|||||||
31
breakpoint.c
31
breakpoint.c
@ -171,6 +171,7 @@ void reorder_hw_bp(struct task *task)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
|
|
||||||
list_for_each(it, &leader->hw_bp_list) {
|
list_for_each(it, &leader->hw_bp_list) {
|
||||||
bp = container_of(it, struct breakpoint, link_list);
|
bp = container_of(it, struct breakpoint, link_list);
|
||||||
if (bp->enabled) {
|
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);
|
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;
|
bp_list[i]->hwcnt = (i < HW_BREAKPOINTS - 1) ? BP_REORDER_THRESHOLD >> (i + 4) : 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (n > HW_BREAKPOINTS - 1)
|
if (n > HW_BREAKPOINTS - 1)
|
||||||
n = HW_BREAKPOINTS - 1;
|
n = HW_BREAKPOINTS - 1;
|
||||||
|
|
||||||
p = bp_list;
|
p = bp_list;
|
||||||
|
|
||||||
for(i = 0; i < n; ++i) {
|
for(i = 0; i < n; ++i) {
|
||||||
if (bp_list[i]->hw) {
|
if (bp_list[i]->hw) {
|
||||||
assert(bp_list[i]->hw_bp_slot != HW_BP_SCRATCH_SLOT);
|
assert(bp_list[i]->hw_bp_slot != HW_BP_SCRATCH_SLOT);
|
||||||
@ -201,14 +205,23 @@ void reorder_hw_bp(struct task *task)
|
|||||||
else
|
else
|
||||||
*p++ = bp_list[i];
|
*p++ = bp_list[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p == bp_list)
|
||||||
|
return;
|
||||||
|
|
||||||
*p = NULL;
|
*p = NULL;
|
||||||
|
|
||||||
|
stop_threads(leader);
|
||||||
|
|
||||||
i = HW_BP_SCRATCH_SLOT + 1;
|
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))
|
while(hw_bp_set & (1 << i))
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
stop_threads(leader);
|
|
||||||
disable_sw_breakpoint(leader, bp);
|
disable_sw_breakpoint(leader, bp);
|
||||||
|
|
||||||
if (leader->hw_bp[i])
|
if (leader->hw_bp[i])
|
||||||
@ -220,7 +233,8 @@ void reorder_hw_bp(struct task *task)
|
|||||||
each_task(leader, enable_hw_bp_cb, bp);
|
each_task(leader, enable_hw_bp_cb, bp);
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
++p;
|
||||||
|
} while(*p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int insert_hw_bp_slot(struct task *task, struct breakpoint *bp)
|
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;
|
break;
|
||||||
|
|
||||||
if (bp->type == BP_HW && leader->hw_bp[i]->type == BP_AUTO) {
|
if (bp->type == BP_HW && leader->hw_bp[i]->type == BP_AUTO) {
|
||||||
stop_threads(leader);
|
|
||||||
hw2sw_bp(leader, leader->hw_bp[i]);
|
hw2sw_bp(leader, leader->hw_bp[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -396,14 +409,14 @@ void breakpoint_enable(struct task *task, struct breakpoint *bp)
|
|||||||
bp->enabled = 1;
|
bp->enabled = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
stop_threads(task);
|
||||||
#if HW_BREAKPOINTS > 1
|
#if HW_BREAKPOINTS > 1
|
||||||
if (bp->type >= BP_HW) {
|
if (bp->type >= BP_HW) {
|
||||||
if (!insert_hw_bp_slot(task, bp))
|
if (!insert_hw_bp_slot(task, bp))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
stop_threads(task);
|
|
||||||
bp->hw = 0;
|
bp->hw = 0;
|
||||||
enable_sw_breakpoint(task, bp);
|
enable_sw_breakpoint(task, bp);
|
||||||
bp->enabled = 1;
|
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);
|
debug(DEBUG_PROCESS, "pid=%d, addr=%#lx", task->pid, bp->addr);
|
||||||
|
|
||||||
if (likely(bp->enabled)) {
|
if (likely(bp->enabled)) {
|
||||||
|
stop_threads(task);
|
||||||
#if HW_BREAKPOINTS > 0
|
#if HW_BREAKPOINTS > 0
|
||||||
if (bp->hw) {
|
if (bp->hw) {
|
||||||
struct task *leader = task->leader;
|
struct task *leader = task->leader;
|
||||||
@ -439,7 +453,6 @@ void breakpoint_disable(struct task *task, struct breakpoint *bp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
stop_threads(task);
|
|
||||||
disable_sw_breakpoint(task, bp);
|
disable_sw_breakpoint(task, bp);
|
||||||
bp->enabled = 0;
|
bp->enabled = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
5
event.c
5
event.c
@ -240,6 +240,11 @@ static int handle_call_after(struct task *task, struct breakpoint *bp)
|
|||||||
if (unlikely(options.verbose > 1))
|
if (unlikely(options.verbose > 1))
|
||||||
start_time(&start);
|
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);
|
task->libsym->func->report_out(task, task->libsym);
|
||||||
|
|
||||||
if (unlikely(options.verbose > 1))
|
if (unlikely(options.verbose > 1))
|
||||||
|
|||||||
@ -609,10 +609,10 @@ done:
|
|||||||
|
|
||||||
int os_task_init(struct task *task)
|
int os_task_init(struct task *task)
|
||||||
{
|
{
|
||||||
struct task *leader = task->leader;
|
if (task == task->leader) {
|
||||||
|
task->os.debug_addr = 0;
|
||||||
leader->os.debug_addr = 0;
|
task->os.debug_state = RT_ADD;
|
||||||
leader->os.debug_state = RT_ADD;
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
46
task.c
46
task.c
@ -131,6 +131,7 @@ static int leader_setup(struct task *leader)
|
|||||||
static int task_init(struct task *task)
|
static int task_init(struct task *task)
|
||||||
{
|
{
|
||||||
pid_t tgid;
|
pid_t tgid;
|
||||||
|
struct task *leader;
|
||||||
|
|
||||||
/* Add process so that we know who the leader is. */
|
/* Add process so that we know who the leader is. */
|
||||||
tgid = process_leader(task->pid);
|
tgid = process_leader(task->pid);
|
||||||
@ -140,7 +141,26 @@ static int task_init(struct task *task)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tgid == task->pid) {
|
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;
|
task->threads = 1;
|
||||||
|
|
||||||
breakpoint_setup(task);
|
breakpoint_setup(task);
|
||||||
@ -148,27 +168,14 @@ static int task_init(struct task *task)
|
|||||||
list_add_tail(&task->leader_list, &list_of_leaders);
|
list_add_tail(&task->leader_list, &list_of_leaders);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
task->leader = pid2task(tgid);
|
leader->threads++;
|
||||||
|
|
||||||
if (!task->leader) {
|
|
||||||
fprintf(stderr, "%s no leader for tgpid=%d\n", __FUNCTION__, tgid);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
task->leader->threads++;
|
|
||||||
task->breakpoints = NULL;
|
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;
|
task->attached = 1;
|
||||||
|
|
||||||
if (arch_task_init(task) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (os_task_init(task) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
breakpoint_hw_destroy(task);
|
breakpoint_hw_destroy(task);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -243,16 +250,17 @@ struct task *task_new(pid_t pid)
|
|||||||
|
|
||||||
library_setup(task);
|
library_setup(task);
|
||||||
|
|
||||||
|
init_event(task);
|
||||||
|
|
||||||
if (task_init(task) < 0)
|
if (task_init(task) < 0)
|
||||||
goto fail1;
|
goto fail1;
|
||||||
|
|
||||||
init_event(task);
|
|
||||||
|
|
||||||
insert_pid(task);
|
insert_pid(task);
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
fail1:
|
fail1:
|
||||||
task_destroy(task);
|
free(task);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user