SimonQian wrote:

simon>> -max-O-packet will not help.

For me, it is 100% required. Period.

>> Debug: 1418 58406 arm7_9_common.c:1190 arm7_9_debug_entry(): entered
debug state at PC 0x20329c
>> Debug: 1419 58406 target.c:799 target_call_event_callbacks(): target
event 4 (halted)
>> Debug: 1420 58406 target.c:3051 target_handle_event(): event: 4
halted - no action
>> User: 1421 58406 target.c:1040 target_arch_state(): target state: halted
>> Debug: 1422 58406 gdb_server.c:613 gdb_output_con(): TX O packet len:
21, chunksize: 256
>> User: 1423 58406 armv4_5.c:308 armv4_5_arch_state(): target halted in
ARM state due to debug-request, current mode: Supervisor
>> cpsr: 0x000000d3 pc: 0x0020329c
>> Debug: 1424 58406 gdb_server.c:613 gdb_output_con(): TX O packet len:
106, chunksize: 256

At that point, without "-max-O-packet' IAR dies a horrible death.

>> Warning: 1425 58531 gdb_server.c:370 gdb_put_packet_inner(): negative
reply, retrying
>> Warning: 1426 58640 gdb_server.c:370 gdb_put_packet_inner(): negative
reply, retrying
>> Warning: 1427 58765 gdb_server.c:370 gdb_put_packet_inner(): negative
reply, retrying
>> Debug: 1428 59812 target.c:3051 target_handle_event(): event: 4
halted - no action
>> Debug: 1429 67593 target.c:799 target_call_event_callbacks(): target
event 24 (gdb-detach)
>> Debug: 1430 67609 target.c:3051 target_handle_event(): event: 24
gdb-detach - no action
>> Info: 1431 67625 server.c:393 server_loop(): dropped 'gdb' connection

Perhaps your NXP ARM7 does not produce that message. I don't see long
"User:" messages in your log.

simon>> Attachment is the log file.

(A) The original problem you had, seems to be fixed by the "Got $,
expected - assuming new packet" fix. [Reference: "log_fail_at_3rd.text",
line: 2830 of 3245] [And at line 3209/3245]

(B) Looking at the log, it seems you have enabled, "gdb configure
--debug-gdb-io" (I see the extra messages) That sadly, re-introduces
that error again... a different way, in a new place.

Reference: "log_fail_at_2nd.txt" - line 5831

I believe the fix (A) took us one step forward. and (B) took us one-half
step backward.

The new attached patch fixes (B) [ see gdb_server.c, line 308, after
applying the new patch ].

====

Also please try the following:

In my IAR kickstart, under, Menu -> Project -> Options -> Debugger ->
GDB Server, "GDB Server" tab there is a check box, "Log Communication".

I turned that check box on - and that is how I discovered it was the
large Oh packet that causes my problem (and thus, the new "gdb configure
-max-O-packet" command).

Look carefully near the end of the log, you should be able to figure out
what packet IAR is having problems with.

-Duane.







Index: gdb_server.c
===================================================================
--- gdb_server.c        (revision 986)
+++ gdb_server.c        (working copy)
@@ -42,9 +42,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 
-#if 0
-#define _DEBUG_GDB_IO_
-#endif
+static int debug_gdb_io;
 
 static int gdb_breakpoint_override;
 static enum breakpoint_type gdb_breakpoint_override_type;
@@ -78,6 +76,15 @@
  * see the code in gdb_read_memory_packet() for further explanations */
 int gdb_report_data_abort = 0;
 
+static int 
+safe_toascii(int c)
+{
+       if( (c < 0x20) || (c > 0x7e) ){
+               c = '.';
+       }
+       return c;
+}
+
 int gdb_last_signal(target_t *target)
 {
        switch (target->debug_reason)
@@ -144,10 +151,9 @@
        gdb_connection_t *gdb_con = connection->priv;
        int retval=ERROR_OK;
 
-#ifdef _DEBUG_GDB_IO_
        char *debug_buffer;
-#endif
 
+
        if (gdb_con->buf_cnt-- > 0)
        {
                *next_char = *(gdb_con->buf_p++);
@@ -156,9 +162,9 @@
                else
                        connection->input_pending = 0;
 
-#ifdef _DEBUG_GDB_IO_
-               LOG_DEBUG("returned char '%c' (0x%2.2x)", *next_char, 
*next_char);
-#endif
+               if( debug_gdb_io ){
+                       LOG_DEBUG("returned char '%c' (0x%2.2x)", *next_char, 
*next_char);
+               }
 
                return ERROR_OK;
        }
@@ -217,13 +223,13 @@
 #endif
        }
 
-#ifdef _DEBUG_GDB_IO_
-       debug_buffer = malloc(gdb_con->buf_cnt + 1);
-       memcpy(debug_buffer, gdb_con->buffer, gdb_con->buf_cnt);
-       debug_buffer[gdb_con->buf_cnt] = 0;
-       LOG_DEBUG("received '%s'", debug_buffer);
-       free(debug_buffer);
-#endif
+       if( debug_gdb_io ){
+               debug_buffer = malloc(gdb_con->buf_cnt + 1);
+               memcpy(debug_buffer, gdb_con->buffer, gdb_con->buf_cnt);
+               debug_buffer[gdb_con->buf_cnt] = 0;
+               LOG_DEBUG("received '%s'", debug_buffer);
+               free(debug_buffer);
+       }
 
        gdb_con->buf_p = gdb_con->buffer;
        gdb_con->buf_cnt--;
@@ -232,9 +238,9 @@
                connection->input_pending = 1;
        else
                connection->input_pending = 0;
-#ifdef _DEBUG_GDB_IO_
-       LOG_DEBUG("returned char '%c' (0x%2.2x)", *next_char, *next_char);
-#endif
+       if( debug_gdb_io ){
+               LOG_DEBUG("returned char '%c' (0x%2.2x)", *next_char, 
*next_char);
+       }
 
        return retval;
 }
@@ -277,9 +283,7 @@
 {
        int i;
        unsigned char my_checksum = 0;
-#ifdef _DEBUG_GDB_IO_
        char *debug_buffer;
-#endif
        int reply;
        int retval;
        gdb_connection_t *gdb_con = connection->priv;
@@ -287,34 +291,39 @@
        for (i = 0; i < len; i++)
                my_checksum += buffer[i];
 
-#ifdef _DEBUG_GDB_IO_
-       /* 
-        * At this point we should have nothing in the input queue from GDB,
-        * however sometimes '-' is sent even though we've already received
-        * an ACK (+) for everything we've sent off.
-        */
-       int gotdata;
-       for (;;)
-       {
-               if ((retval=check_pending(connection, 0, &gotdata))!=ERROR_OK)
-                       return retval;
-               if (!gotdata)
-                       break;
-               if ((retval = gdb_get_char(connection, &reply)) != ERROR_OK)
-                       return retval;
-               LOG_WARNING("Discard unexpected char %c", reply);
+       if( debug_gdb_io ){
+               /* 
+                * At this point we should have nothing in the input queue from 
GDB,
+                * however sometimes '-' is sent even though we've already 
received
+                * an ACK (+) for everything we've sent off.
+                */
+               int gotdata;
+               for (;;){
+                       if ((retval=check_pending(connection, 0, 
&gotdata))!=ERROR_OK)
+                               return retval;
+                       if (!gotdata)
+                               break;
+                       if ((retval = gdb_get_char(connection, &reply)) != 
ERROR_OK)
+                               return retval;
+                       if( reply == '$' ){
+                               gdb_putback_char( connection, reply );
+                               LOG_DEBUG("Unexpected start of new packet");
+                               break;
+                       } else {
+                               LOG_WARNING("Discard unexpected char 0x%02x 
%c", reply, safe_toascii(reply));
+                       }
+               }
        }
-#endif
 
        while (1)
        {
-#ifdef _DEBUG_GDB_IO_
-               debug_buffer = malloc(len + 1);
-               memcpy(debug_buffer, buffer, len);
-               debug_buffer[len] = 0;
-               LOG_DEBUG("sending packet '$%s#%2.2x'", debug_buffer, 
my_checksum);
-               free(debug_buffer);
-#endif
+               if( debug_gdb_io ){
+                       debug_buffer = malloc(len + 1);
+                       memcpy(debug_buffer, buffer, len);
+                       debug_buffer[len] = 0;
+                       LOG_DEBUG("sending packet '$%s#%2.2x'", debug_buffer, 
my_checksum);
+                       free(debug_buffer);
+               }
 
                char local_buffer[1024];
                local_buffer[0] = '$';
@@ -347,7 +356,14 @@
 
                if (reply == '+')
                        break;
-               else if (reply == '-')
+               else if( reply == '$' ){
+                       // $ starts a new GDB packet.
+                       // Perhaps GDB is sending a *NEW* packet.
+                       // assume the packet was good.
+                       gdb_putback_char( connection, reply );
+                       LOG_WARNING("Got $, expected - Assuming New Packet");
+                       break;
+               } else if (reply == '-')
                {
                        /* Stop sending output packets for now */
                        log_remove_callback(gdb_log_callback, connection);
@@ -368,14 +384,14 @@
                        }
                        else
                        {
-                               LOG_ERROR("unknown character 0x%2.2x in reply, 
dropping connection", reply);
+                               LOG_ERROR("(^C) unknown character 0x%2.2x (%c) 
in reply, dropping connection", reply, safe_toascii(reply));
                                gdb_con->closed=1;
                                return ERROR_SERVER_REMOTE_CLOSED;
                        }
                }
                else
                {
-                       LOG_ERROR("unknown character 0x%2.2x in reply, dropping 
connection", reply);
+                       LOG_ERROR("(?) unknown character 0x%2.2x (%c) in reply, 
dropping connection", reply, safe_toascii(reply));
                        gdb_con->closed=1;
                        return ERROR_SERVER_REMOTE_CLOSED;
                }
@@ -517,9 +533,9 @@
                        if ((retval = gdb_get_char(connection, &character)) != 
ERROR_OK)
                                return retval;
 
-#ifdef _DEBUG_GDB_IO_
-                       LOG_DEBUG("character: '%c'", character);
-#endif
+                       if( debug_gdb_io ){
+                               LOG_DEBUG("character: '%c'", character);
+                       }
 
                        switch (character)
                        {
@@ -538,7 +554,7 @@
                                        *len = 0;
                                        return ERROR_OK;
                                default:
-                                       LOG_WARNING("ignoring character 0x%x", 
character);
+                                       LOG_WARNING("ignoring character 0x%x 
(%c)", character, safe_toascii(character) );
                                        break;
                        }
                } while (character != '$');
@@ -585,25 +601,42 @@
        return retval;
 }
 
+static int gdb_max_o_packet = 256;
 int gdb_output_con(connection_t *connection, const char* line)
 {
        char *hex_buffer;
        int i, bin_size;
+       int n;
 
        bin_size = strlen(line);
+       LOG_DEBUG("TX O packet len: %d, chunksize: %d", 
+                         bin_size, gdb_max_o_packet );
+       
+       if( gdb_max_o_packet > 0 ){
+               hex_buffer = malloc(2+(gdb_max_o_packet*2));
+               if (hex_buffer == NULL)
+                       return ERROR_GDB_BUFFER_TOO_SMALL;
 
-       hex_buffer = malloc(bin_size*2 + 2);
-       if (hex_buffer == NULL)
-               return ERROR_GDB_BUFFER_TOO_SMALL;
+               while( bin_size ){
+                       n = bin_size;
+                       if( n > gdb_max_o_packet ){
+                               n = gdb_max_o_packet;
+                       }
+                       
+                       
+                       hex_buffer[0] = 'O';
+                       for (i=0; i<n; i++)
+                               snprintf(hex_buffer + 1 + i*2, 3, "%2.2x", 
line[i]);
+                       hex_buffer[(n*2)+1] = 0;
+                       
+                       gdb_put_packet(connection, hex_buffer, (n*2) + 1);
+                       line     += n;
+                       bin_size -= n;
+               }
+               
+               free(hex_buffer);               
+       }
 
-       hex_buffer[0] = 'O';
-       for (i=0; i<bin_size; i++)
-               snprintf(hex_buffer + 1 + i*2, 3, "%2.2x", line[i]);
-       hex_buffer[bin_size*2+1] = 0;
-
-       gdb_put_packet(connection, hex_buffer, bin_size*2 + 1);
-
-       free(hex_buffer);
        return ERROR_OK;
 }
 
@@ -845,9 +878,9 @@
        char *reg_packet_p;
        int i;
 
-#ifdef _DEBUG_GDB_IO_
-       LOG_DEBUG("-");
-#endif
+       if( debug_gdb_io ){
+               LOG_DEBUG("-");
+       }
 
        if ((retval = target->type->get_gdb_reg_list(target, &reg_list, 
&reg_list_size)) != ERROR_OK)
        {
@@ -868,15 +901,14 @@
                reg_packet_p += CEIL(reg_list[i]->size, 8) * 2;
        }
 
-#ifdef _DEBUG_GDB_IO_
-       {
+       if( debug_gdb_io ){
                char *reg_packet_p;
                reg_packet_p = strndup(reg_packet, CEIL(reg_packet_size, 8) * 
2);
                LOG_DEBUG("reg_packet: %s", reg_packet_p);
                free(reg_packet_p);
        }
-#endif
 
+
        gdb_put_packet(connection, reg_packet, CEIL(reg_packet_size, 8) * 2);
        free(reg_packet);
 
@@ -893,9 +925,9 @@
        int retval;
        char *packet_p;
 
-#ifdef _DEBUG_GDB_IO_
-       LOG_DEBUG("-");
-#endif
+       if( debug_gdb_io ){
+               LOG_DEBUG("-");
+       }
 
        /* skip command character */
        packet++;
@@ -959,9 +991,9 @@
        int reg_list_size;
        int retval;
 
-#ifdef _DEBUG_GDB_IO_
-       LOG_DEBUG("-");
-#endif
+       if( debug_gdb_io ){
+               LOG_DEBUG("-");
+       }
 
        if ((retval = target->type->get_gdb_reg_list(target, &reg_list, 
&reg_list_size)) != ERROR_OK)
        {
@@ -2258,9 +2290,137 @@
        return ERROR_OK;
 }
 
+static int
+gdb_config( Jim_GetOptInfo *goi )
+{
+       jim_wide w;
+       int e;
+       Jim_Nvp *n;
+       enum {
+               GDB_CONFIG_MAX_OPACKET,
+               GDB_DEBUG_IO,
+       };
+       const Jim_Nvp nvp_gdb_config[] = {
+               { .name = "-max-O-packet", .value = GDB_CONFIG_MAX_OPACKET },
+               { .name = "-debug-io"    , .value = GDB_DEBUG_IO },
+               // terminate 
+               { .name = NULL, .value = -1 },
+       };
 
+       while( goi->argc ){
+               e = Jim_GetOpt_Nvp( goi, nvp_gdb_config, &n );
+               if( e != JIM_OK ){
+                       Jim_GetOpt_NvpUnknown( goi, nvp_gdb_config, 1 );
+                       return JIM_ERR;
+               }
+               
+               switch( n->value ){
+               default:
+                       Jim_SetResult_sprintf( goi->interp, "Unknown cfg option 
%d\n", n->value );
+                       return JIM_ERR;
+               case GDB_DEBUG_IO:
+                       if( goi->isconfigure ){
+                               if( goi->argc != 1 ){
+                                       Jim_WrongNumArgs(interp, 2, 
goi->argv-2, "VALUE");
+                                       return JIM_ERR;
+                               }
+                               e = Jim_GetOpt_Wide( goi, &w );
+                               if( e != JIM_OK ){
+                                       return e;
+                               }
+                               if( (w == 0) || (w==1) ){
+                                       // good
+                               } else {
+                                       /* this is a bit excessive... */
+                                       Jim_SetResult_sprintf( goi->interp, 
+                                                                               
   "Expected 0/1, not %d", (int)(w) );
+                                       return JIM_ERR;
+                               }
+                               debug_gdb_io = 1;
+                       }
+                       Jim_SetResult( interp, Jim_NewIntObj( goi->interp, 
debug_gdb_io ));
+                       break;
+
+               case GDB_CONFIG_MAX_OPACKET:
+                       if( goi->isconfigure ){
+                               if( goi->argc != 1 ){
+                                       Jim_WrongNumArgs(interp, 2, 
goi->argv-2, "VALUE");
+                                       return JIM_ERR;
+                               }
+                               e = Jim_GetOpt_Wide( goi, &w );
+                               if( e != JIM_OK ){
+                                       return e;
+                               }
+                               if( (w > 2048) || (w < -1) ){
+                                       /* this is a bit excessive... */
+                                       Jim_SetResult_sprintf( goi->interp, 
"opacket max is 512, 0 or -1 to disable O packets");
+                                       return JIM_ERR;
+                               }
+                               if( w < 0 ){
+                                       w = 0;
+                               }
+                               gdb_max_o_packet = w;
+                       }
+                       Jim_SetResult( interp, Jim_NewIntObj( goi->interp, 
gdb_max_o_packet ) );
+                       break;
+               }
+       }
+       return JIM_OK;
+}                      
+
+static int
+jim_gdb_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
+{
+       Jim_GetOptInfo goi;
+       Jim_Nvp *n;
+       int e;
+
+       enum {
+               GDB_CMD_CONFIG,
+               GDB_CMD_CGET
+       };
+
+       const Jim_Nvp nvp_gdb_commands[] = {
+               { .name = "configure", .value = GDB_CMD_CONFIG },
+               { .name = "cget", .value = GDB_CMD_CGET },
+               // add more here later
+               { .name = NULL, .value = -1 },
+       };
+       
+       
+       /* go past cmd name */
+       Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 );
+
+       e = Jim_GetOpt_Nvp( &goi, nvp_gdb_commands, &n );
+       if( e != JIM_OK ){
+               Jim_GetOpt_NvpUnknown( &goi, nvp_gdb_commands, 1 );
+               return JIM_ERR;
+       }
+       Jim_SetEmptyResult( goi.interp );
+       switch(n->value){
+       default:
+               Jim_SetResultString( goi.interp, "(gdb command) unknown 
option",-1);
+               return JIM_ERR;
+               break;
+       case GDB_CMD_CONFIG:
+               goi.isconfigure = 1;
+               return gdb_config( &goi );
+               break;
+       case GDB_CMD_CGET:
+               goi.isconfigure = 0;
+               return gdb_config( &goi );
+               break;
+       }
+}
+
+
 int gdb_register_commands(command_context_t *command_context)
 {
+       register_jim( command_context,
+                                 "gdb",
+                                 jim_gdb_command,
+                                 "(try gdb -help) for details");
+
        register_command(command_context, NULL, "gdb_port", 
handle_gdb_port_command,
                        COMMAND_CONFIG, "");
        register_command(command_context, NULL, "gdb_detach", 
handle_gdb_detach_command,
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to