gdb: fix occasional crash when flash probe failed
[fw/openocd] / src / server / gdb_server.c
index 518090265ae9a2449f877835c4e9eff51b35c44c..77142dfadec8acfd5c2ebf41560cd491ded3ca38 100644 (file)
@@ -833,9 +833,6 @@ static int gdb_new_connection(struct connection *connection)
        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;
@@ -861,7 +858,7 @@ static int gdb_new_connection(struct connection *connection)
                        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;
                        }
                }
@@ -873,6 +870,13 @@ static int gdb_new_connection(struct connection *connection)
                  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;
 }
 
@@ -2410,7 +2414,7 @@ static int gdb_target_add_one(struct target *target)
                 * 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)
@@ -2466,8 +2470,10 @@ COMMAND_HANDLER(handle_gdb_sync_command)
 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;
 }