This is an automated email from Gerrit.

Antonio Borneo (borneo.anto...@gmail.com) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/5865

-- gerrit

commit fa98c2bc8d836d148c4371e1a70e224910e15d66
Author: Antonio Borneo <borneo.anto...@gmail.com>
Date:   Thu Oct 15 14:45:27 2020 +0200

    gdb_server: allow multiple GDB connections to selected targets
    
    The default way of working is to have a single GDB attached to one
    target, so OpenOCD accepts only one connection to the GDB port of
    each targets and rejects any further connection.
    
    There are some barely safe use cases in which it could get useful
    having a second GDB connection to the same target.
    One such use case is while using GDB as a 'non-intrusive memory
    inspector', as explained in the OpenOCD documentation.
    One GDB can be left running an infinite loop to dump some memory
    area, or even analysing the content, while keeping a second GDB
    ready for user interaction or spot memory check.
    
    Add a target configure option to specify the maximum number of GDB
    connections allowed for that target, keeping the default to 1.
    
    Change-Id: I4985a602e61588df0b527d2f2aa5b955c93e125e
    Signed-off-by: Antonio Borneo <borneo.anto...@gmail.com>

diff --git a/doc/openocd.texi b/doc/openocd.texi
index dba2a0a..577d758 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -4694,6 +4694,11 @@ possible values of the parameter @var{number}, which are 
not only numeric values
 Use this option to override, for this target only, the global parameter set 
with
 command @command{gdb_port}.
 @xref{gdb_port,,command gdb_port}.
+
+@item @code{-gdb-max-connections} @var{number} -- EXPERIMENTAL: set the maximum
+number of GDB connections that are allowed for the target. Default is 1.
+A negative value for @var{number} means unlimited connections.
+See @xref{gdbmeminspect,,Using GDB as a non-intrusive memory inspector}.
 @end itemize
 @end deffn
 
@@ -10606,7 +10611,13 @@ of a running target. Do not use GDB commands 
@command{continue},
 and GDB would require stopping the target to get the prompt back.
 
 Do not use this mode under an IDE like Eclipse as it caches values of
-previously shown varibles.
+previously shown variables.
+
+It's also possible to connect more than one GDB to the same target by the
+target's configuration option @code{-gdb-max-connections}. This allows, for
+example, one GDB to run a script that continuously polls a set of variables
+while other GDB can be used interactively. Be extremely careful in this case,
+because the two GDB can easily get out-of-sync.
 
 @section RTOS Support
 @cindex RTOS Support
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index c369665..df25d3e 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -3508,7 +3508,7 @@ static int gdb_target_start(struct target *target, const 
char *port)
        target->gdb_service = gdb_service;
 
        ret = add_service("gdb",
-                       port, 1, &gdb_new_connection, &gdb_input,
+                       port, target->gdb_max_connections, &gdb_new_connection, 
&gdb_input,
                        &gdb_connection_closed, gdb_service);
        /* initialize all targets gdb service with the same pointer */
        {
diff --git a/src/target/target.c b/src/target/target.c
index fa609ef..96fa39e 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1265,10 +1265,10 @@ int target_get_gdb_reg_list_noread(struct target 
*target,
 bool target_supports_gdb_connection(struct target *target)
 {
        /*
-        * based on current code, we can simply exclude all the targets that
-        * don't provide get_gdb_reg_list; this could change with new targets.
+        * exclude all the targets that don't provide get_gdb_reg_list
+        * or that have explicit gdb_max_connection == 0
         */
-       return !!target->type->get_gdb_reg_list;
+       return !!target->type->get_gdb_reg_list && 
!!target->gdb_max_connections;
 }
 
 int target_step(struct target *target,
@@ -4646,6 +4646,7 @@ enum target_cfg_param {
        TCFG_RTOS,
        TCFG_DEFER_EXAMINE,
        TCFG_GDB_PORT,
+       TCFG_GDB_MAX_CONNECTIONS,
 };
 
 static Jim_Nvp nvp_config_opts[] = {
@@ -4662,6 +4663,7 @@ static Jim_Nvp nvp_config_opts[] = {
        { .name = "-rtos",             .value = TCFG_RTOS },
        { .name = "-defer-examine",    .value = TCFG_DEFER_EXAMINE },
        { .name = "-gdb-port",         .value = TCFG_GDB_PORT },
+       { .name = "-gdb-max-connections",   .value = TCFG_GDB_MAX_CONNECTIONS },
        { .name = NULL, .value = -1 }
 };
 
@@ -4969,6 +4971,25 @@ no_params:
                        Jim_SetResultString(goi->interp, 
target->gdb_port_override ? : "undefined", -1);
                        /* loop for more */
                        break;
+
+               case TCFG_GDB_MAX_CONNECTIONS:
+                       if (goi->isconfigure) {
+                               struct command_context *cmd_ctx = 
current_command_context(goi->interp);
+                               if (cmd_ctx->mode != COMMAND_CONFIG) {
+                                       Jim_SetResultString(goi->interp, 
"-gdb-max-conenctions must be configured before 'init'", -1);
+                                       return JIM_ERR;
+                               }
+
+                               e = Jim_GetOpt_Wide(goi, &w);
+                               if (e != JIM_OK)
+                                       return e;
+                               target->gdb_max_connections = (w < 0) ? 
CONNECTION_LIMIT_UNLIMITED : (int)w;
+                       } else {
+                               if (goi->argc != 0)
+                                       goto no_params;
+                       }
+                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, 
target->gdb_max_connections));
+                       break;
                }
        } /* while (goi->argc) */
 
@@ -5549,6 +5570,7 @@ static int target_create(Jim_GetOptInfo *goi)
        target->rtos_auto_detect = false;
 
        target->gdb_port_override = NULL;
+       target->gdb_max_connections = 1;
 
        /* Do the rest as "configure" options */
        goi->isconfigure = 1;
diff --git a/src/target/target.h b/src/target/target.h
index c69aa93..94e3b8c 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -211,6 +211,8 @@ struct target {
 
        char *gdb_port_override;                        /* target-specific 
override for gdb_port */
 
+       int gdb_max_connections;                        /* max number of 
simultaneous gdb connections */
+
        /* The semihosting information, extracted from the target. */
        struct semihosting *semihosting;
 };

-- 


_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to