gdb_server: add target_debug_reason for program exit detection
Currently, there is no way to notify gdb that program has exited. Add new target_debug_reason called DBG_REASON_EXIT to notify gdb the condition has occured. If the debug reason is DBG_REASON_EXIT, gdb_server will send 'W' packet to tell gdb the process has exited. Change-Id: I7a371da292716a3e6ac4cc2c31b009a651fe047a Signed-off-by: Hsiangkai Wang <hsiangkai@gmail.com> Reviewed-on: http://openocd.zylin.com/1242 Tested-by: jenkins Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
This commit is contained in:
parent
0a4c8990c2
commit
399561eafa
|
@ -702,40 +702,44 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio
|
||||||
int sig_reply_len;
|
int sig_reply_len;
|
||||||
int signal_var;
|
int signal_var;
|
||||||
|
|
||||||
if (gdb_connection->ctrl_c) {
|
if (target->debug_reason == DBG_REASON_EXIT) {
|
||||||
signal_var = 0x2;
|
sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "W00");
|
||||||
gdb_connection->ctrl_c = 0;
|
} else {
|
||||||
} else
|
if (gdb_connection->ctrl_c) {
|
||||||
signal_var = gdb_last_signal(target);
|
signal_var = 0x2;
|
||||||
|
gdb_connection->ctrl_c = 0;
|
||||||
|
} else
|
||||||
|
signal_var = gdb_last_signal(target);
|
||||||
|
|
||||||
stop_reason[0] = '\0';
|
stop_reason[0] = '\0';
|
||||||
if (target->debug_reason == DBG_REASON_WATCHPOINT) {
|
if (target->debug_reason == DBG_REASON_WATCHPOINT) {
|
||||||
enum watchpoint_rw hit_wp_type;
|
enum watchpoint_rw hit_wp_type;
|
||||||
uint32_t hit_wp_address;
|
uint32_t hit_wp_address;
|
||||||
|
|
||||||
if (watchpoint_hit(target, &hit_wp_type, &hit_wp_address) == ERROR_OK) {
|
if (watchpoint_hit(target, &hit_wp_type, &hit_wp_address) == ERROR_OK) {
|
||||||
|
|
||||||
switch (hit_wp_type) {
|
switch (hit_wp_type) {
|
||||||
case WPT_WRITE:
|
case WPT_WRITE:
|
||||||
snprintf(stop_reason, sizeof(stop_reason),
|
snprintf(stop_reason, sizeof(stop_reason),
|
||||||
"watch:%08x;", hit_wp_address);
|
"watch:%08x;", hit_wp_address);
|
||||||
break;
|
break;
|
||||||
case WPT_READ:
|
case WPT_READ:
|
||||||
snprintf(stop_reason, sizeof(stop_reason),
|
snprintf(stop_reason, sizeof(stop_reason),
|
||||||
"rwatch:%08x;", hit_wp_address);
|
"rwatch:%08x;", hit_wp_address);
|
||||||
break;
|
break;
|
||||||
case WPT_ACCESS:
|
case WPT_ACCESS:
|
||||||
snprintf(stop_reason, sizeof(stop_reason),
|
snprintf(stop_reason, sizeof(stop_reason),
|
||||||
"awatch:%08x;", hit_wp_address);
|
"awatch:%08x;", hit_wp_address);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "T%2.2x%s",
|
sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "T%2.2x%s",
|
||||||
signal_var, stop_reason);
|
signal_var, stop_reason);
|
||||||
|
}
|
||||||
|
|
||||||
gdb_put_packet(connection, sig_reply, sig_reply_len);
|
gdb_put_packet(connection, sig_reply, sig_reply_len);
|
||||||
gdb_connection->frontend_state = TARGET_HALTED;
|
gdb_connection->frontend_state = TARGET_HALTED;
|
||||||
|
|
|
@ -1921,7 +1921,13 @@ int nds32_examine_debug_reason(struct nds32 *nds32)
|
||||||
&instruction))
|
&instruction))
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
|
||||||
target->debug_reason = DBG_REASON_BREAKPOINT;
|
/* hit 'break 0x7FFF' */
|
||||||
|
if ((instruction.info.opc_6 == 0x32) &&
|
||||||
|
(instruction.info.sub_opc == 0xA) &&
|
||||||
|
(instruction.info.imm == 0x7FFF)) {
|
||||||
|
target->debug_reason = DBG_REASON_EXIT;
|
||||||
|
} else
|
||||||
|
target->debug_reason = DBG_REASON_BREAKPOINT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE:
|
case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE:
|
||||||
|
|
|
@ -228,6 +228,7 @@ static const Jim_Nvp nvp_target_debug_reason[] = {
|
||||||
{ .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT },
|
{ .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT },
|
||||||
{ .name = "single-step" , .value = DBG_REASON_SINGLESTEP },
|
{ .name = "single-step" , .value = DBG_REASON_SINGLESTEP },
|
||||||
{ .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED },
|
{ .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED },
|
||||||
|
{ .name = "program-exit" , .value = DBG_REASON_EXIT },
|
||||||
{ .name = "undefined" , .value = DBG_REASON_UNDEFINED },
|
{ .name = "undefined" , .value = DBG_REASON_UNDEFINED },
|
||||||
{ .name = NULL, .value = -1 },
|
{ .name = NULL, .value = -1 },
|
||||||
};
|
};
|
||||||
|
|
|
@ -83,7 +83,8 @@ enum target_debug_reason {
|
||||||
DBG_REASON_WPTANDBKPT = 3,
|
DBG_REASON_WPTANDBKPT = 3,
|
||||||
DBG_REASON_SINGLESTEP = 4,
|
DBG_REASON_SINGLESTEP = 4,
|
||||||
DBG_REASON_NOTHALTED = 5,
|
DBG_REASON_NOTHALTED = 5,
|
||||||
DBG_REASON_UNDEFINED = 6
|
DBG_REASON_EXIT = 6,
|
||||||
|
DBG_REASON_UNDEFINED = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum target_endianness {
|
enum target_endianness {
|
||||||
|
|
Loading…
Reference in New Issue