This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
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:
rs6000-nat.c.diff
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |