Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2015-04-16 03:18:02 +0000
committerEugene Tarassov2015-04-16 03:18:02 +0000
commit8694bfb3d2202519243e359c8b96e09f7a5b4bf8 (patch)
tree62b62139ff06ca4d7e00730ff182e12adbe0cc77
parenta99f491aea6606c59b69c228bce59e0c10a955a4 (diff)
downloadorg.eclipse.tcf.agent-8694bfb3d2202519243e359c8b96e09f7a5b4bf8.tar.gz
org.eclipse.tcf.agent-8694bfb3d2202519243e359c8b96e09f7a5b4bf8.tar.xz
org.eclipse.tcf.agent-8694bfb3d2202519243e359c8b96e09f7a5b4bf8.zip
Bug 464388 - Commit bb173cd6d46277f844c0e57934c00ce6730aee4b breaks SkipProlog logic.
-rw-r--r--agent/tcf/services/breakpoints.c54
-rw-r--r--agent/tcf/services/runctrl.c2
2 files changed, 53 insertions, 3 deletions
diff --git a/agent/tcf/services/breakpoints.c b/agent/tcf/services/breakpoints.c
index 2a8cda37..b74313c6 100644
--- a/agent/tcf/services/breakpoints.c
+++ b/agent/tcf/services/breakpoints.c
@@ -47,6 +47,15 @@
#include <tcf/services/memorymap.h>
#include <tcf/services/pathmap.h>
+
+/* ENABLE_SkipPrologueWhenPlanting: select how "skip prologue" is implemented:
+ * 0 - plant breakpoint at function entry, then step until after prologue;
+ * 1 - when planting, adjust breakpoint address to a location right after prologue;
+ */
+#if !defined(ENABLE_SkipPrologueWhenPlanting)
+# define ENABLE_SkipPrologueWhenPlanting 0
+#endif
+
typedef struct BreakpointRef BreakpointRef;
typedef struct InstructionRef InstructionRef;
typedef struct BreakInstruction BreakInstruction;
@@ -224,6 +233,12 @@ static unsigned listener_max = 0;
#define link_bp2hcnt(A) ((BreakpointHitCount *)((char *)(A) - offsetof(BreakpointHitCount, link_bp)))
#define link_ctx2hcnt(A) ((BreakpointHitCount *)((char *)(A) - offsetof(BreakpointHitCount, link_ctx)))
+#if ENABLE_SkipPrologueWhenPlanting
+# define suspend_by_bp(ctx, trigger, bp, skip_prologue) suspend_by_breakpoint(ctx, trigger, bp, 0)
+#else
+# define suspend_by_bp(ctx, trigger, bp, skip_prologue) suspend_by_breakpoint(ctx, trigger, bp, skip_prologue)
+#endif
+
static LINK breakpoints = TCF_LIST_INIT(breakpoints);
static LINK id2bp[ID2BP_HASH_SIZE];
@@ -1318,7 +1333,7 @@ static void done_condition_evaluation(EvaluationRequest * req) {
else {
assert(bp->id[0] != 0);
req->bp_arr[i].triggered = 1;
- if (bp->stop_group == NULL) suspend_by_breakpoint(ctx, ctx, bp->id, bp->skip_prologue);
+ if (bp->stop_group == NULL) suspend_by_bp(ctx, ctx, bp->id, bp->skip_prologue);
}
}
}
@@ -1350,7 +1365,7 @@ static void done_all_evaluations(void) {
while (*ids) {
Context * c = id2ctx(*ids++);
if (c == NULL) continue;
- suspend_by_breakpoint(c, ctx, bp->id, bp->skip_prologue);
+ suspend_by_bp(c, ctx, bp->id, bp->skip_prologue);
}
}
if (bp->temporary) {
@@ -1372,6 +1387,35 @@ static void done_all_evaluations(void) {
}
}
+#if ENABLE_SkipPrologueWhenPlanting
+
+static void function_prolog_line_info(CodeArea * area, void * args) {
+ CodeArea * res = (CodeArea *)args;
+ if (res->file != NULL) return;
+ *res = *area;
+}
+
+static int skip_function_prologue(Context * ctx, Symbol * sym, ContextAddress * addr) {
+#if ENABLE_Symbols
+ int sym_class = SYM_CLASS_UNKNOWN;
+ ContextAddress sym_size = 0;
+ CodeArea area;
+
+ if (get_symbol_class(sym, &sym_class) < 0) return -1;
+ if (sym_class != SYM_CLASS_FUNCTION) return 0;
+ if (get_symbol_size(sym, &sym_size) < 0) return -1;
+ if (sym_size == 0) return 0;
+ memset(&area, 0, sizeof(area));
+ if (address_to_line(ctx, *addr, *addr + 1, function_prolog_line_info, &area) < 0) return -1;
+ if (area.start_address > *addr || area.end_address <= *addr) return 0;
+ if (*addr + sym_size <= area.end_address) return 0;
+ *addr = area.end_address;
+#endif
+ return 0;
+}
+
+#endif /* ENABLE_SkipPrologueWhenPlanting */
+
static void plant_at_address_expression(Context * ctx, ContextAddress ip, BreakpointInfo * bp) {
ContextAddress addr = 0;
ContextAddress size = 1;
@@ -1380,6 +1424,9 @@ static void plant_at_address_expression(Context * ctx, ContextAddress ip, Breakp
if (evaluate_expression(ctx, STACK_NO_FRAME, ip, bp->location, 1, &v) < 0) error = errno;
if (!error && value_to_address(&v, &addr) < 0) error = errno;
+#if ENABLE_SkipPrologueWhenPlanting
+ if (!error && bp->skip_prologue && v.sym != NULL && skip_function_prologue(ctx, v.sym, &addr) < 0) error = errno;
+#endif
if (bp->access_size > 0) {
size = bp->access_size;
}
@@ -1410,6 +1457,9 @@ static void plant_at_address_expression(Context * ctx, ContextAddress ip, Breakp
while (v.sym_list[n] != NULL) {
Symbol * sym = v.sym_list[n++];
if (get_symbol_address(sym, &addr) == 0) {
+#if ENABLE_SkipPrologueWhenPlanting
+ if (bp->skip_prologue) skip_function_prologue(ctx, sym, &addr);
+#endif
plant_breakpoint(ctx, bp, addr, size);
}
}
diff --git a/agent/tcf/services/runctrl.c b/agent/tcf/services/runctrl.c
index bd20ffe1..3598a9c0 100644
--- a/agent/tcf/services/runctrl.c
+++ b/agent/tcf/services/runctrl.c
@@ -1978,7 +1978,7 @@ static int update_step_machine_state(Context * ctx) {
if (address_to_line(ctx, addr, addr + 1, get_machine_code_area, &area) < 0) return -1;
if (area == NULL || !is_function_prologue(ctx, addr, area)) {
ctx->pending_intercept = 1;
- ext->step_done = REASON_STEP;
+ ext->step_done = REASON_USER_REQUEST;
return 0;
}
}

Back to the top