Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2013-06-08 19:32:11 +0000
committerEugene Tarassov2013-06-08 19:32:11 +0000
commit79765261262d7144766c1acefcf13faf96115cb4 (patch)
tree927118ed3117065297893599e587ff9812007520
parent88c11eb62cb4526601c2014bb5fa0bf653c563b2 (diff)
downloadorg.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.c33
-rw-r--r--agent/system/GNU/Linux/tcf/context-linux.c8
-rw-r--r--agent/tcf/framework/cpudefs.c4
-rw-r--r--agent/tcf/framework/cpudefs.h4
-rw-r--r--agent/tcf/services/runctrl.c1
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);

Back to the top