Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2010-08-27 15:47:27 +0000
committereutarass2010-08-27 15:47:27 +0000
commit50c911874962d7e46ff451e69a3135c3327edb81 (patch)
tree733823fbe3b10db792a01c968762ec2ceb392264
parent6aabca06a7a2c55a5566c6d4d8c2e39eeb59952c (diff)
downloadorg.eclipse.tcf.agent-50c911874962d7e46ff451e69a3135c3327edb81.tar.gz
org.eclipse.tcf.agent-50c911874962d7e46ff451e69a3135c3327edb81.tar.xz
org.eclipse.tcf.agent-50c911874962d7e46ff451e69a3135c3327edb81.zip
TCF Agent:
1. Added support for all register properties that are defined for Registers service. 2. Added SignalDescription property to context execution state object.
-rw-r--r--framework/cpudefs.h39
-rw-r--r--services/breakpoints.c2
-rw-r--r--services/registers.c124
-rw-r--r--services/runctrl.c16
-rw-r--r--system/Darwin/context-darwin.c9
-rw-r--r--system/FreeBSD/context-freebsd.c9
-rw-r--r--system/GNU/Linux/context-linux.c9
-rw-r--r--system/Windows/context-win32.c12
8 files changed, 148 insertions, 72 deletions
diff --git a/framework/cpudefs.h b/framework/cpudefs.h
index 297a345b..5068cfcb 100644
--- a/framework/cpudefs.h
+++ b/framework/cpudefs.h
@@ -38,15 +38,36 @@ typedef uintptr_t ContextAddress;
typedef struct RegisterData RegisterData;
typedef struct RegisterDefinition RegisterDefinition;
+typedef struct NamedRegisterValue NamedRegisterValue;
+
+struct NamedRegisterValue {
+ uint8_t * value;
+ const char * name;
+ const char * description;
+};
struct RegisterDefinition {
- const char * name; /* pointer to register name */
- size_t offset; /* offset to entry in REG_SET */
- size_t size; /* register size in bytes */
- int16_t dwarf_id; /* ID of the register in DWARF sections, or -1 */
- int16_t eh_frame_id; /* ID of the register in .eh_frame section, or -1 */
- uint8_t traceable; /* register value can be traced using .eh_frame of .debug_frame */
- uint8_t big_endian; /* 0 - little endian, 1 - big endian */
+ const char * name; /* pointer to register name */
+ size_t offset; /* offset to entry in REG_SET */
+ size_t size; /* register size in bytes */
+ int16_t dwarf_id; /* ID of the register in DWARF sections, or -1 */
+ int16_t eh_frame_id; /* ID of the register in .eh_frame section, or -1 */
+ uint8_t traceable; /* register value can be traced using .eh_frame of .debug_frame */
+ uint8_t big_endian; /* 0 - little endian, 1 - big endian */
+ uint8_t fp_value; /* true if the register value is a floating-point value */
+ uint8_t no_read; /* true if context value can not be read */
+ uint8_t no_write; /* true if context value can not be written */
+ uint8_t read_once; /* true if reading the context (register) destroys its current value */
+ uint8_t write_once; /* true if register value can not be overwritten - every write counts */
+ uint8_t side_effects; /* true if writing the context can change values of other registers */
+ uint8_t volatile_value;/* true if the register value can change even when target is stopped */
+ uint8_t left_to_right; /* true if the lowest numbered bit should be shown to user as the left-most bit */
+ int first_bit; /* bit numbering base (0 or 1) to use when showing bits to user */
+ int * bits; /* if context is a bit field, contains the field bit numbers in the parent context */
+ NamedRegisterValue ** values; /* predefined names (mnemonics) for some of register values */
+ ContextAddress memory_address;/* the address of a memory mapped register */
+ const char * memory_context;/* the context ID of a memory context in which a memory mapped register is located */
+ const char * role; /* the role the register plays in a program execution */
};
/* Stack tracing command codes */
@@ -153,9 +174,7 @@ extern uint8_t * get_break_instruction(Context * ctx, size_t * size);
*/
extern int crawl_stack_frame(StackFrame * frame, StackFrame * down);
-/*
- * Execute stack tracing command sequence.
- */
+/* Execute stack tracing command sequence */
extern uint64_t evaluate_stack_trace_commands(Context * ctx, StackFrame * frame, StackTracingCommandSequence * cmds);
#endif /* ENABLE_DebugContext */
diff --git a/services/breakpoints.c b/services/breakpoints.c
index 683399da..7c13a86a 100644
--- a/services/breakpoints.c
+++ b/services/breakpoints.c
@@ -319,7 +319,7 @@ static BreakInstruction * add_instruction(Context * ctx, ContextAddress address)
static BreakInstruction * find_instruction(Context * ctx, ContextAddress address) {
int hash = addr2instr_hash(ctx, address);
LINK * l = addr2instr[hash].next;
- assert(address != 0);
+ if (address == 0) return NULL;
while (l != addr2instr + hash) {
BreakInstruction * bi = link_adr2bi(l);
if (bi->ctx->mem == ctx->mem && bi->address == address) return bi;
diff --git a/services/registers.c b/services/registers.c
index 06e49cc0..7003b4eb 100644
--- a/services/registers.c
+++ b/services/registers.c
@@ -41,6 +41,15 @@ static uint8_t * bbf = NULL;
static unsigned bbf_pos = 0;
static unsigned bbf_len = 0;
+static void write_boolean_member(OutputStream * out, const char * name, int val) {
+ /* For this service FALSE is same as absence of the member */
+ if (!val) return;
+ write_stream(out, ',');
+ json_write_string(out, name);
+ write_stream(out, ':');
+ json_write_boolean(out, 1);
+}
+
static void write_context(OutputStream * out, char * id, Context * ctx, int frame, RegisterDefinition * reg_def) {
assert(!ctx->exited);
@@ -61,6 +70,11 @@ static void write_context(OutputStream * out, char * id, Context * ctx, int fram
}
write_stream(out, ',');
+ json_write_string(out, "ProcessID");
+ write_stream(out, ':');
+ json_write_string(out, ctx->mem->id);
+
+ write_stream(out, ',');
json_write_string(out, "Name");
write_stream(out, ':');
json_write_string(out, reg_def->name);
@@ -70,23 +84,6 @@ static void write_context(OutputStream * out, char * id, Context * ctx, int fram
write_stream(out, ':');
json_write_long(out, reg_def->size);
- write_stream(out, ',');
- json_write_string(out, "Readable");
- write_stream(out, ':');
- json_write_boolean(out, 1);
-
- write_stream(out, ',');
- json_write_string(out, "Writeable");
- write_stream(out, ':');
- json_write_boolean(out, 1);
-
- if (reg_def == get_PC_definition(ctx)) {
- write_stream(out, ',');
- json_write_string(out, "Role");
- write_stream(out, ':');
- json_write_string(out, "PC");
- }
-
if (reg_def->dwarf_id >= 0) {
write_stream(out, ',');
json_write_string(out, "DwarfID");
@@ -101,22 +98,93 @@ static void write_context(OutputStream * out, char * id, Context * ctx, int fram
json_write_long(out, reg_def->eh_frame_id);
}
- if (reg_def->traceable) {
+ write_boolean_member(out, "Traceable", reg_def->traceable);
+ write_boolean_member(out, "BigEndian", reg_def->big_endian);
+ write_boolean_member(out, "Float", reg_def->fp_value);
+ write_boolean_member(out, "Readable", !reg_def->no_read);
+ write_boolean_member(out, "Writeable", !reg_def->no_write);
+ write_boolean_member(out, "ReadOnce", reg_def->read_once);
+ write_boolean_member(out, "WriteOnce", reg_def->write_once);
+ write_boolean_member(out, "Volatile", reg_def->volatile_value);
+ write_boolean_member(out, "SideEffects", reg_def->side_effects);
+ write_boolean_member(out, "LeftToRight", reg_def->left_to_right);
+
+ if (reg_def->first_bit > 0) {
write_stream(out, ',');
- json_write_string(out, "Traceable");
+ json_write_string(out, "FirstBit");
write_stream(out, ':');
- json_write_boolean(out, reg_def->traceable);
+ json_write_long(out, reg_def->first_bit);
}
- write_stream(out, ',');
- json_write_string(out, "ProcessID");
- write_stream(out, ':');
- json_write_string(out, ctx->mem->id);
+ if (reg_def->bits != NULL) {
+ int i = 0;
+ write_stream(out, ',');
+ json_write_string(out, "Bits");
+ write_stream(out, ':');
+ write_stream(out, '[');
+ while (reg_def->bits[i] >= 0) {
+ if (i > 0) write_stream(out, ',');
+ json_write_long(out, reg_def->bits[i++]);
+ }
+ write_stream(out, ']');
+ }
- write_stream(out, ',');
- json_write_string(out, "BigEndian");
- write_stream(out, ':');
- json_write_boolean(out, reg_def->big_endian);
+ if (reg_def->values != NULL) {
+ int i = 0;
+ write_stream(out, ',');
+ json_write_string(out, "Values");
+ write_stream(out, ':');
+ write_stream(out, '[');
+ while (reg_def->values[i] != NULL) {
+ NamedRegisterValue * v = reg_def->values[i++];
+ if (i > 0) write_stream(out, ',');
+ write_stream(out, '(');
+ json_write_string(out, "Value");
+ write_stream(out, ':');
+ json_write_binary(out, v->value, reg_def->size);
+ if (v->name != NULL) {
+ write_stream(out, ',');
+ json_write_string(out, "Name");
+ write_stream(out, ':');
+ json_write_string(out, v->name);
+ }
+ if (v->description != NULL) {
+ write_stream(out, ',');
+ json_write_string(out, "Description");
+ write_stream(out, ':');
+ json_write_string(out, v->description);
+ }
+ write_stream(out, '}');
+ }
+ write_stream(out, ']');
+ }
+
+ if (reg_def->memory_address > 0) {
+ write_stream(out, ',');
+ json_write_string(out, "MemoryAddress");
+ write_stream(out, ':');
+ json_write_uint64(out, reg_def->memory_address);
+ }
+
+ if (reg_def->memory_context != NULL) {
+ write_stream(out, ',');
+ json_write_string(out, "MemoryContext");
+ write_stream(out, ':');
+ json_write_string(out, reg_def->memory_context);
+ }
+
+ if (reg_def->role != NULL) {
+ write_stream(out, ',');
+ json_write_string(out, "Role");
+ write_stream(out, ':');
+ json_write_string(out, reg_def->role);
+ }
+ else if (reg_def == get_PC_definition(ctx)) {
+ write_stream(out, ',');
+ json_write_string(out, "Role");
+ write_stream(out, ':');
+ json_write_string(out, "PC");
+ }
write_stream(out, '}');
write_stream(out, 0);
diff --git a/services/runctrl.c b/services/runctrl.c
index ec6d1d5b..78866df5 100644
--- a/services/runctrl.c
+++ b/services/runctrl.c
@@ -227,14 +227,22 @@ static void write_context_state(OutputStream * out, Context * ctx) {
/* Object: Additional context state info */
write_stream(out, '{');
if (ctx->signal) {
+ const char * name = signal_name(ctx->signal);
+ const char * desc = signal_description(ctx->signal);
json_write_string(out, "Signal");
write_stream(out, ':');
json_write_long(out, ctx->signal);
- if (signal_name(ctx->signal)) {
+ if (name != NULL) {
write_stream(out, ',');
json_write_string(out, "SignalName");
write_stream(out, ':');
- json_write_string(out, signal_name(ctx->signal));
+ json_write_string(out, name);
+ }
+ if (desc != NULL) {
+ write_stream(out, ',');
+ json_write_string(out, "SignalDescription");
+ write_stream(out, ':');
+ json_write_string(out, desc);
}
fst = 0;
}
@@ -741,7 +749,9 @@ static void send_event_context_exception(Context * ctx) {
}
else {
char buf[128];
- snprintf(buf, sizeof(buf), "Signal %d %s", ctx->signal, signal_name(ctx->signal));
+ const char * desc = signal_description(ctx->signal);
+ if (desc == NULL) desc = signal_name(ctx->signal);
+ snprintf(buf, sizeof(buf), desc == NULL ? "Signal %d" : "Signal %d: %s", ctx->signal, desc);
json_write_string(out, buf);
}
write_stream(out, 0);
diff --git a/system/Darwin/context-darwin.c b/system/Darwin/context-darwin.c
index 2ad089c6..7113e656 100644
--- a/system/Darwin/context-darwin.c
+++ b/system/Darwin/context-darwin.c
@@ -74,14 +74,7 @@ const char * context_suspend_reason(Context * ctx) {
if (EXT(ctx)->end_of_step) return "Step";
if (EXT(ctx)->syscall_enter) return "System Call";
if (EXT(ctx)->syscall_exit) return "System Return";
- if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) {
- return "Suspended";
- }
- if (signal_name(ctx->signal)) {
- snprintf(reason, sizeof(reason), "Signal %d %s", ctx->signal, signal_name(ctx->signal));
- return reason;
- }
-
+ if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) return "Suspended";
snprintf(reason, sizeof(reason), "Signal %d", ctx->signal);
return reason;
}
diff --git a/system/FreeBSD/context-freebsd.c b/system/FreeBSD/context-freebsd.c
index f619d4ee..86773588 100644
--- a/system/FreeBSD/context-freebsd.c
+++ b/system/FreeBSD/context-freebsd.c
@@ -90,14 +90,7 @@ const char * context_suspend_reason(Context * ctx) {
snprintf(reason, sizeof(reason), "Event: %s", event_name(EXT(ctx)->ptrace_event));
return reason;
}
- if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) {
- return "Suspended";
- }
- if (signal_name(ctx->signal)) {
- snprintf(reason, sizeof(reason), "Signal %d %s", ctx->signal, signal_name(ctx->signal));
- return reason;
- }
-
+ if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) return "Suspended";
snprintf(reason, sizeof(reason), "Signal %d", ctx->signal);
return reason;
}
diff --git a/system/GNU/Linux/context-linux.c b/system/GNU/Linux/context-linux.c
index d63c5e8c..fd734997 100644
--- a/system/GNU/Linux/context-linux.c
+++ b/system/GNU/Linux/context-linux.c
@@ -131,14 +131,7 @@ const char * context_suspend_reason(Context * ctx) {
}
if (EXT(ctx)->syscall_enter) return "System Call";
if (EXT(ctx)->syscall_exit) return "System Return";
- if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) {
- return "Suspended";
- }
- if (signal_name(ctx->signal)) {
- snprintf(reason, sizeof(reason), "Signal %d %s", ctx->signal, signal_name(ctx->signal));
- return reason;
- }
-
+ if (ctx->signal == SIGSTOP || ctx->signal == SIGTRAP) return "Suspended";
snprintf(reason, sizeof(reason), "Signal %d", ctx->signal);
return reason;
}
diff --git a/system/Windows/context-win32.c b/system/Windows/context-win32.c
index 0a5ff718..5fb4b3d0 100644
--- a/system/Windows/context-win32.c
+++ b/system/Windows/context-win32.c
@@ -104,17 +104,17 @@ static OSVERSIONINFOEX os_version;
const char * context_suspend_reason(Context * ctx) {
ContextExtensionWin32 * ext = EXT(ctx);
DWORD exception_code = ext->suspend_reason.ExceptionRecord.ExceptionCode;
- const char * desc = NULL;
static char buf[64];
if (exception_code == 0) return "Suspended";
if (exception_code == EXCEPTION_SINGLE_STEP) return "Step";
if (exception_code == EXCEPTION_BREAKPOINT) return "Eventpoint";
-
- desc = signal_description(get_signal_from_code(exception_code));
- if (desc != NULL) return desc;
-
- snprintf(buf, sizeof(buf), "Exception %#lx", exception_code);
+ if (ext->suspend_reason.dwFirstChance) {
+ snprintf(buf, sizeof(buf), "Exception %#lx", exception_code);
+ }
+ else {
+ snprintf(buf, sizeof(buf), "Unhandled exception %#lx", exception_code);
+ }
return buf;
}

Back to the top