This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[commit+7.5] Fix /proc access regression on older Linux kernels
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 2 Aug 2012 18:04:32 +0200 (CEST)
- Subject: [commit+7.5] Fix /proc access regression on older Linux kernels
Hello,
this patch fixes an unfortunate regression introduced by my patch series to
support /proc file access for remote targets. As a side-effect of these
patches, GDB (or gdbserver) will now actually use a "pread" system call
on /proc files.
This works fine on recent Linux kernels. However, on certain older kernels
(e.g. the 2.6.18 in RHEL 5), pread on some /proc files, in particular on
/proc/.../maps, will always fail with an errno of ESPIPE. This means that
current GDB on such systems will fail to properly execute any command that
requires /proc access, in particular "info proc" and "gcore".
The fix is to detect a failing pread call and fall back to doing an lseek
and read, as would be done anyway on systems without pread. This works
fine on those /proc files even on old Linux kernels.
Tested on spu-elf, powerpc(64)-linux, and arm-linux-gnuabi in both
native and remote testing.
Committed to mainline and 7.5.
Bye,
Ulrich
ChangeLog:
* inf-child.c (inf_child_fileio_pwrite): If pwrite fails, fall back
to attempting lseek/write.
(inf_child_fileio_pread): Likewise for pread.
gdbserver/ChangeLog:
* hostio.c (handle_pread): If pread fails, fall back to attempting
lseek/read.
(handle_pwrite): Likewise for pwrite.
Index: gdb/inf-child.c
===================================================================
RCS file: /cvs/src/src/gdb/inf-child.c,v
retrieving revision 1.34
diff -u -p -r1.34 inf-child.c
--- gdb/inf-child.c 24 May 2012 16:39:09 -0000 1.34
+++ gdb/inf-child.c 2 Aug 2012 13:28:32 -0000
@@ -265,10 +265,15 @@ inf_child_fileio_pwrite (int fd, const g
#ifdef HAVE_PWRITE
ret = pwrite (fd, write_buf, len, (long) offset);
#else
- ret = lseek (fd, (long) offset, SEEK_SET);
- if (ret != -1)
- ret = write (fd, write_buf, len);
+ ret = -1;
#endif
+ /* If we have no pwrite or it failed for this file, use lseek/write. */
+ if (ret == -1)
+ {
+ ret = lseek (fd, (long) offset, SEEK_SET);
+ if (ret != -1)
+ ret = write (fd, write_buf, len);
+ }
if (ret == -1)
*target_errno = inf_child_errno_to_fileio_error (errno);
@@ -288,10 +293,15 @@ inf_child_fileio_pread (int fd, gdb_byte
#ifdef HAVE_PREAD
ret = pread (fd, read_buf, len, (long) offset);
#else
- ret = lseek (fd, (long) offset, SEEK_SET);
- if (ret != -1)
- ret = read (fd, read_buf, len);
+ ret = -1;
#endif
+ /* If we have no pread or it failed for this file, use lseek/read. */
+ if (ret == -1)
+ {
+ ret = lseek (fd, (long) offset, SEEK_SET);
+ if (ret != -1)
+ ret = read (fd, read_buf, len);
+ }
if (ret == -1)
*target_errno = inf_child_errno_to_fileio_error (errno);
Index: gdb/gdbserver/hostio.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/hostio.c,v
retrieving revision 1.18
diff -u -p -r1.18 hostio.c
--- gdb/gdbserver/hostio.c 9 Feb 2012 17:29:34 -0000 1.18
+++ gdb/gdbserver/hostio.c 2 Aug 2012 13:28:32 -0000
@@ -328,10 +328,15 @@ handle_pread (char *own_buf, int *new_pa
#ifdef HAVE_PREAD
ret = pread (fd, data, len, offset);
#else
- ret = lseek (fd, offset, SEEK_SET);
- if (ret != -1)
- ret = read (fd, data, len);
+ ret = -1;
#endif
+ /* If we have no pread or it failed for this file, use lseek/read. */
+ if (ret == -1)
+ {
+ ret = lseek (fd, offset, SEEK_SET);
+ if (ret != -1)
+ ret = read (fd, data, len);
+ }
if (ret == -1)
{
@@ -376,10 +381,15 @@ handle_pwrite (char *own_buf, int packet
#ifdef HAVE_PWRITE
ret = pwrite (fd, data, len, offset);
#else
- ret = lseek (fd, offset, SEEK_SET);
- if (ret != -1)
- ret = write (fd, data, len);
+ ret = -1;
#endif
+ /* If we have no pwrite or it failed for this file, use lseek/write. */
+ if (ret == -1)
+ {
+ ret = lseek (fd, offset, SEEK_SET);
+ if (ret != -1)
+ ret = write (fd, data, len);
+ }
if (ret == -1)
{
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com