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, ®_list, ®_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, ®_list, ®_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