From 399561eafa747e71202d00985206b65868142afb Mon Sep 17 00:00:00 2001 From: Hsiangkai Wang Date: Wed, 6 Mar 2013 09:39:52 +0800 Subject: [PATCH] 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 Reviewed-on: http://openocd.zylin.com/1242 Tested-by: jenkins Reviewed-by: Spencer Oliver --- src/server/gdb_server.c | 60 ++++++++++++++++++++++------------------- src/target/nds32.c | 8 +++++- src/target/target.c | 1 + src/target/target.h | 3 ++- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 14925a2bf..c4ad91cfa 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -702,40 +702,44 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio int sig_reply_len; int signal_var; - if (gdb_connection->ctrl_c) { - signal_var = 0x2; - gdb_connection->ctrl_c = 0; - } else - signal_var = gdb_last_signal(target); + if (target->debug_reason == DBG_REASON_EXIT) { + sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "W00"); + } else { + if (gdb_connection->ctrl_c) { + signal_var = 0x2; + gdb_connection->ctrl_c = 0; + } else + signal_var = gdb_last_signal(target); - stop_reason[0] = '\0'; - if (target->debug_reason == DBG_REASON_WATCHPOINT) { - enum watchpoint_rw hit_wp_type; - uint32_t hit_wp_address; + stop_reason[0] = '\0'; + if (target->debug_reason == DBG_REASON_WATCHPOINT) { + enum watchpoint_rw hit_wp_type; + 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) { - case WPT_WRITE: - snprintf(stop_reason, sizeof(stop_reason), - "watch:%08x;", hit_wp_address); - break; - case WPT_READ: - snprintf(stop_reason, sizeof(stop_reason), - "rwatch:%08x;", hit_wp_address); - break; - case WPT_ACCESS: - snprintf(stop_reason, sizeof(stop_reason), - "awatch:%08x;", hit_wp_address); - break; - default: - break; + switch (hit_wp_type) { + case WPT_WRITE: + snprintf(stop_reason, sizeof(stop_reason), + "watch:%08x;", hit_wp_address); + break; + case WPT_READ: + snprintf(stop_reason, sizeof(stop_reason), + "rwatch:%08x;", hit_wp_address); + break; + case WPT_ACCESS: + snprintf(stop_reason, sizeof(stop_reason), + "awatch:%08x;", hit_wp_address); + break; + default: + break; + } } } - } - sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "T%2.2x%s", - signal_var, stop_reason); + sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "T%2.2x%s", + signal_var, stop_reason); + } gdb_put_packet(connection, sig_reply, sig_reply_len); gdb_connection->frontend_state = TARGET_HALTED; diff --git a/src/target/nds32.c b/src/target/nds32.c index c4bd63aad..50d6e3b9e 100644 --- a/src/target/nds32.c +++ b/src/target/nds32.c @@ -1921,7 +1921,13 @@ int nds32_examine_debug_reason(struct nds32 *nds32) &instruction)) 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; case NDS32_DEBUG_DATA_ADDR_WATCHPOINT_PRECISE: diff --git a/src/target/target.c b/src/target/target.c index 442f0d9f1..1fe89eb40 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -228,6 +228,7 @@ static const Jim_Nvp nvp_target_debug_reason[] = { { .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT }, { .name = "single-step" , .value = DBG_REASON_SINGLESTEP }, { .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED }, + { .name = "program-exit" , .value = DBG_REASON_EXIT }, { .name = "undefined" , .value = DBG_REASON_UNDEFINED }, { .name = NULL, .value = -1 }, }; diff --git a/src/target/target.h b/src/target/target.h index ee282b193..44f382a22 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -83,7 +83,8 @@ enum target_debug_reason { DBG_REASON_WPTANDBKPT = 3, DBG_REASON_SINGLESTEP = 4, DBG_REASON_NOTHALTED = 5, - DBG_REASON_UNDEFINED = 6 + DBG_REASON_EXIT = 6, + DBG_REASON_UNDEFINED = 7, }; enum target_endianness {