Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/tcf/framework/cpudefs.c41
-rw-r--r--agent/tcf/framework/cpudefs.h14
-rw-r--r--agent/tcf/services/breakpoints.c81
-rw-r--r--agent/tcf/services/symbols_elf.c11
-rw-r--r--agent/tcf/services/symbols_mux.c14
-rw-r--r--agent/tcf/services/symbols_proxy.c25
6 files changed, 108 insertions, 78 deletions
diff --git a/agent/tcf/framework/cpudefs.c b/agent/tcf/framework/cpudefs.c
index d7b68b9a..30ef7515 100644
--- a/agent/tcf/framework/cpudefs.c
+++ b/agent/tcf/framework/cpudefs.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2016 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2017 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -85,31 +85,54 @@ int write_reg_value(StackFrame * frame, RegisterDefinition * reg_def, uint64_t v
}
ContextAddress get_regs_PC(Context * ctx) {
+ ContextAddress pc = 0;
+ if (get_PC(ctx, &pc) < 0) return 0;
+ return pc;
+}
+
+void set_regs_PC(Context * ctx, ContextAddress pc) {
+ set_PC(ctx, pc);
+}
+
+int get_PC(Context * ctx, ContextAddress * p) {
size_t i;
uint8_t buf[8];
ContextAddress pc = 0;
RegisterDefinition * def = get_PC_definition(ctx);
- if (def == NULL) return 0;
- assert(def->size <= sizeof(buf));
- if (context_read_reg(ctx, def, 0, def->size, buf) < 0) return 0;
+ if (def == NULL) {
+ set_errno(ERR_OTHER, "Cannot read PC: no such register");
+ return -1;
+ }
+ if (def->size > sizeof(buf)) {
+ set_errno(ERR_OTHER, "Cannot read PC: register is too large");
+ return -1;
+ }
+ if (context_read_reg(ctx, def, 0, def->size, buf) < 0) return -1;
for (i = 0; i < def->size; i++) {
pc = pc << 8;
pc |= buf[def->big_endian ? i : def->size - i - 1];
}
- return pc;
+ *p = pc;
+ return 0;
}
-void set_regs_PC(Context * ctx, ContextAddress pc) {
+int set_PC(Context * ctx, ContextAddress pc) {
size_t i;
uint8_t buf[8];
RegisterDefinition * def = get_PC_definition(ctx);
- if (def == NULL) return;
- assert(def->size <= sizeof(buf));
+ if (def == NULL) {
+ set_errno(ERR_OTHER, "Cannot write PC: no such register");
+ return -1;
+ }
+ if (def->size > sizeof(buf)) {
+ set_errno(ERR_OTHER, "Cannot write PC: register is too large");
+ return -1;
+ }
for (i = 0; i < def->size; i++) {
buf[def->big_endian ? def->size - i - 1 : i] = (uint8_t)pc;
pc = pc >> 8;
}
- context_write_reg(ctx, def, 0, def->size, buf);
+ return context_write_reg(ctx, def, 0, def->size, buf);
}
int id2frame(const char * id, Context ** ctx, int * frame) {
diff --git a/agent/tcf/framework/cpudefs.h b/agent/tcf/framework/cpudefs.h
index de4b4bb6..749e94c9 100644
--- a/agent/tcf/framework/cpudefs.h
+++ b/agent/tcf/framework/cpudefs.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2016 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2017 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -265,12 +265,20 @@ extern int write_reg_bytes(StackFrame * frame, RegisterDefinition * reg_def, uns
extern int write_reg_location(StackFrame * frame, RegisterDefinition * reg_def, LocationExpressionCommand * cmds, unsigned cmds_cnt);
#endif
-/* Get instruction pointer (PC) value */
+/* Get instruction pointer (PC) value.
+* Deprecated: use get_PC() */
extern ContextAddress get_regs_PC(Context * ctx);
-/* Set instruction pointer (PC) value */
+/* Set instruction pointer (PC) value.
+ * Deprecated: use set_PC() */
extern void set_regs_PC(Context * ctx, ContextAddress y);
+/* Get instruction pointer (PC) value, return 0 on success, return -1 and set errno on error */
+extern int get_PC(Context * ctx, ContextAddress * pc);
+
+/* Set instruction pointer (PC) value, return 0 on success, return -1 and set errno on error */
+extern int set_PC(Context * ctx, ContextAddress pc);
+
/* Get TCF ID of a stack frame */
extern const char * frame2id(Context * ctx, int frame);
diff --git a/agent/tcf/services/breakpoints.c b/agent/tcf/services/breakpoints.c
index 2efe57af..dd880a35 100644
--- a/agent/tcf/services/breakpoints.c
+++ b/agent/tcf/services/breakpoints.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2016 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2017 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -294,10 +294,10 @@ static int print_not_stopped_contexts(Context * ctx) {
if (is_all_stopped(ctx)) return 1;
grp = context_get_group(ctx, CONTEXT_GROUP_STOP);
for (l = context_root.next; l != &context_root; l = l->next) {
- Context * ctx = ctxl2ctxp(l);
- if (context_get_group(ctx, CONTEXT_GROUP_STOP) != grp) continue;
+ Context * c = ctxl2ctxp(l);
+ if (context_get_group(c, CONTEXT_GROUP_STOP) != grp) continue;
printf("ID %s, stopped %d, exiting %d, exited %d, signal %d\n",
- ctx->id, ctx->stopped, ctx->exiting, ctx->exited, ctx->signal);
+ c->id, c->stopped, c->exiting, c->exited, c->signal);
}
return 0;
}
@@ -992,11 +992,11 @@ static void write_breakpoint_status(OutputStream * out, BreakpointInfo * bp) {
#if ENABLE_ExtendedBreakpointStatus
if (bi->saved_size == 0) {
/* Back-end context breakpoint status */
- int cnt = 0;
+ int st_len = 0;
const char ** names = NULL;
const char ** values = NULL;
- if (context_get_breakpoint_status(&bi->cb, &names, &values, &cnt) == 0) {
- while (cnt > 0) {
+ if (context_get_breakpoint_status(&bi->cb, &names, &values, &st_len) == 0) {
+ while (st_len > 0) {
if (*values != NULL) {
if (strcmp (*names, "BreakpointType") == 0) bp_type_is_set = 1;
write_stream(out, ',');
@@ -1006,7 +1006,7 @@ static void write_breakpoint_status(OutputStream * out, BreakpointInfo * bp) {
}
names++;
values++;
- cnt--;
+ st_len--;
}
}
}
@@ -1347,8 +1347,8 @@ static void post_location_evaluation_request(Context * ctx, BreakpointInfo * bp)
int bp_found = 0;
LINK * l = breakpoints.next;
while (l != &breakpoints) {
- BreakpointInfo * bp = link_all2bp(l);
- if (!is_disabled(bp) && (bp->context_query || check_context_ids_location(bp, grp))) {
+ BreakpointInfo * b = link_all2bp(l);
+ if (!is_disabled(b) && (b->context_query || check_context_ids_location(b, grp))) {
bp_found = 1;
break;
}
@@ -2909,9 +2909,6 @@ int is_breakpoint_address(Context * ctx, ContextAddress address) {
void evaluate_breakpoint(Context * ctx) {
unsigned i;
- Context * mem = NULL;
- ContextAddress mem_addr = 0;
- BreakInstruction * bi = NULL;
Context * grp = context_get_group(ctx, CONTEXT_GROUP_BREAKPOINT);
EvaluationRequest * req = create_evaluation_request(grp);
int already_posted = !list_is_empty(&req->link_posted) || !list_is_empty(&req->link_active);
@@ -2921,10 +2918,24 @@ void evaluate_breakpoint(Context * ctx) {
assert(ctx->stopped);
assert(ctx->stopped_by_bp || ctx->stopped_by_cb);
assert(ctx->exited == 0);
+ assert(!is_intercepted(ctx));
if (ctx->stopped_by_bp) {
- if (context_get_canonical_addr(ctx, get_regs_PC(ctx), &mem, &mem_addr, NULL, NULL) < 0) return;
- bi = find_instruction(mem, 0, mem_addr, CTX_BP_ACCESS_INSTRUCTION, 1);
+ Context * mem = NULL;
+ ContextAddress mem_addr = 0;
+ ContextAddress pc = 0;
+ BreakInstruction * bi = NULL;
+ if (get_PC(ctx, &pc) < 0 ||
+ context_get_canonical_addr(ctx, pc, &mem, &mem_addr, NULL, NULL) < 0) {
+ int error = set_errno(errno, "Cannot evaluate breakpoint");
+ ctx->pending_intercept = 1;
+ ctx->stopped_by_exception = 1;
+ loc_free(ctx->exception_description);
+ ctx->exception_description = loc_strdup(errno_to_str(error));
+ }
+ else {
+ bi = find_instruction(mem, 0, mem_addr, CTX_BP_ACCESS_INSTRUCTION, 1);
+ }
if (bi != NULL && bi->planted) {
assert(bi->valid);
for (i = 0; i < bi->ref_cnt; i++) {
@@ -2948,7 +2959,7 @@ void evaluate_breakpoint(Context * ctx) {
int j;
assert(ctx->stopped_by_cb[0] != NULL);
for (j = 0; ctx->stopped_by_cb[j]; j++) {
- bi = (BreakInstruction *)((char *)ctx->stopped_by_cb[j] - offsetof(BreakInstruction, cb));
+ BreakInstruction * bi = (BreakInstruction *)((char *)ctx->stopped_by_cb[j] - offsetof(BreakInstruction, cb));
assert(bi->planted);
for (i = 0; i < bi->ref_cnt; i++) {
if (bi->refs[i].ctx == grp) {
@@ -2974,13 +2985,13 @@ void evaluate_breakpoint(Context * ctx) {
else {
done_condition_evaluation(req);
for (i = 0; i < req->bp_cnt; i++) {
- Context * ctx = req->bp_arr[i].ctx;
+ Context * c = req->bp_arr[i].ctx;
BreakpointInfo * bp = req->bp_arr[i].bp;
if (bp->status_changed && generation_done == generation_posted) {
assert(bp->client_cnt > 0);
notify_breakpoint_status(bp);
}
- context_unlock(ctx);
+ context_unlock(c);
}
req->bp_cnt = 0;
}
@@ -2999,8 +3010,9 @@ static void safe_restore_breakpoint(void * arg) {
if (!ctx->exiting && ctx->stopped && !ctx->stopped_by_exception && !ctx->advanced) {
Context * mem = NULL;
ContextAddress mem_addr = 0;
- ContextAddress pc = get_regs_PC(ctx);
- if (context_get_canonical_addr(ctx, pc, &mem, &mem_addr, NULL, NULL) == 0 &&
+ ContextAddress pc = 0;
+ if (get_PC(ctx, &pc) == 0 &&
+ context_get_canonical_addr(ctx, pc, &mem, &mem_addr, NULL, NULL) == 0 &&
bi->cb.ctx == mem && bi->cb.address == mem_addr) {
if (ext->step_over_bp_cnt < 100) {
ext->step_over_bp_cnt++;
@@ -3025,10 +3037,7 @@ static void safe_skip_breakpoint(void * arg) {
ContextExtensionBP * ext = EXT(ctx);
BreakInstruction * bi = ext->stepping_over_bp;
int error = 0;
-#ifndef NDEBUG
- Context * mem = NULL;
- ContextAddress mem_addr = 0;
-#endif
+
assert(bi != NULL);
assert(bi->stepping_over_bp > 0);
assert(find_instruction(bi->cb.ctx, 0, bi->cb.address, bi->cb.access_types, bi->cb.length) == bi);
@@ -3037,10 +3046,19 @@ static void safe_skip_breakpoint(void * arg) {
if (ctx->exited || ctx->exiting) return;
- assert(ctx->stopped);
- assert(!is_intercepted(ctx));
- assert(context_get_canonical_addr(ctx, get_regs_PC(ctx), &mem, &mem_addr, NULL, NULL) == 0);
- assert(bi->cb.address == mem_addr);
+#ifndef NDEBUG
+ {
+ Context * mem = NULL;
+ ContextAddress mem_addr = 0;
+ ContextAddress pc = 0;
+ assert(ctx->stopped);
+ assert(!is_intercepted(ctx));
+ if (get_PC(ctx, &pc) == 0) {
+ assert(context_get_canonical_addr(ctx, pc, &mem, &mem_addr, NULL, NULL) == 0);
+ assert(bi->cb.address == mem_addr);
+ }
+ }
+#endif
if (bi->planted && remove_instruction(bi) < 0) error = errno;
if (error == 0 && safe_context_single_step(ctx) < 0) error = errno;
@@ -3050,11 +3068,10 @@ static void safe_skip_breakpoint(void * arg) {
ctx->stopped = 1;
ctx->stopped_by_bp = 0;
ctx->stopped_by_cb = NULL;
- ctx->stopped_by_exception = 1;
ctx->pending_intercept = 1;
+ ctx->stopped_by_exception = 1;
loc_free(ctx->exception_description);
ctx->exception_description = loc_strdup(errno_to_str(error));
- send_context_changed_event(ctx);
}
}
@@ -3069,6 +3086,7 @@ static void safe_skip_breakpoint(void * arg) {
int skip_breakpoint(Context * ctx, int single_step) {
ContextExtensionBP * ext = EXT(ctx);
Context * mem = NULL;
+ ContextAddress pc = 0;
ContextAddress mem_addr = 0;
BreakInstruction * bi;
@@ -3080,7 +3098,8 @@ int skip_breakpoint(Context * ctx, int single_step) {
if (!ctx->stopped_by_bp && ctx->stopped_by_cb == NULL) return 0;
if (ctx->exited || ctx->exiting) return 0;
- if (context_get_canonical_addr(ctx, get_regs_PC(ctx), &mem, &mem_addr, NULL, NULL) < 0) return -1;
+ if (get_PC(ctx, &pc) < 0) return -1;
+ if (context_get_canonical_addr(ctx, pc, &mem, &mem_addr, NULL, NULL) < 0) return -1;
bi = find_instruction(mem, 0, mem_addr, CTX_BP_ACCESS_INSTRUCTION, 1);
if (bi == NULL || bi->planting_error) return 0;
bi->stepping_over_bp++;
diff --git a/agent/tcf/services/symbols_elf.c b/agent/tcf/services/symbols_elf.c
index 880a979e..b5f79f7d 100644
--- a/agent/tcf/services/symbols_elf.c
+++ b/agent/tcf/services/symbols_elf.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2015 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2017 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -211,7 +211,6 @@ static int get_sym_context(Context * ctx, int frame, ContextAddress addr) {
sym_ip = addr;
}
else if (is_top_frame(ctx, frame)) {
- unsigned cnt = cache_miss_count();
if (!ctx->stopped) {
errno = ERR_IS_RUNNING;
return -1;
@@ -220,13 +219,7 @@ static int get_sym_context(Context * ctx, int frame, ContextAddress addr) {
errno = ERR_ALREADY_EXITED;
return -1;
}
- sym_ip = get_regs_PC(ctx);
- if (cache_miss_count() > cnt) {
- /* The value of the PC (0) is incorrect. */
- /* errno should already be set to a value different from 0 */
- assert(errno != 0);
- return -1;
- }
+ if (get_PC(ctx, &sym_ip) < 0) return -1;
}
else {
U8_T ip = 0;
diff --git a/agent/tcf/services/symbols_mux.c b/agent/tcf/services/symbols_mux.c
index 65b96466..cabcd353 100644
--- a/agent/tcf/services/symbols_mux.c
+++ b/agent/tcf/services/symbols_mux.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2015 Wind River Systems, Inc. and others.
+ * Copyright (c) 2012, 2017 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -46,7 +46,6 @@ static int get_sym_addr(Context * ctx, int frame, ContextAddress addr, ContextAd
*sym_addr = addr;
}
else if (is_top_frame(ctx, frame)) {
- unsigned cnt = cache_miss_count();
if (!ctx->stopped) {
errno = ERR_IS_RUNNING;
return -1;
@@ -55,20 +54,15 @@ static int get_sym_addr(Context * ctx, int frame, ContextAddress addr, ContextAd
errno = ERR_ALREADY_EXITED;
return -1;
}
- *sym_addr = get_regs_PC(ctx);
- if (cache_miss_count() > cnt) {
- /* The value of the PC (0) is incorrect. */
- /* errno should already be set to a value different from 0 */
- assert(errno != 0);
- return -1;
- }
+ if (get_PC(ctx, sym_addr) < 0) return -1;
}
else {
uint64_t ip = 0;
StackFrame * info = NULL;
if (get_frame_info(ctx, frame, &info) < 0) return -1;
if (read_reg_value(info, get_PC_definition(ctx), &ip) < 0) return -1;
- if (!info->is_top_frame && ip > 0) ip--;
+ assert(!info->is_top_frame);
+ if (ip > 0) ip--;
*sym_addr = (ContextAddress)ip;
}
return 0;
diff --git a/agent/tcf/services/symbols_proxy.c b/agent/tcf/services/symbols_proxy.c
index 123d6a2b..32684729 100644
--- a/agent/tcf/services/symbols_proxy.c
+++ b/agent/tcf/services/symbols_proxy.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2016 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2017 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -622,30 +622,23 @@ static Channel * get_channel(SymbolsCache * syms) {
static uint64_t get_symbol_ip(Context * ctx, int * frame, ContextAddress addr) {
uint64_t ip = 0;
if (*frame == STACK_NO_FRAME) {
- ip = addr;
+ ip = (uint64_t)addr;
}
else if (is_top_frame(ctx, *frame)) {
- unsigned cnt = cache_miss_count();
- if (!ctx->stopped) {
- exception(ERR_IS_RUNNING);
- }
- if (ctx->exited) {
- exception(ERR_ALREADY_EXITED);
- }
+ ContextAddress pc = 0;
+ if (!ctx->stopped) exception(ERR_IS_RUNNING);
+ if (ctx->exited) exception(ERR_ALREADY_EXITED);
*frame = get_top_frame(ctx);
- ip = get_regs_PC(ctx);
- if (cache_miss_count() > cnt) {
- /* The value of the PC (0) is incorrect. */
- /* errno should already be set to a value different from 0 */
- assert(errno != 0);
- exception(errno);
- }
+ if (get_PC(ctx, &pc) < 0) exception(errno);
+ ip = (uint64_t)pc;
}
else {
StackFrame * info = NULL;
if (get_frame_info(ctx, *frame, &info) < 0) exception(errno);
if (read_reg_value(info, get_PC_definition(ctx), &ip) < 0) exception(errno);
+ assert(!info->is_top_frame);
*frame = info->frame;
+ if (ip > 0) ip--;
}
return ip;
}

Back to the top