breakpoint_clear_target(gdb_service->target);
watchpoint_clear_target(gdb_service->target);
- /* register callback to be informed about target events */
- target_register_event_callback(gdb_target_callback_event_handler, connection);
-
/* remove the initial ACK from the incoming buffer */
if ((retval = gdb_get_char(connection, &initial_ack)) != ERROR_OK)
return retval;
retval = get_flash_bank_by_num(i, &p);
if (retval != ERROR_OK)
{
- LOG_ERROR("Connect failed. Consider setting up a gdb-attach event for the target to prepare target for GDB connect.");
+ LOG_ERROR("Connect failed. Consider setting up a gdb-attach event for the target to prepare target for GDB connect, or use 'gdb_memory_map disable'.");
return retval;
}
}
target_name(gdb_service->target),
target_state_name(gdb_service->target));
+ /* DANGER! If we fail subsequently, we must remove this handler,
+ * otherwise we occasionally see crashes as the timer can invoke the
+ * callback fn.
+ *
+ * register callback to be informed about target events */
+ target_register_event_callback(gdb_target_callback_event_handler, connection);
+
return ERROR_OK;
}
return ERROR_OK;
}
-static int gdb_target_start(struct target *target, uint16_t port)
+static int gdb_target_start(struct target *target, const char *port)
{
- bool use_pipes = 0 == port;
struct gdb_service *gdb_service = malloc(sizeof(struct gdb_service));
if (NULL == gdb_service)
return -ENOMEM;
gdb_service->target = target;
- add_service("gdb", use_pipes ? CONNECTION_PIPE : CONNECTION_TCP,
+ return add_service("gdb",
port, 1, &gdb_new_connection, &gdb_input,
&gdb_connection_closed, gdb_service);
-
- const char *name = target_name(target);
- if (use_pipes)
- LOG_DEBUG("gdb service for target '%s' using pipes", name);
- else
- LOG_DEBUG("gdb service for target '%s' on TCP port %u", name, port);
- return ERROR_OK;
}
static int gdb_target_add_one(struct target *target)
{
- long portnumber_parsed;
- /* If we can parse the port number
- * then we increment the port number for the next target.
- */
- char *end_parse;
- portnumber_parsed = strtol(gdb_port_next, &end_parse, 0);
- if (!*end_parse)
- {
- LOG_ERROR("Illegal port number");
- return ERROR_FAIL;
- }
-
- int retval = gdb_target_start(target, portnumber_parsed);
+ int retval = gdb_target_start(target, gdb_port_next);
if (retval == ERROR_OK)
{
long portnumber;
* then we increment the port number for the next target.
*/
char *end;
- strtol(gdb_port_next, &end, 0);
+ portnumber = strtol(gdb_port_next, &end, 0);
if (!*end)
{
if (parse_long(gdb_port_next, &portnumber) == ERROR_OK)
COMMAND_HANDLER(handle_gdb_port_command)
{
int retval = CALL_COMMAND_HANDLER(server_pipe_command, &gdb_port);
- if (ERROR_OK == retval)
+ if (ERROR_OK == retval) {
+ free((void*)gdb_port_next);
gdb_port_next = strdup(gdb_port);
+ }
return retval;
}
.name = "gdb_port",
.handler = handle_gdb_port_command,
.mode = COMMAND_ANY,
- .help = "Display or specify base port on which to listen "
- "for incoming GDB connections. "
- "No arguments reports GDB port; zero disables.",
+ .help = "Normally gdb listens to a TCP/IP port. Each subsequent GDB "
+ "server listens for the next port number after the "
+ "base port number specified. "
+ "No arguments reports GDB port. \"pipe\" means listen to stdin "
+ "output to stdout, an integer is base port number, \"disable\" disables "
+ "port. Any other string is are interpreted as named pipe to listen to. "
+ "Output pipe is the same name as input pipe, but with 'o' appended.",
.usage = "[port_num]",
},
{