Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/agent/tcf
diff options
context:
space:
mode:
authorEugene Tarassov2019-11-14 20:38:17 +0000
committerEugene Tarassov2019-11-17 18:06:27 +0000
commita5aeb971a3f36b65a2b49172bc1c85a5c83beadb (patch)
tree60512cc409157824948b3aac9c43b3393a46cda9 /agent/tcf
parentccff68c5f39a09e1ab3005620268add20661b557 (diff)
downloadorg.eclipse.tcf.agent-a5aeb971a3f36b65a2b49172bc1c85a5c83beadb.tar.gz
org.eclipse.tcf.agent-a5aeb971a3f36b65a2b49172bc1c85a5c83beadb.tar.xz
org.eclipse.tcf.agent-a5aeb971a3f36b65a2b49172bc1c85a5c83beadb.zip
TCF Agent: fixed data caching for server side services
When Symbols and/or some other services are configured to run in TCF server, MEM_ACCESS_RD_STOP can cause infinite loop of cache misses. Need to lock run control until cache validation is done.
Diffstat (limited to 'agent/tcf')
-rw-r--r--agent/tcf/services/breakpoints.c7
-rw-r--r--agent/tcf/services/disassembly.c8
-rw-r--r--agent/tcf/services/expressions.c4
-rw-r--r--agent/tcf/services/runctrl.c41
4 files changed, 51 insertions, 9 deletions
diff --git a/agent/tcf/services/breakpoints.c b/agent/tcf/services/breakpoints.c
index a77f3d2d..4ae399d6 100644
--- a/agent/tcf/services/breakpoints.c
+++ b/agent/tcf/services/breakpoints.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007-2017 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007-2019 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.
@@ -1627,19 +1627,21 @@ static void plant_at_address_expression(Context * ctx, ContextAddress ip, Breakp
int error = 0;
#if ENABLE_Expressions
Value v;
- SymbolProperties props;
memset (&v, 0, sizeof (Value));
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_Symbols
if (!error && v.sym != NULL) {
+ SymbolProperties props;
/* We want to add the LocalEntryOffset */
get_symbol_props(v.sym, &props);
/* If the symbol is not a PPC64 function, offset should be 0, so it is safe to add */
addr += props.local_entry_offset;
}
#endif
+#endif
#if ENABLE_SkipPrologueWhenPlanting
/* Even if addr is incremented by local_entry_offset, we still should be on right code area */
if (!error && bp->skip_prologue && v.sym != NULL && skip_function_prologue(ctx, v.sym, &addr) < 0) error = errno;
@@ -1674,6 +1676,7 @@ 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) {
+ SymbolProperties props;
/* We want to add the LocalEntryOffset */
get_symbol_props(sym, &props);
/* If the symbol is not a PPC64 function, offset should be 0, so it is safe to add */
diff --git a/agent/tcf/services/disassembly.c b/agent/tcf/services/disassembly.c
index c6c35653..07f018c8 100644
--- a/agent/tcf/services/disassembly.c
+++ b/agent/tcf/services/disassembly.c
@@ -278,7 +278,7 @@ static int disassemble_block(Context * ctx, OutputStream * out, uint8_t * mem_bu
return 0;
}
-#if SERVICE_LineNumbers
+#if ENABLE_LineNumbers
static void address_to_line_cb(CodeArea * area, void * args) {
CodeArea ** p = (CodeArea **)args;
if (*p == NULL || (*p)->start_address < area->start_address) {
@@ -325,7 +325,7 @@ static void disassemble_cache_client(void * x) {
ContextAddress sym_size = 0;
int sym_addr_ok = 0;
int sym_size_ok = 0;
-#if SERVICE_Symbols
+#if ENABLE_Symbols
{
Symbol * sym = NULL;
if (find_symbol_by_addr(ctx, STACK_NO_FRAME, args->addr, &sym) == 0) {
@@ -338,7 +338,7 @@ static void disassemble_cache_client(void * x) {
}
}
#endif
-#if SERVICE_LineNumbers
+#if ENABLE_LineNumbers
if (!sym_addr_ok || !sym_size_ok) {
CodeArea * area = NULL;
address_to_line(ctx, args->addr, args->addr + 1, address_to_line_cb, &area);
@@ -476,7 +476,7 @@ static void read_disassembly_params(InputStream * inp, const char * name, void *
args->pseudo_instr = json_read_boolean(inp);
}
else if (strcmp(name, "OpcodeValue") == 0) {
- args->opcode_value =json_read_boolean(inp);
+ args->opcode_value = json_read_boolean(inp);
}
else {
json_skip_object(inp);
diff --git a/agent/tcf/services/expressions.c b/agent/tcf/services/expressions.c
index e9434607..81de0026 100644
--- a/agent/tcf/services/expressions.c
+++ b/agent/tcf/services/expressions.c
@@ -1574,6 +1574,7 @@ static void load_value(Value * v) {
else if (v->value != NULL) {
/* OK */
}
+#if ENABLE_Symbols
else if (v->loc != NULL) {
size_t size = 0;
void * value = NULL;
@@ -1584,6 +1585,7 @@ static void load_value(Value * v) {
v->size = (ContextAddress)size;
sign_extend(v, loc);
}
+#endif
else {
error(ERR_OTHER, "Has no value");
}
@@ -2041,7 +2043,9 @@ static void primary_expression(int mode, Value * v) {
next_sy();
}
else if (text_sy == SY_VAL) {
+#if ENABLE_Symbols
int flags = text_val_flags;
+#endif
*v = text_val;
next_sy();
#if ENABLE_Symbols
diff --git a/agent/tcf/services/runctrl.c b/agent/tcf/services/runctrl.c
index 653381c0..695cf9fb 100644
--- a/agent/tcf/services/runctrl.c
+++ b/agent/tcf/services/runctrl.c
@@ -70,6 +70,7 @@ static unsigned listener_cnt = 0;
static unsigned listener_max = 0;
static const char RUN_CONTROL[] = "RunControl";
+static const char CONTEXT_PROXY[] = "ContextProxy";
typedef struct ContextExtensionRC {
int pending_safe_event; /* safe events are waiting for this context to be stopped */
@@ -111,10 +112,16 @@ typedef struct ContextExtensionRC {
} ContextExtensionRC;
static size_t context_extension_offset = 0;
-
#define EXT(ctx) (ctx ? ((ContextExtensionRC *)((char *)(ctx) + context_extension_offset)) : NULL)
#define link2ctx(lnk) ((Context *)((char *)(lnk) - offsetof(ContextExtensionRC, link) - context_extension_offset))
+typedef struct ChannelExtensionRC {
+ int cache_lock;
+} ChannelExtensionRC;
+
+static size_t channel_extension_offset = 0;
+#define EXT_CH(ch) ((ChannelExtensionRC *)((char *)(ch) + channel_extension_offset))
+
typedef struct SafeEvent {
Context * ctx;
EventCallBack * done;
@@ -2759,8 +2766,8 @@ static void clear_context_proxy_cache(Context * ctx) {
int i;
for (i = 0; i < c->peer_service_cnt; i++) {
char * nm = c->peer_service_list[i];
- if (strcmp(nm, "ContextProxy") == 0) {
- protocol_send_command(c, "ContextProxy", "clear", context_proxy_reply, NULL);
+ if (strcmp(nm, CONTEXT_PROXY) == 0) {
+ protocol_send_command(c, CONTEXT_PROXY, "clear", context_proxy_reply, NULL);
json_write_string(&c->out, ctx->id);
write_stream(&c->out, 0);
write_stream(&c->out, MARKER_EOM);
@@ -2819,12 +2826,38 @@ static void event_context_exited(Context * ctx, void * args) {
}
static void channel_closed(Channel * c) {
+ ChannelExtensionRC * ext_ch = EXT_CH(c);
LINK * l;
for (l = context_root.next; l != &context_root; l = l ->next) {
Context * ctx = ctxl2ctxp(l);
ContextExtensionRC * ext = EXT(ctx);
if (ext->step_channel == c) cancel_step_mode(ctx);
}
+ if (ext_ch->cache_lock) {
+ ext_ch->cache_lock = 0;
+ run_ctrl_unlock();
+ }
+}
+
+static void context_cache_lock(Channel * c) {
+ ChannelExtensionRC * ext = EXT_CH(c);
+ json_test_char(&c->inp, MARKER_EOM);
+ assert(ext->cache_lock == 0);
+ ext->cache_lock = 1;
+ run_ctrl_lock();
+}
+
+static void context_cache_unlock(Channel * c) {
+ ChannelExtensionRC * ext = EXT_CH(c);
+ json_test_char(&c->inp, MARKER_EOM);
+ assert(ext->cache_lock == 1);
+ ext->cache_lock = 0;
+ run_ctrl_unlock();
+}
+
+static void channel_opened(Channel * c) {
+ add_event_handler(c, CONTEXT_PROXY, "lock", context_cache_lock);
+ add_event_handler(c, CONTEXT_PROXY, "unlock", context_cache_unlock);
}
static void event_context_disposed(Context * ctx, void * args) {
@@ -2870,7 +2903,9 @@ void ini_run_ctrl_service(Protocol * proto, TCFBroadcastGroup * bcg) {
broadcast_group = bcg;
add_context_event_listener(&listener, NULL);
add_channel_close_listener(channel_closed);
+ add_channel_open_listener(channel_opened);
context_extension_offset = context_extension(sizeof(ContextExtensionRC));
+ channel_extension_offset = channel_extension(sizeof(ChannelExtensionRC));
add_command_handler(proto, RUN_CONTROL, "getContext", command_get_context);
add_command_handler(proto, RUN_CONTROL, "getChildren", command_get_children);
add_command_handler(proto, RUN_CONTROL, "getState", command_get_state);

Back to the top