* [RFA] Fix memory corruption when writting in inferior memory
@ 2003-06-01 6:34 Joel Brobecker
2003-06-10 17:12 ` Kevin Buettner
0 siblings, 1 reply; 3+ messages in thread
From: Joel Brobecker @ 2003-06-01 6:34 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 3024 bytes --]
Hello,
This occurs on AiX (4.3.2 or 5.1). The case that we came across was with
an Ada program that contains a function with a string as a parameter.
We noticed that the string was not always correctly passed when the
function was called from GDB. For instance, we saw:
(gdb) call trace ("1234567890")
Trace_Message:
(gdb)
But we expected:
(gdb) call trace ("1234567890")
Trace_Message: 1234567890
(gdb)
Contrary to C, our Ada-mode no longer uses malloc() to allocate some
memory for the string, but rather pushes the string on the stack.
As you may have noticed, the string length is not a multiple of 4.
A string in Ada is an array of characters. Arrays in Ada is actually
fat pointers, that is a structure containings 2 fields: the first field
is a pointer to the array, and the second field is a pointer to a
structure containing the 2 bounds.
In C parlance, a string would be defined like this:
struct { int UB0; int LB0; } string___XUB;
struct { char *P_ARRAY; struct string___XUB *P_BOUNDS; } string;
So, what happens when GDB the Ada mode pushes the string on the stack
is the following (say SP is equal to Addr, Addr being a multiple of 4).
The pushing is done by push_bytes(), which eventually calls
target_xfer_memory() which in our case is set to child_xfer_memory()
in rs6000-nat.c.
1. GDB pushes the bounds (8 bytes) at Addr - 8
2. GDB pushes the string (10 bytes), at Addr - 18
3. GDB pushes the string struct (8 bytes) at Addr - 26.
child_xfer_memory() needs to do the write operation in chunks of words,
and these chunks must be 4byte aligned. So when do step 2, it creates a
3 words buffer, reads the word at Addr - 20 to get the first 2 bytes,
fills in the next 10 bytes, and then writes 3 words at Addr - 20.
So far, so good.
For the next write operation, child_xfer_memory() needs to write 8 bytes
at Addr - 26. Addr - 26 is not 4bytes aligned, so GDB decides to write
at Addr - 28. And to be able to write the full structure, GDB will need
to write 3 words. As before, it reads the first two bytes, and then
decides to read the last 2 bytes, before then filling in the rest.
Unfortunately, it used the wrong address for reading the trailing bytes.
This later causes a memory corruption on the string that we just wrote,
when we finally write the buffer into memory, which explains the problem
we've seen.
The attached patch fixes it. It has been tested on powerpc-aix version
4.3.2 and 5.1, and shows no regression. Given the fact that the C mode
uses malloc() to allocate its inferior memory, I was not too surprised
that the test results did not improve.
Ok to commit?
2003-05-31 J. Brobecker <brobecker@gnat.com>
* rs6000-nat.c (child_xfer_memory): Compute the right address when
fetching the trailing bytes of the buffer we are about to write.
Thanks,
--
Joel
BTW: libiberty no longer builds on AiX 4.3.2, and I suspect on any AiX 4.x.
I think I have the proper fix for it, will send it shortly, after I have
tested it on 5.x.
[-- Attachment #2: rs6000-nat.c.diff --]
[-- Type: text/plain, Size: 992 bytes --]
Index: rs6000-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-nat.c,v
retrieving revision 1.30
diff -u -7 -p -r1.30 rs6000-nat.c
--- rs6000-nat.c 8 May 2003 20:52:48 -0000 1.30
+++ rs6000-nat.c 1 Jun 2003 06:30:01 -0000
@@ -481,15 +481,16 @@ child_xfer_memory (CORE_ADDR memaddr, ch
/* Fetch leading memory needed for alignment. */
if (addr < memaddr)
if (!read_word (addr, buf, arch64))
return 0;
/* Fetch trailing memory needed for alignment. */
if (addr + count * sizeof (int) > memaddr + len)
- if (!read_word (addr, buf + count - 1, arch64))
+ if (!read_word (addr + (count - 1) * sizeof (int),
+ buf + count - 1, arch64))
return 0;
/* Copy supplied data into memory buffer. */
memcpy ((char *)buf + (memaddr - addr), myaddr, len);
/* Store memory one word at a time. */
for (i = 0, errno = 0; i < count; i++, addr += sizeof (int))
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFA] Fix memory corruption when writting in inferior memory
2003-06-01 6:34 [RFA] Fix memory corruption when writting in inferior memory Joel Brobecker
@ 2003-06-10 17:12 ` Kevin Buettner
2003-06-10 20:35 ` Joel Brobecker
0 siblings, 1 reply; 3+ messages in thread
From: Kevin Buettner @ 2003-06-10 17:12 UTC (permalink / raw)
To: Joel Brobecker, gdb-patches
On May 31, 11:33pm, Joel Brobecker wrote:
> Ok to commit?
>
> 2003-05-31 J. Brobecker <brobecker@gnat.com>
>
> * rs6000-nat.c (child_xfer_memory): Compute the right address when
> fetching the trailing bytes of the buffer we are about to write.
Okay.
Kevin
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFA] Fix memory corruption when writting in inferior memory
2003-06-10 17:12 ` Kevin Buettner
@ 2003-06-10 20:35 ` Joel Brobecker
0 siblings, 0 replies; 3+ messages in thread
From: Joel Brobecker @ 2003-06-10 20:35 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
> > 2003-05-31 J. Brobecker <brobecker@gnat.com>
> >
> > * rs6000-nat.c (child_xfer_memory): Compute the right address when
> > fetching the trailing bytes of the buffer we are about to write.
>
> Okay.
Thank you, checked in.
--
Joel
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-06-10 20:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-06-01 6:34 [RFA] Fix memory corruption when writting in inferior memory Joel Brobecker
2003-06-10 17:12 ` Kevin Buettner
2003-06-10 20:35 ` Joel Brobecker
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox