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
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development