Currently size of the GDB buffer is 16384 bytes but it is treated as
nul-terminated string in most of the code, so effective size of the
buffer is actually 16383 bytes. OpenOCD responds with `PacketSize=3fff`
to qSupported request. Result of GDB's `m` command is encoded in hex so
each data byte uses two bytes in the buffer. As a result GDB will split
bulk read requests into chunks 0x1fff bytes each. This causes troubles
on targets (or memory regions) which support only aligned, word-sized
access (such as MMIO buffers).
Steps to reproduce (psoc6 target):
gdb> dump binary memory dump.bin 0x040320000 (0x040320000 + 65536)
OpenOCD:
Error: Failed to read memory at 0x40321ffe
Error: Failed to read memory at 0x40321000
Error: Failed to read memory at 0x40323000
Error: Failed to read memory at 0x40325ffe
Error: Failed to read memory at 0x40329ffa
Error: Failed to read memory at 0x40329ffc
Error: Failed to read memory at 0x4032bffc
Error: Failed to read memory at 0x4032dffa
Consolidate GDB_BUFFER_SIZE usage: ensure size of each buffer is
(GDB_BUFFER_SIZE + 1), add explicit comment that additional byte is used
for nul-termination. Report correct size of the buffer to GDB (0x4000)
as recommended in GDB's docummentation: `if the stub stores packets in a
NUL-terminated format, it should allow an extra byte in its buffer for
the NUL`
Checked with clang-asan, clang-analyzer, valgrind - no new errors.
Change-Id: I909e8a2c6b010c5d4a304641808d4a807a4ec18d
Signed-off-by: Bohdan Tymkiv <bhdt@cypress.com>
Reviewed-on: http://openocd.zylin.com/5109
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
static int nuttx_thread_packet(struct connection *connection,
char const *packet, int packet_size)
{
static int nuttx_thread_packet(struct connection *connection,
char const *packet, int packet_size)
{
- char cmd[GDB_BUFFER_SIZE / 2] = "";
+ char cmd[GDB_BUFFER_SIZE / 2 + 1] = ""; /* Extra byte for nul-termination */
if (!strncmp(packet, "qRcmd", 5)) {
size_t len = unhexify((uint8_t *)cmd, packet + 6, sizeof(cmd));
if (!strncmp(packet, "qRcmd", 5)) {
size_t len = unhexify((uint8_t *)cmd, packet + 6, sizeof(cmd));
int rtos_detected = 0;
uint64_t addr = 0;
size_t reply_len;
int rtos_detected = 0;
uint64_t addr = 0;
size_t reply_len;
- char reply[GDB_BUFFER_SIZE], cur_sym[GDB_BUFFER_SIZE / 2] = "";
+ char reply[GDB_BUFFER_SIZE + 1], cur_sym[GDB_BUFFER_SIZE / 2 + 1] = ""; /* Extra byte for nul-termination */
symbol_table_elem_t *next_sym = NULL;
struct target *target = get_target_from_connection(connection);
struct rtos *os = target->rtos;
symbol_table_elem_t *next_sym = NULL;
struct target *target = get_target_from_connection(connection);
struct rtos *os = target->rtos;
/* private connection data for GDB */
struct gdb_connection {
/* private connection data for GDB */
struct gdb_connection {
- char buffer[GDB_BUFFER_SIZE];
+ char buffer[GDB_BUFFER_SIZE + 1]; /* Extra byte for nul-termination */
char *buf_p;
int buf_cnt;
int ctrl_c;
char *buf_p;
int buf_cnt;
int ctrl_c;
/* We don't have to worry about the default 2 second timeout for GDB packets,
* because GDB breaks up large memory reads into smaller reads.
/* We don't have to worry about the default 2 second timeout for GDB packets,
* because GDB breaks up large memory reads into smaller reads.
- *
- * 8191 bytes by the looks of it. Why 8191 bytes instead of 8192?????
*/
static int gdb_read_memory_packet(struct connection *connection,
char const *packet, int packet_size)
*/
static int gdb_read_memory_packet(struct connection *connection,
char const *packet, int packet_size)
&pos,
&size,
"PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+;vContSupported+",
&pos,
&size,
"PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+;vContSupported+",
((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-',
(gdb_target_desc_supported == 1) ? '+' : '-');
((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-',
(gdb_target_desc_supported == 1) ? '+' : '-');
static int gdb_input_inner(struct connection *connection)
{
/* Do not allocate this on the stack */
static int gdb_input_inner(struct connection *connection)
{
/* Do not allocate this on the stack */
- static char gdb_packet_buffer[GDB_BUFFER_SIZE];
+ static char gdb_packet_buffer[GDB_BUFFER_SIZE + 1]; /* Extra byte for nul-termination */
struct target *target;
char const *packet = gdb_packet_buffer;
struct target *target;
char const *packet = gdb_packet_buffer;
* drain the rest of the buffer.
*/
do {
* drain the rest of the buffer.
*/
do {
- packet_size = GDB_BUFFER_SIZE-1;
+ packet_size = GDB_BUFFER_SIZE;
retval = gdb_get_packet(connection, gdb_packet_buffer, &packet_size);
if (retval != ERROR_OK)
return retval;
retval = gdb_get_packet(connection, gdb_packet_buffer, &packet_size);
if (retval != ERROR_OK)
return retval;
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)