I just realized that we can print out some messages when
handling the stepi/continue packets to inform the GDB
user what's happening.
--
Øyvind Harboe
http://www.zylin.com/zy1000.html
ARM7 ARM9 ARM11 XScale Cortex
JTAG debugger and flash programmer
### Eclipse Workspace Patch 1.0
#P openocd
Index: src/server/gdb_server.h
===================================================================
--- src/server/gdb_server.h (revision 2748)
+++ src/server/gdb_server.h (working copy)
@@ -43,6 +43,10 @@
int closed;
int busy;
int noack_mode;
+ bool sync; /* set flag to true if you want the next stepi to
return immediately.
+ allowing GDB to pick up a fresh set of register values
from the target
+ without modifying the target state. */
+
} gdb_connection_t;
typedef struct gdb_service_s
Index: src/server/gdb_server.c
===================================================================
--- src/server/gdb_server.c (revision 2748)
+++ src/server/gdb_server.c (working copy)
@@ -40,6 +40,8 @@
#define _DEBUG_GDB_IO_
#endif
+static gdb_connection_t *current_gdb_connection;
+
static int gdb_breakpoint_override;
static enum breakpoint_type gdb_breakpoint_override_type;
@@ -750,6 +752,7 @@
gdb_connection->closed = 0;
gdb_connection->busy = 0;
gdb_connection->noack_mode = 0;
+ gdb_connection->sync = true;
/* send ACK to GDB for debug request */
gdb_write(connection, "+", 1);
@@ -767,30 +770,6 @@
/* register callback to be informed about target events */
target_register_event_callback(gdb_target_callback_event_handler,
connection);
- /* a gdb session just attached, try to put the target in halt mode.
- *
- * DANGER!!!!
- *
- * If the halt fails(e.g. target needs a reset, JTAG communication not
- * working, etc.), then the GDB connect will succeed as
- * the get_gdb_reg_list() will lie and return a register list with
- * dummy values.
- *
- * This allows GDB monitor commands to be run from a GDB init script to
- * initialize the target
- *
- * Also, since the halt() is asynchronous target connect will be
- * instantaneous and thus avoiding annoying timeout problems during
- * connect.
- */
- target_halt(gdb_service->target);
- /* FIX!!!! could extended-remote work better here?
- *
- * wait a tiny bit for halted state or we just continue. The
- * GDB register packet will then contain garbage
- */
- target_wait_state(gdb_service->target, TARGET_HALTED, 500);
-
/* remove the initial ACK from the incoming buffer */
if ((retval = gdb_get_char(connection, &initial_ack)) != ERROR_OK)
return retval;
@@ -1609,7 +1588,11 @@
/* We want to print all debug output to GDB connection
*/
log_add_callback(gdb_log_callback, connection);
target_call_timer_callbacks_now();
+ /* some commands need to know the GDB connection, make
note of current
+ * GDB connection. */
+ current_gdb_connection = gdb_connection;
command_run_line(cmd_ctx, cmd);
+ current_gdb_connection = NULL;
target_call_timer_callbacks_now();
log_remove_callback(gdb_log_callback, connection);
free(cmd);
@@ -2107,20 +2090,47 @@
case 'c':
case 's':
{
- if (target->state !=
TARGET_HALTED)
+ int retval = ERROR_OK;
+ gdb_connection_t *gdb_con =
connection->priv;
+
log_add_callback(gdb_log_callback, connection);
+
+ bool nostep = false;
+ if (target->state ==
TARGET_RUNNING)
+ {
+ LOG_WARNING("The target
is already running. Halt target before stepi/continue.");
+ retval =
target_halt(target);
+ if (retval == ERROR_OK)
+ retval =
target_wait_state(target, TARGET_HALTED, 100);
+ } else if (target->state !=
TARGET_HALTED)
+ {
+ LOG_WARNING("The target
is not in the halted nor running stated, stepi/continue ignored.");
+ nostep = true;
+ } else if (gdb_con->sync)
+ {
+ nostep = true;
+
LOG_WARNING("stepi/continue ignored. GDB will now fetch the register state from
the target.");
+ }
+ gdb_con->sync = false;
+
+ if ((retval!=ERROR_OK) ||
nostep)
{
- /* If the target isn't
in the halted state, then we can't
+ /* Either the target
isn't in the halted state, then we can't
* step/continue. This
might be early setup, etc.
+ *
+ * Or we want to allow
GDB to pick up a fresh set of
+ * register values
without modifying the target state.
+ *
*/
gdb_sig_halted(connection);
+
+ /* stop forwarding log
packets! */
+
log_remove_callback(gdb_log_callback, connection);
} else
{
/* We're
running/stepping, in which case we can
* forward log output
until the target is halted
*/
- gdb_connection_t
*gdb_con = connection->priv;
gdb_con->frontend_state
= TARGET_RUNNING;
-
log_add_callback(gdb_log_callback, connection);
target_call_event_callbacks(target, TARGET_EVENT_GDB_START);
int retval =
gdb_step_continue_packet(connection, target, packet, packet_size);
if (retval != ERROR_OK)
@@ -2255,6 +2265,25 @@
return ERROR_OK;
}
+int handle_gdb_sync_command(struct command_context_s *cmd_ctx, char *cmd, char
**args, int argc)
+{
+ if (argc != 0)
+ {
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ if (current_gdb_connection == NULL)
+ {
+ command_print(cmd_ctx,
+ "gdb_sync command can only be run from within
gdb using \"monitor gdb_sync\"");
+ return ERROR_FAIL;
+ }
+
+ current_gdb_connection->sync = true;
+
+ return ERROR_OK;
+}
+
/* daemon configuration command gdb_port */
int handle_gdb_port_command(struct command_context_s *cmd_ctx, char *cmd, char
**args, int argc)
{
@@ -2399,6 +2428,8 @@
int gdb_register_commands(command_context_t *command_context)
{
+ register_command(command_context, NULL, "gdb_sync",
handle_gdb_sync_command,
+ COMMAND_ANY, "next stepi will return immediately
allowing GDB fetch register state without affecting target state");
register_command(command_context, NULL, "gdb_port",
handle_gdb_port_command,
COMMAND_ANY, "daemon configuration command gdb_port");
register_command(command_context, NULL, "gdb_detach",
handle_gdb_detach_command,
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development