Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2012-10-05 21:12:37 +0000
committerEugene Tarassov2012-10-05 21:12:37 +0000
commit146f189581fe8e756359cce185388609b693ec4a (patch)
tree8d9345447e399ee92fd964045a9f2a32b62e1e51 /agent/tcf/services
parentfe66b5deb91158f76b444bff426486a0283531f2 (diff)
downloadorg.eclipse.tcf.agent-146f189581fe8e756359cce185388609b693ec4a.tar.gz
org.eclipse.tcf.agent-146f189581fe8e756359cce185388609b693ec4a.tar.xz
org.eclipse.tcf.agent-146f189581fe8e756359cce185388609b693ec4a.zip
TCF Agent: function get_next_stack_frame() is moved to stacktrace.c to reduce code duplication
Diffstat (limited to 'agent/tcf/services')
-rw-r--r--agent/tcf/services/stacktrace.c53
-rw-r--r--agent/tcf/services/stacktrace.h9
-rw-r--r--agent/tcf/services/symbols.h9
-rw-r--r--agent/tcf/services/symbols_elf.c49
-rw-r--r--agent/tcf/services/symbols_proxy.c109
-rw-r--r--agent/tcf/services/symbols_win32.c4
6 files changed, 89 insertions, 144 deletions
diff --git a/agent/tcf/services/stacktrace.c b/agent/tcf/services/stacktrace.c
index 4d026b42..e4370f9c 100644
--- a/agent/tcf/services/stacktrace.c
+++ b/agent/tcf/services/stacktrace.c
@@ -54,6 +54,57 @@ static size_t context_extension_offset = 0;
#define EXT(ctx) ((StackTrace *)((char *)(ctx) + context_extension_offset))
+int get_next_stack_frame(StackFrame * frame, StackFrame * down) {
+#if ENABLE_Symbols
+ int error = 0;
+ uint64_t ip = 0;
+ Context * ctx = frame->ctx;
+ StackTracingInfo * info = NULL;
+
+ if (read_reg_value(frame, get_PC_definition(ctx), &ip) < 0) {
+ if (frame->is_top_frame) error = errno;
+ }
+ else if (get_stack_tracing_info(ctx, (ContextAddress)ip, &info) < 0) {
+ error = errno;
+ }
+ else if (info != NULL) {
+ Trap trap;
+ if (set_trap(&trap)) {
+ int i;
+ LocationExpressionState * state;
+ state = evaluate_location_expression(ctx, frame, info->fp->cmds, info->fp->cmds_cnt, NULL, 0);
+ if (state->stk_pos != 1) str_exception(ERR_OTHER, "Invalid stack trace expression");
+ frame->fp = (ContextAddress)state->stk[0];
+ frame->is_walked = 1;
+ for (i = 0; i < info->reg_cnt; i++) {
+ int ok = 0;
+ uint64_t v = 0;
+ Trap trap_reg;
+ if (set_trap(&trap_reg)) {
+ /* If a saved register value cannot be evaluated - ignore it */
+ state = evaluate_location_expression(ctx, frame, info->regs[i]->cmds, info->regs[i]->cmds_cnt, NULL, 0);
+ if (state->stk_pos == 1) {
+ v = state->stk[0];
+ ok = 1;
+ }
+ clear_trap(&trap_reg);
+ }
+ if (ok && write_reg_value(down, info->regs[i]->reg, v) < 0) exception(errno);
+ }
+ clear_trap(&trap);
+ }
+ else {
+ frame->fp = 0;
+ }
+ }
+ if (error) {
+ errno = error;
+ return -1;
+ }
+#endif
+ return 0;
+}
+
static void add_frame(StackTrace * stack, StackFrame * frame) {
if (stack->frame_cnt >= stack->frame_max) {
stack->frame_max += 32;
@@ -102,14 +153,12 @@ static void trace_stack(Context * ctx, StackTrace * stack) {
}
}
#endif
-#if ENABLE_Symbols
if (get_next_stack_frame(&frame, &down) < 0) {
error = errno;
trace(LOG_STACK, " trace error: %s", errno_to_str(errno));
loc_free(down.regs);
break;
}
-#endif
if (frame.is_walked == 0) {
trace(LOG_STACK, " *** frame info not available ***");
loc_free(down.regs);
diff --git a/agent/tcf/services/stacktrace.h b/agent/tcf/services/stacktrace.h
index 10817d63..0baad8e9 100644
--- a/agent/tcf/services/stacktrace.h
+++ b/agent/tcf/services/stacktrace.h
@@ -44,6 +44,15 @@ extern int is_top_frame(Context * ctx, int frame);
extern int get_frame_info(Context * ctx, int frame, StackFrame ** info);
/*
+ * For given context and its registers in a stack frame,
+ * compute stack frame location and next frame register values.
+ * If frame info is not available, do nothing.
+ * Return -1 and set errno in case of an error.
+ * Return 0 on success.
+ */
+extern int get_next_stack_frame(StackFrame * frame, StackFrame * down);
+
+/*
* Initialize stack trace service.
*/
extern void ini_stack_trace_service(Protocol *, TCFBroadcastGroup *);
diff --git a/agent/tcf/services/symbols.h b/agent/tcf/services/symbols.h
index 305f00bb..35c4631c 100644
--- a/agent/tcf/services/symbols.h
+++ b/agent/tcf/services/symbols.h
@@ -269,15 +269,6 @@ extern int get_funccall_info(const Symbol * func,
const Symbol ** args, unsigned args_cnt, FunctionCallInfo ** info);
/*
- * For given context and its registers in a stack frame,
- * compute stack frame location and next frame register values.
- * If frame info is not available, do nothing.
- * Return -1 and set errno in case of an error.
- * Return 0 on success.
- */
-extern int get_next_stack_frame(StackFrame * frame, StackFrame * down);
-
-/*
* For given context and instruction address,
* search for stack tracing information.
* Return -1 and set errno in case of an error.
diff --git a/agent/tcf/services/symbols_elf.c b/agent/tcf/services/symbols_elf.c
index e03d65b0..0cbfaf70 100644
--- a/agent/tcf/services/symbols_elf.c
+++ b/agent/tcf/services/symbols_elf.c
@@ -1718,55 +1718,6 @@ int get_stack_tracing_info(Context * ctx, ContextAddress rt_addr, StackTracingIn
return 0;
}
-int get_next_stack_frame(StackFrame * frame, StackFrame * down) {
- int error = 0;
- uint64_t ip = 0;
- Context * ctx = frame->ctx;
- StackTracingInfo * info = NULL;
-
- if (read_reg_value(frame, get_PC_definition(ctx), &ip) < 0) {
- if (frame->is_top_frame) error = errno;
- }
- else if (get_stack_tracing_info(ctx, (ContextAddress)ip, &info) < 0) {
- error = errno;
- }
- else if (info != NULL) {
- Trap trap;
- if (set_trap(&trap)) {
- int i;
- LocationExpressionState * state;
- state = evaluate_location_expression(ctx, frame, info->fp->cmds, info->fp->cmds_cnt, NULL, 0);
- if (state->stk_pos != 1) str_exception(ERR_OTHER, "Invalid stack trace expression");
- frame->fp = (ContextAddress)state->stk[0];
- frame->is_walked = 1;
- for (i = 0; i < info->reg_cnt; i++) {
- int ok = 0;
- uint64_t v = 0;
- Trap trap_reg;
- if (set_trap(&trap_reg)) {
- /* If a saved register value cannot be evaluated - ignore it */
- state = evaluate_location_expression(ctx, frame, info->regs[i]->cmds, info->regs[i]->cmds_cnt, NULL, 0);
- if (state->stk_pos == 1) {
- v = state->stk[0];
- ok = 1;
- }
- clear_trap(&trap_reg);
- }
- if (ok && write_reg_value(down, info->regs[i]->reg, v) < 0) exception(errno);
- }
- clear_trap(&trap);
- }
- else {
- frame->fp = 0;
- }
- }
- if (error) {
- errno = error;
- return -1;
- }
- return 0;
-}
-
const char * get_symbol_file_name(Context * ctx, MemoryRegion * module) {
int error = 0;
ELF_File * file = module ? elf_open_memory_region_file(module, &error) : NULL;
diff --git a/agent/tcf/services/symbols_proxy.c b/agent/tcf/services/symbols_proxy.c
index 57c4fe24..ef933272 100644
--- a/agent/tcf/services/symbols_proxy.c
+++ b/agent/tcf/services/symbols_proxy.c
@@ -130,13 +130,7 @@ typedef struct StackFrameCache {
ErrorReport * error;
Context * ctx;
uint64_t ip;
- uint64_t address;
- uint64_t size;
-
- StackFrameRegisterLocation * fp;
- StackFrameRegisterLocation ** regs;
- int regs_cnt;
-
+ StackTracingInfo sti;
int disposed;
} StackFrameCache;
@@ -327,9 +321,9 @@ static void free_stack_frame_cache(StackFrameCache * c) {
cache_dispose(&c->cache);
release_error_report(c->error);
context_unlock(c->ctx);
- for (i = 0; i < c->regs_cnt; i++) free_sft_sequence(c->regs[i]);
- free_sft_sequence(c->fp);
- loc_free(c->regs);
+ for (i = 0; i < c->sti.reg_cnt; i++) free_sft_sequence(c->sti.regs[i]);
+ free_sft_sequence(c->sti.fp);
+ loc_free(c->sti.regs);
loc_free(c);
}
}
@@ -553,7 +547,6 @@ int find_symbol_by_name(Context * ctx, int frame, ContextAddress addr, const cha
if (!set_trap(&trap)) return -1;
if (frame == STACK_NO_FRAME) {
- ctx = context_get_group(ctx, CONTEXT_GROUP_SYMBOLS);
ip = addr;
}
else {
@@ -655,7 +648,6 @@ int find_symbol_by_addr(Context * ctx, int frame, ContextAddress addr, Symbol **
if (!set_trap(&trap)) return -1;
if (frame == STACK_NO_FRAME) {
- ctx = context_get_group(ctx, CONTEXT_GROUP_SYMBOLS);
ip = addr;
}
else {
@@ -726,7 +718,6 @@ int find_symbol_in_scope(Context * ctx, int frame, ContextAddress addr, Symbol *
if (!set_trap(&trap)) return -1;
if (frame == STACK_NO_FRAME) {
- ctx = context_get_group(ctx, CONTEXT_GROUP_SYMBOLS);
ip = addr;
}
else {
@@ -820,10 +811,7 @@ int enumerate_symbols(Context * ctx, int frame, EnumerateSymbolsCallBack * func,
if (!set_trap(&trap)) return -1;
- if (frame == STACK_NO_FRAME) {
- ctx = context_get_group(ctx, CONTEXT_GROUP_SYMBOLS);
- }
- else {
+ if (frame != STACK_NO_FRAME) {
StackFrame * info = NULL;
if (frame == STACK_TOP_FRAME && (frame = get_top_frame(ctx)) < 0) exception(errno);;
if (get_frame_info(ctx, frame, &info) < 0) exception(errno);
@@ -1308,15 +1296,12 @@ int get_location_info(const Symbol * sym, LocationInfo ** loc) {
LocationInfoCache * f = NULL;
SymInfoCache * sym_cache = NULL;
Context * ctx = NULL;
- Context * prs = NULL;
uint64_t ip = 0;
sym_cache = get_sym_info_cache(sym, ACC_OTHER);
if (sym_cache == NULL) return -1;
- /* Here we assume that symbol location info is valid for all threads in same memory space */
ctx = sym_cache->update_owner;
- prs = context_get_group(ctx, CONTEXT_GROUP_SYMBOLS);
if (!set_trap(&trap)) return -1;
@@ -1330,7 +1315,7 @@ int get_location_info(const Symbol * sym, LocationInfo ** loc) {
syms = get_symbols_cache();
for (l = syms->link_location[h].next; l != syms->link_location + h; l = l->next) {
LocationInfoCache * c = syms2location(l);
- if (c->ctx == prs && strcmp(sym_cache->id, c->sym_id) == 0) {
+ if (c->ctx == ctx && strcmp(sym_cache->id, c->sym_id) == 0) {
if (c->pending != NULL) {
cache_wait(&c->cache);
}
@@ -1347,7 +1332,7 @@ int get_location_info(const Symbol * sym, LocationInfo ** loc) {
if (f == NULL) {
f = (LocationInfoCache *)loc_alloc_zero(sizeof(LocationInfoCache));
list_add_first(&f->link_syms, syms->link_location + h);
- context_lock(f->ctx = prs);
+ context_lock(f->ctx = ctx);
f->ip = ip;
#if ENABLE_RCBP_TEST
if (strncmp(sym_cache->id, "@T.", 3) == 0) {
@@ -1426,30 +1411,30 @@ static void validate_frame(Channel * c, void * args, int error) {
size = json_read_uint64(&c->inp);
json_test_char(&c->inp, MARKER_EOA);
if (error || size == 0) {
- f->address = f->ip & ~(uint64_t)3;
- f->size = 4;
+ f->sti.addr = f->ip & ~(uint64_t)3;
+ f->sti.size = 4;
}
else {
assert(addr <= f->ip);
assert(addr + size > f->ip);
- f->address = addr;
- f->size = size;
+ f->sti.addr = (ContextAddress)addr;
+ f->sti.size = (ContextAddress)size;
}
location_cmds.cnt = 0;
if (json_read_array(&c->inp, read_location_command, NULL)) {
- f->fp = (StackFrameRegisterLocation *)loc_alloc(sizeof(StackFrameRegisterLocation) +
+ f->sti.fp = (StackFrameRegisterLocation *)loc_alloc(sizeof(StackFrameRegisterLocation) +
(location_cmds.cnt - 1) * sizeof(LocationExpressionCommand));
- f->fp->reg = NULL;
- f->fp->cmds_cnt = location_cmds.cnt;
- f->fp->cmds_max = location_cmds.cnt;
- memcpy(f->fp->cmds, location_cmds.cmds, location_cmds.cnt * sizeof(LocationExpressionCommand));
+ f->sti.fp->reg = NULL;
+ f->sti.fp->cmds_cnt = location_cmds.cnt;
+ f->sti.fp->cmds_max = location_cmds.cnt;
+ memcpy(f->sti.fp->cmds, location_cmds.cmds, location_cmds.cnt * sizeof(LocationExpressionCommand));
}
json_test_char(&c->inp, MARKER_EOA);
trace_regs_cnt = 0;
if (json_read_struct(&c->inp, read_stack_trace_register, NULL)) {
- f->regs_cnt = trace_regs_cnt;
- f->regs = (StackFrameRegisterLocation **)loc_alloc(trace_regs_cnt * sizeof(StackFrameRegisterLocation *));
- memcpy(f->regs, trace_regs, trace_regs_cnt * sizeof(StackFrameRegisterLocation *));
+ f->sti.reg_cnt = trace_regs_cnt;
+ f->sti.regs = (StackFrameRegisterLocation **)loc_alloc(trace_regs_cnt * sizeof(StackFrameRegisterLocation *));
+ memcpy(f->sti.regs, trace_regs, trace_regs_cnt * sizeof(StackFrameRegisterLocation *));
}
json_test_char(&c->inp, MARKER_EOA);
json_test_char(&c->inp, MARKER_EOM);
@@ -1465,34 +1450,25 @@ static void validate_frame(Channel * c, void * args, int error) {
if (f->disposed) free_stack_frame_cache(f);
}
-int get_next_stack_frame(StackFrame * frame, StackFrame * down) {
+int get_stack_tracing_info(Context * ctx, ContextAddress ip, StackTracingInfo ** info) {
Trap trap;
unsigned h;
LINK * l;
- uint64_t ip = 0;
- Context * ctx = frame->ctx;
- /* Here we assume that stack tracing info is valid for all threads in same memory space */
- Context * prs = context_get_group(ctx, CONTEXT_GROUP_SYMBOLS);
SymbolsCache * syms = NULL;
StackFrameCache * f = NULL;
+ *info = NULL;
if (!set_trap(&trap)) return -1;
- if (read_reg_value(frame, get_PC_definition(ctx), &ip) < 0) {
- if (frame->is_top_frame) exception(errno);
- clear_trap(&trap);
- return 0;
- }
-
- h = hash_frame(prs);
+ h = hash_frame(ctx);
syms = get_symbols_cache();
for (l = syms->link_frame[h].next; l != syms->link_frame + h; l = l->next) {
StackFrameCache * c = syms2frame(l);
- if (c->ctx == prs) {
+ if (c->ctx == ctx) {
if (c->pending != NULL) {
cache_wait(&c->cache);
}
- else if (c->address <= ip && c->address + c->size > ip) {
+ else if (c->sti.addr <= ip && c->sti.addr + c->sti.size > ip) {
f = c;
break;
}
@@ -1508,7 +1484,7 @@ int get_next_stack_frame(StackFrame * frame, StackFrame * down) {
Channel * c = get_channel(syms);
f = (StackFrameCache *)loc_alloc_zero(sizeof(StackFrameCache));
list_add_first(&f->link_syms, syms->link_frame + h);
- context_lock(f->ctx = prs);
+ context_lock(f->ctx = ctx);
f->ip = ip;
f->pending = protocol_send_command(c, SYMBOLS, "findFrameInfo", validate_frame, f);
json_write_string(&c->out, f->ctx->id);
@@ -1521,35 +1497,8 @@ int get_next_stack_frame(StackFrame * frame, StackFrame * down) {
else if (f->error != NULL) {
exception(set_error_report_errno(f->error));
}
- else if (f->fp != NULL) {
- Trap trap;
- if (set_trap(&trap)) {
- int i;
- LocationExpressionState * state;
- state = evaluate_location_expression(ctx, frame, f->fp->cmds, f->fp->cmds_cnt, NULL, 0);
- if (state->stk_pos != 1) str_exception(ERR_OTHER, "Invalid stack trace expression");
- frame->fp = (ContextAddress)state->stk[0];
- frame->is_walked = 1;
- for (i = 0; i < f->regs_cnt; i++) {
- int ok = 0;
- uint64_t v = 0;
- Trap trap_reg;
- if (set_trap(&trap_reg)) {
- /* If a saved register value cannot be evaluated - ignore it */
- state = evaluate_location_expression(ctx, frame, f->regs[i]->cmds, f->regs[i]->cmds_cnt, NULL, 0);
- if (state->stk_pos == 1) {
- v = state->stk[0];
- ok = 1;
- }
- clear_trap(&trap_reg);
- }
- if (ok && write_reg_value(down, f->regs[i]->reg, v) < 0) exception(errno);
- }
- clear_trap(&trap);
- }
- else {
- frame->fp = 0;
- }
+ else if (f->sti.fp != NULL) {
+ *info = &f->sti;
}
clear_trap(&trap);
@@ -1628,13 +1577,13 @@ static void flush_syms(Context * ctx, int mode) {
while (l != syms->link_frame + i) {
StackFrameCache * c = syms2frame(l);
l = l->next;
- if (c->ctx == prs) free_stack_frame_cache(c);
+ if (context_get_group(c->ctx, CONTEXT_GROUP_SYMBOLS) == prs) free_stack_frame_cache(c);
}
l = syms->link_location[i].next;
while (l != syms->link_location + i) {
LocationInfoCache * c = syms2location(l);
l = l->next;
- if (c->ctx == prs) free_location_info_cache(c);
+ if (context_get_group(c->ctx, CONTEXT_GROUP_SYMBOLS) == prs) free_location_info_cache(c);
}
}
}
diff --git a/agent/tcf/services/symbols_win32.c b/agent/tcf/services/symbols_win32.c
index 39b50c9f..65406a7b 100644
--- a/agent/tcf/services/symbols_win32.c
+++ b/agent/tcf/services/symbols_win32.c
@@ -1200,10 +1200,6 @@ int get_stack_tracing_info(Context * ctx, ContextAddress addr, StackTracingInfo
return 0;
}
-int get_next_stack_frame(StackFrame * frame, StackFrame * down) {
- return 0;
-}
-
int get_funccall_info(const Symbol * func,
const Symbol ** args, unsigned args_cnt, FunctionCallInfo ** res) {
FunctionCallInfo * info = (FunctionCallInfo *)tmp_alloc_zero(sizeof(FunctionCallInfo));

Back to the top