aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@adacore.com>2014-09-19 18:00:07 -0400
committerJoel Brobecker <brobecker@adacore.com>2014-11-17 07:23:27 +0400
commit43968415b0025fa8e1fa5c813e53e87ae392e977 (patch)
tree1be4b9f060e01c45551a91b758611e1644431024 /gdb/gdbserver
parentabdef8eb901ce829fdc9fbe7eb89c8327c262f07 (diff)
downloadgdb-43968415b0025fa8e1fa5c813e53e87ae392e977.zip
gdb-43968415b0025fa8e1fa5c813e53e87ae392e977.tar.gz
gdb-43968415b0025fa8e1fa5c813e53e87ae392e977.tar.bz2
[gdbserver/lynx] spurious failure to write in inferior memory
We noticed the following error on ppc-lynx178, using just about any program: (gdb) tar remote mytarget:4444 Remote debugging using mytarget:4444 0x000100c8 in _start () (gdb) b try Breakpoint 1 at 0x10844: file try.adb, line 11. (gdb) cont Continuing. !!!-> Cannot remove breakpoints because program is no longer writable. !!!-> Further execution is probably impossible. Breakpoint 1, try () at try.adb:11 11 Local : Integer := 18; And, of course, trying to continue yielded the expected outcome: (gdb) c Continuing. warning: Error removing breakpoint 1 Cannot remove breakpoints because program is no longer writable. Further execution is probably impossible. It turns out that the problem is caused by an intentional test against a variable with an undefined value. After GDB receives notification of the inferior stopping, it tries to remove the breakpoint by sending a memory-write packet ("X10844,4:9 "). This leads us to lynx_write_memory, where it tries to split the memory-write into chunks of 4 bytes. And, in order to handle writes which are not aligned on word boundaries, we have the following code: if (skip > 0 || truncate > 0) /* We need to read the memory at this address in order to preserve the data that we are not overwriting. */ lynx_read_memory (addr, (unsigned char *) &buf, xfer_size); if (errno) return errno; (the comment explains what the code is about). Unfortunately, the not-so-glaring error that we've made here is that we're checking ERRNO regardless of whether we've called lynx_read_memory. In our case, because we are writing 4 bytes aligned on a word boundary, we do not call lynx_read_memory and therefore test an ERRNO with an undefined value. gdb/gdbserver/ChangeLog: * lynx-low.c (lynx_write_memory): Put lynx_read_memory and corresponding ERRNO check in same block.
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r--gdb/gdbserver/ChangeLog5
-rw-r--r--gdb/gdbserver/lynx-low.c12
2 files changed, 12 insertions, 5 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 5a42642..0c25069 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-17 Joel Brobecker <brobecker@adacore.com>
+
+ * lynx-low.c (lynx_write_memory): Put lynx_read_memory and
+ corresponding ERRNO check in same block.
+
2014-11-12 Pedro Alves <palves@redhat.com>
* server.c (cont_thread): Update comment.
diff --git a/gdb/gdbserver/lynx-low.c b/gdb/gdbserver/lynx-low.c
index 96dea03..6178e03 100644
--- a/gdb/gdbserver/lynx-low.c
+++ b/gdb/gdbserver/lynx-low.c
@@ -688,11 +688,13 @@ lynx_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
if (addr + xfer_size > memaddr + len)
truncate = addr + xfer_size - memaddr - len;
if (skip > 0 || truncate > 0)
- /* We need to read the memory at this address in order to preserve
- the data that we are not overwriting. */
- lynx_read_memory (addr, (unsigned char *) &buf, xfer_size);
- if (errno)
- return errno;
+ {
+ /* We need to read the memory at this address in order to preserve
+ the data that we are not overwriting. */
+ lynx_read_memory (addr, (unsigned char *) &buf, xfer_size);
+ if (errno)
+ return errno;
+ }
memcpy ((gdb_byte *) &buf + skip, myaddr + (addr - memaddr) + skip,
xfer_size - skip - truncate);
errno = 0;