diff options
author | Eugene Tarassov | 2015-04-16 03:18:02 +0000 |
---|---|---|
committer | Eugene Tarassov | 2015-04-16 03:18:02 +0000 |
commit | 8694bfb3d2202519243e359c8b96e09f7a5b4bf8 (patch) | |
tree | 62b62139ff06ca4d7e00730ff182e12adbe0cc77 | |
parent | a99f491aea6606c59b69c228bce59e0c10a955a4 (diff) | |
download | org.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.c | 54 | ||||
-rw-r--r-- | agent/tcf/services/runctrl.c | 2 |
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; } } |