This is the mail archive of the gdb-patches@sourceware.cygnus.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]

Patch: gdb -vs- Debian 2.0


I'm still running Debian 2.0, kernel 2.0.34.  Recently gdb stopped
working on this platform.  I tracked this down to code in
i386-linux-nat.c which uses PTRACE_GETREGS, which is not implemented
in this kernel.

This patch fixes the problem by falling back on the old method when
ptrace fails.  I'm not entirely certain that the infptrace.c part of
this patch is correct (in particular, is it safe to unconditionally
compile the code that was formerly bracketed by
FETCH_INFERIOR_REGISTERS?).  For that matter, I'm not entirely sure
about the patch as a whole, though it does seem to work for me.

I didn't run the test suite since the results would be meaningless --
very little passed before this patch.

One concern might be: how much backwards compatibility do we want?  I
don't think Debian 2.0 is all that old, but others might think
differently.

Comments?  Questions?  Ok to commit?

1999-11-18  Tom Tromey  <tromey@cygnus.com>

	* i386-linux-nat.c (ptrace_getregs_fails): New global.
	(fetch_regs): Set ptrace_getregs_fails when appropriate.
	(fetch_inferior_registers): Call ptrace_fetch_inferior_registers
	when appropriate.
	(store_inferior_registers): Call ptrace_store_inferior_registers
	when appropriate.
	* infptrace.c (ptrace_fetch_inferior_registers): Renamed from
	fetch_inferior_registers.
	(ptrace_store_inferior_registers): Renamed from
	store_inferior_registers.
	(fetch_inferior_registers): New function.
	(store_inferior_registers): New function.

Tom

Index: i386-linux-nat.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/i386-linux-nat.c,v
retrieving revision 1.7
diff -u -r1.7 i386-linux-nat.c
--- i386-linux-nat.c	1999/11/03 21:12:27	1.7
+++ i386-linux-nat.c	1999/11/19 06:05:20
@@ -70,7 +70,13 @@
 #endif
 ;
 
+/* If nonzero, we've determined that this kernel does not support
+   PTRACE_GETREGS.  In this case we use the old-style ptrace support
+   when fetching or setting registers.  */
 
+static int ptrace_getregs_fails = 0;
+
+
 
 /* Transfering the general registers between GDB, inferiors and core files.  */
 
@@ -142,7 +148,15 @@
   ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int) &buf);
   if (ret < 0)
     {
-      warning ("Couldn't get registers");
+      if (errno == EIO)
+	{
+	  /* Some Linux kernels don't support PTRACE_GETREGS.  We fall
+	     back to old-style ptrace support in that case.  */
+	  ptrace_getregs_fails = 1;
+	  ptrace_fetch_inferior_registers (-1);
+	}
+      else
+	warning ("Couldn't get registers");
       return;
     }
 
@@ -161,8 +175,18 @@
   ret = ptrace (PTRACE_GETREGS, inferior_pid, 0, (int) &buf);
   if (ret < 0)
     {
-      warning ("Couldn't get registers");
-      return;
+      if (errno == EIO)
+	{
+	  /* Some Linux kernels don't support PTRACE_SETREGS.  We fall
+	     back to old-style ptrace support in that case.  */
+	  ptrace_getregs_fails = 1;
+	  ptrace_fetch_inferior_registers (-1);
+	}
+      else
+	{
+	  warning ("Couldn't get registers");
+	  return;
+	}
     }
 
   convert_to_gregset (&buf, registers, register_valid);
@@ -521,13 +545,20 @@
 void
 fetch_inferior_registers (int regno)
 {
+  if (ptrace_getregs_fails)
+    {
+      ptrace_fetch_inferior_registers (regno);
+      return;
+    }
+
   /* Use the xfpregs requests whenever possible, since they transfer
      more registers in one system call, and we'll cache the results.
      But remember that fetch_xfpregs can fail, and return zero.  */
   if (regno == -1)
     {
       fetch_regs ();
-      if (fetch_xfpregs ())
+      /* ptrace_getregs_fails might have just been set.  */
+      if (ptrace_getregs_fails || fetch_xfpregs ())
 	return;
       fetch_fpregs ();
       return;
@@ -570,13 +601,20 @@
 store_inferior_registers (regno)
      int regno;
 {
+  if (ptrace_getregs_fails)
+    {
+      ptrace_store_inferior_registers (regno);
+      return;
+    }
+
   /* Use the xfpregs requests whenever possible, since they transfer
      more registers in one system call.  But remember that
      fetch_xfpregs can fail, and return zero.  */
   if (regno == -1)
     {
       store_regs ();
-      if (store_xfpregs ())
+      /* ptrace_getregs_fails might have just been set.  */
+      if (ptrace_getregs_fails || store_xfpregs ())
 	return;
       store_fpregs ();
       return;
Index: infptrace.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/infptrace.c,v
retrieving revision 1.70
diff -u -r1.70 infptrace.c
--- infptrace.c	1999/08/08 07:19:46	1.70
+++ infptrace.c	1999/11/19 06:05:26
@@ -334,8 +334,6 @@
 #endif /* KERNEL_U_ADDR_BSD.  */
 }
 
-#if !defined (FETCH_INFERIOR_REGISTERS)
-
 #if !defined (offsetof)
 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
 #endif
@@ -397,7 +395,7 @@
    Otherwise, REGNO specifies which register (so we can save time). */
 
 void
-fetch_inferior_registers (regno)
+ptrace_fetch_inferior_registers (regno)
      int regno;
 {
   if (regno >= 0)
@@ -457,7 +455,7 @@
    Otherwise, REGNO specifies which register (so we can save time).  */
 
 void
-store_inferior_registers (regno)
+ptrace_store_inferior_registers (regno)
      int regno;
 {
   if (regno >= 0)
@@ -472,6 +470,31 @@
 	}
     }
 }
+
+#if !defined (FETCH_INFERIOR_REGISTERS)
+
+/* A wrapper for ptrace_fetch_inferior_registers.  On some platforms
+   we need ptrace_fetch_inferior_registers to be visible with a
+   different name.  */
+
+void
+fetch_inferior_registers (regno)
+     int regno;
+{
+  ptrace_fetch_inferior_registers (regno);
+}
+
+/* A wrapper for ptrace_store_inferior_registers.  On some platforms
+   we need ptrace_store_inferior_registers to be visible with a
+   different name. */
+
+void
+store_inferior_registers (regno)
+     int regno;
+{
+  ptrace_store_inferior_registers (regno);
+}
+
 #endif /* !defined (FETCH_INFERIOR_REGISTERS).  */
 
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]