diff options
author | Eugene Tarassov | 2013-06-08 19:32:11 +0000 |
---|---|---|
committer | Eugene Tarassov | 2013-06-08 19:32:11 +0000 |
commit | 79765261262d7144766c1acefcf13faf96115cb4 (patch) | |
tree | 927118ed3117065297893599e587ff9812007520 | |
parent | 88c11eb62cb4526601c2014bb5fa0bf653c563b2 (diff) | |
download | org.eclipse.tcf.agent-79765261262d7144766c1acefcf13faf96115cb4.tar.gz org.eclipse.tcf.agent-79765261262d7144766c1acefcf13faf96115cb4.tar.xz org.eclipse.tcf.agent-79765261262d7144766c1acefcf13faf96115cb4.zip |
TCF Agent: fixed intermittent assertion failure in ARM stepping logic
-rw-r--r-- | agent/machine/arm/tcf/cpudefs-mdep.c | 33 | ||||
-rw-r--r-- | agent/system/GNU/Linux/tcf/context-linux.c | 8 | ||||
-rw-r--r-- | agent/tcf/framework/cpudefs.c | 4 | ||||
-rw-r--r-- | agent/tcf/framework/cpudefs.h | 4 | ||||
-rw-r--r-- | agent/tcf/services/runctrl.c | 1 |
5 files changed, 28 insertions, 22 deletions
diff --git a/agent/machine/arm/tcf/cpudefs-mdep.c b/agent/machine/arm/tcf/cpudefs-mdep.c index c95f85e5..92a232e4 100644 --- a/agent/machine/arm/tcf/cpudefs-mdep.c +++ b/agent/machine/arm/tcf/cpudefs-mdep.c @@ -28,6 +28,7 @@ #include <tcf/framework/myalloc.h> #include <tcf/framework/trace.h> #include <tcf/services/symbols.h> +#include <tcf/services/runctrl.h> #include <machine/arm/tcf/disassembler-arm.h> #include <machine/arm/tcf/stack-crawl-arm.h> #include <tcf/cpudefs-mdep.h> @@ -226,7 +227,7 @@ static int arm_evaluate_condition (uint32_t opc, uint32_t cpsr) { return 1; } -static ContextAddress arm_get_next_branch (Context * ctx, ContextAddress addr, uint32_t opc, int cond) { +static ContextAddress arm_get_next_branch(Context * ctx, ContextAddress addr, uint32_t opc, int cond) { int32_t imm = opc & 0x00FFFFFF; if (cond == 0) return addr + 4; if (imm & 0x00800000) imm |= 0xFF000000; @@ -234,7 +235,7 @@ static ContextAddress arm_get_next_branch (Context * ctx, ContextAddress addr, u return (ContextAddress)((int)addr + imm + 8); } -static ContextAddress arm_get_next_address (Context * ctx) { +static ContextAddress arm_get_next_address(Context * ctx) { ContextAddress addr; uint32_t opc; ContextAddress cpsr; @@ -244,38 +245,42 @@ static ContextAddress arm_get_next_address (Context * ctx) { if (read_reg(ctx, pc_def, pc_def->size, &addr) < 0) return -1; if (read_reg(ctx, cpsr_def, cpsr_def->size, &cpsr) < 0) return -1; if (context_read_mem(ctx, addr, &opc, sizeof(opc)) < 0) return -1; - trace (LOG_ALWAYS, "pc: 0x%x, opcode 0x%x", (int)addr, (int)opc); + trace(LOG_CONTEXT, "pc: 0x%x, opcode 0x%x", (int)addr, (int)opc); /* decode opcode */ - cond = arm_evaluate_condition (opc, (uint32_t) cpsr); + cond = arm_evaluate_condition(opc, (uint32_t) cpsr); switch (GET_GROUP(opc)) { // case LD_ST_IMM : return get_next_load_store_imm (); - case BRANCH_LINK : return arm_get_next_branch (ctx, addr, opc, cond); + case BRANCH_LINK : return arm_get_next_branch(ctx, addr, opc, cond); } return addr + 4; } -int cpu_enable_stepping_mode (Context * ctx, uint32_t * is_cont) { +int cpu_enable_stepping_mode(Context * ctx, uint32_t * is_cont) { Context * grp = context_get_group(ctx, CONTEXT_GROUP_PROCESS); ContextExtensionARM * ext = EXT(grp); - assert (!ext->stepping); - ext->addr = arm_get_next_address (ctx); - trace (LOG_ALWAYS, "cpu_enable_stepping_mode 0x%x", (int) ext->addr); - if (context_read_mem(ctx, ext->addr, ext->opcode, sizeof(BREAK_INST)) < 0) return -1; - if (context_write_mem(ctx,ext->addr, BREAK_INST, sizeof(BREAK_INST)) < 0) return -1; + assert(!grp->exited); + assert(!ext->stepping); + ext->addr = arm_get_next_address(ctx); + trace(LOG_CONTEXT, "cpu_enable_stepping_mode 0x%x", (int)ext->addr); + if (context_read_mem(grp, ext->addr, ext->opcode, sizeof(BREAK_INST)) < 0) return -1; + if (context_write_mem(grp, ext->addr, BREAK_INST, sizeof(BREAK_INST)) < 0) return -1; ext->stepping = 1; + run_ctrl_lock(); *is_cont = 1; return 0; } -int cpu_disable_stepping_mode (Context * ctx) { +int cpu_disable_stepping_mode(Context * ctx) { Context * grp = context_get_group(ctx, CONTEXT_GROUP_PROCESS); ContextExtensionARM * ext = EXT(grp); - trace (LOG_ALWAYS, "cpu_disable_stepping_mode"); + trace(LOG_CONTEXT, "cpu_disable_stepping_mode"); if (ext->stepping) { + run_ctrl_unlock(); ext->stepping = 0; - return context_write_mem(ctx, ext->addr, ext->opcode, sizeof(BREAK_INST)); + if (grp->exited) return 0; + return context_write_mem(grp, ext->addr, ext->opcode, sizeof(BREAK_INST)); } return 0; } diff --git a/agent/system/GNU/Linux/tcf/context-linux.c b/agent/system/GNU/Linux/tcf/context-linux.c index 926ed45c..c1fe07c9 100644 --- a/agent/system/GNU/Linux/tcf/context-linux.c +++ b/agent/system/GNU/Linux/tcf/context-linux.c @@ -433,11 +433,11 @@ static int do_single_step(Context * ctx) { assert(!ext->pending_step); if (skip_breakpoint(ctx, 1)) return 0; + if (!ctx->stopped) return 0; + if (flush_regs(ctx) < 0) return -1; trace(LOG_CONTEXT, "context: single step ctx %#lx, id %s", ctx, ctx->id); if (cpu_enable_stepping_mode(ctx, &is_cont) < 0) return -1; - if (flush_regs(ctx) < 0) return -1; - if (!ctx->stopped) return 0; if (is_cont) { if (ptrace(PTRACE_CONT, ext->pid, 0, 0) < 0) { int err = errno; @@ -545,6 +545,7 @@ int context_continue(Context * ctx) { add_waitpid_process(ext->pid); } free_regs(ctx); + cpu_disable_stepping_mode(ctx); send_context_exited_event(ctx); send_process_exited_event(prs); } @@ -1033,6 +1034,7 @@ static void event_pid_exited(pid_t pid, int status, int signal) { ctx->exiting = 1; if (ctx->stopped) send_context_started_event(ctx); free_regs(ctx); + cpu_disable_stepping_mode(ctx); send_context_exited_event(ctx); send_process_exited_event(prs); } @@ -1408,8 +1410,8 @@ static void event_pid_stopped(pid_t pid, int signal, int event, int syscall) { else ctx->stopped_by_bp = is_breakpoint_address(ctx, pc1); ext->end_of_step = !ctx->stopped_by_cb && !ctx->stopped_by_bp && ext->pending_step; } - cpu_disable_stepping_mode(ctx); ext->pending_step = 0; + cpu_disable_stepping_mode(ctx); send_context_stopped_event(ctx); } diff --git a/agent/tcf/framework/cpudefs.c b/agent/tcf/framework/cpudefs.c index 17faaca5..b599e52d 100644 --- a/agent/tcf/framework/cpudefs.c +++ b/agent/tcf/framework/cpudefs.c @@ -575,12 +575,12 @@ void write_location_pieces(Context * ctx, StackFrame * frame, } #if !defined(ENABLE_external_stepping_mode) || !ENABLE_external_stepping_mode -int cpu_enable_stepping_mode (Context * ctx, uint32_t * is_cont) { +int cpu_enable_stepping_mode(Context * ctx, uint32_t * is_cont) { * is_cont = 0; return 0; } -int cpu_disable_stepping_mode (Context * ctx) { +int cpu_disable_stepping_mode(Context * ctx) { return 0; } #endif diff --git a/agent/tcf/framework/cpudefs.h b/agent/tcf/framework/cpudefs.h index 1bae50bc..5f0232d5 100644 --- a/agent/tcf/framework/cpudefs.h +++ b/agent/tcf/framework/cpudefs.h @@ -319,10 +319,10 @@ extern int cpu_bp_on_suspend(Context * ctx, int * triggered); /*** CPU external stepping mode API ***/ /* Disable the stepping mode */ -extern int cpu_disable_stepping_mode (Context * ctx); +extern int cpu_disable_stepping_mode(Context * ctx); /* Enable the stepping mode */ -extern int cpu_enable_stepping_mode (Context * ctx, uint32_t * is_cont); +extern int cpu_enable_stepping_mode(Context * ctx, uint32_t * is_cont); /*** Initialization functions ***/ diff --git a/agent/tcf/services/runctrl.c b/agent/tcf/services/runctrl.c index 2e1e0dd5..7f170605 100644 --- a/agent/tcf/services/runctrl.c +++ b/agent/tcf/services/runctrl.c @@ -2116,7 +2116,6 @@ static void event_context_stopped(Context * ctx, void * args) { static void event_context_started(Context * ctx, void * args) { ContextExtensionRC * ext = EXT(ctx); assert(!ctx->stopped); - assert(run_ctrl_lock_cnt == 0 || ext->safe_single_step || ctx->exiting); if (ext->intercepted) resume_context_tree(ctx); ext->intercepted_by_bp = 0; stop_if_safe_events(ctx); |