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

multithreaded watchpoints for i386 gdb


Hi,
 
this implements multithreaded watchpoints for I386 gdb.
i tested it on a heavily multithreaded application on
SUSE10.1/kernel 2.6.16.21.
 
 
 
best regards
 
Christian
 
 
 

ChangeLog:
 

 * thread.c (prune_threads): declare non-static 
 to be callable by i386-linux-nat.c.
 

 * i386-linux-nat.c (iterate_thread_callback): New function
 serves as callback for iterate_over_threads.
 
 (i386_linux_dr_set ): if multithreaded set DR reg in every thread's
 process descriptor.
 
 
 
 
 
 
 
diff -up ../originalModules/thread.c ./thread.c
--- ../originalModules/thread.c 2005-12-17 23:34:04.000000000 +0100
+++ ./thread.c  2008-02-20 13:21:52.000000000 +0100
@@ -64,7 +64,7 @@ static void info_threads_command (char *
 static void thread_apply_command (char *, int);
 static void restore_current_thread (ptid_t);
 static void switch_to_thread (ptid_t ptid);
-static void prune_threads (void);
+void prune_threads (void);
 
 void
 delete_step_resume_breakpoint (void *arg)
@@ -382,7 +382,7 @@ thread_alive (struct thread_info *tp)
   return 1;
 }
 
-static void
+void
 prune_threads (void)
 {
   struct thread_info *tp, *next;
 
 
 
diff -up ../originalModules/i386-linux-nat.c ./i386-linux-nat.c
--- ../originalModules/i386-linux-nat.c 2006-08-09 00:32:38.000000000 +0200
+++ ./i386-linux-nat.c  2008-02-20 14:32:40.000000000 +0100
@@ -33,6 +33,8 @@
 #include <sys/user.h>
 #include <sys/procfs.h>
 
+#include "gdbthread.h"
+
 #ifdef HAVE_SYS_REG_H
 #include <sys/reg.h>
 #endif
@@ -642,6 +644,35 @@ i386_linux_dr_get (int regnum)
   return value;
 }
 
+
+/* christian hoffmann (hc002821@arcor.de <mailto:hc002821@arcor.de> ) multithreaded watchpoints */
+
+#define MAX_THREADS_PER_PROCESS 100
+
+static struct thread_info *pThreadInfoArray[MAX_THREADS_PER_PROCESS];
+static int threadArrayIndex;
+
+/* callback function for iterate_over_threads called from within i386_linux_dr_set.
+   since we return 0 we will be called for every thread of the debugee.
+   store every pThreadInfo and the number of threads for use in i386_linux_dr_set. */
+
+static int
+iterate_thread_callback(struct thread_info *pThreadInfo, void *pData)
+{
+  pThreadInfoArray[threadArrayIndex] = pThreadInfo;
+  threadArrayIndex++;
+  if (threadArrayIndex >= MAX_THREADS_PER_PROCESS)
+    {
+     return 1;  /* stop the loop.      iterate_over_threads will return != NULL so nothing be done */
+    }
+    else
+    {
+     return 0;
+    }
+}
+
+
+
 static void
 i386_linux_dr_set (int regnum, unsigned long value)
 {
@@ -650,13 +681,53 @@ i386_linux_dr_set (int regnum, unsigned
   /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
      multi-threaded processes here.  For now, pretend there is just
      one thread.  */
-  tid = PIDGET (inferior_ptid);
-
-  errno = 0;
-  ptrace (PTRACE_POKEUSER, tid,
-         offsetof (struct user, u_debugreg[regnum]), value);
-  if (errno != 0)
-    perror_with_name (_("Couldn't write debug register"));
+
+  /* christian hoffmann (hc002821@arcor.de <mailto:hc002821@arcor.de> ) multithreaded watchpoints */
+
+  int i;
+  struct thread_info *rc;
+
+  tid = TIDGET (inferior_ptid);
+  if (tid == 0)
+    {
+      /* single threaded application */
+      tid = PIDGET (inferior_ptid);
+      errno = 0;
+      ptrace (PTRACE_POKEUSER, tid,
+             offsetof (struct user, u_debugreg[regnum]), value);
+      if (errno != 0)
+        perror_with_name (_("Couldn't write debug register"));
+    }
+  else
+  {
+      /* multi threaded application. update DR in every threads process descriptor */
+      memset (pThreadInfoArray, 0, sizeof(pThreadInfoArray));
+      threadArrayIndex = 0;
+      /* the following 2 calls are necessary to update our thread list */
+      prune_threads ();
+      target_find_new_threads ();
+
+      rc = iterate_over_threads (iterate_thread_callback, NULL);
+      if(rc != NULL)
+      {
+       printf("i386_linux_dr_set multi-threaded iterate_over_threads failed\n");
+      }
+      else
+      {
+       for (i=0; i<MAX_THREADS_PER_PROCESS; i++)   /* avoid endless loop */
+       {
+        errno = 0;
+        if( (pThreadInfoArray[i] == NULL)||(i == threadArrayIndex) )
+        {
+         break;
+        }
+        ptrace (PTRACE_POKEUSER, TIDGET(pThreadInfoArray[i]->ptid),
+             offsetof (struct user, u_debugreg[regnum]), value);
+        if (errno != 0)
+          perror_with_name (_("Couldn't write debug register"));
+       }
+      }
+  }
 }
 
 void

 

Mit freundlichen Grüßen/ kind regards 

Christian Hoffmann

Siemens Enterprise Communications GmbH & Co. KG 
Small Medium Enterprice Software Development Platform 

SEN ESY SME MP532
Brauckstr.14
D-58449 Witten
Phone: +49 2302 667 2821 
Fax: +49 2302 667 2121
Email : Christian-Hoffmann@siemens.com 

Communication for the open minded
www.siemens.de/open <http://www.siemens.de/open> 
www.siemens.com/open <http://www.siemens.com/open>  

Siemens Enterprise Communications GmbH & Co. KG
Managing Directors: Andreas Bernhardt, Reinhard Benditte,
Gerhard Otterbach, Thomas Zimmermann
Registered offices: Munich
Commercial registry Munich, HRA 88546
WEEE-Reg.-No. DE 27980375
General Partner:
Siemens Enterprise Communications Management GmbH
Registered offices: Munich
Commercial registry: Munich, HRB 163415 



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