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]

[commit] Support large thread IDs in gdbserver


This patch cleans up gdbserver to use unsigned long instead of int for
thread IDs.  I believe both LinuxThreads and NPTL have always used this as
the type of ti_tid; but it hasn't mattered so far, because LinuxThreads TIDs
fit in integers.  However, they're just pointers in NPTL; and in the most
recent Linux kernels, thread IDs are in a section of the heap which shows up
as negative.  The vitally necessary bit of this patch on i386 is the
conversion from strtol to strtoul.  The rest is for consistency, and for
64-bit hosts.

Tested on i386-linux; vastly improves threading results.  The symptom was a
vCont:s;<TID> packet stepping the wrong thread, because no thread matched
TID.  Committed.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

2005-03-03  Daniel Jacobowitz  <dan@codesourcery.com>

	* inferiors.c (change_inferior_id, add_thread, find_inferior_id):
	Take unsigned long arguments for PIDs.
	* linux-low.c (add_process, linux_attach_lwp, linux_attach)
	(linux_thread_alive, linux_wait_for_event, kill_lwp, send_sigstop)
	(wait_for_sigstop, linux_resume_one_process)
	(regsets_fetch_inferior_registers, linux_send_signal)
	(linux_read_auxv): Likewise.  Update the types of variables holding
	PIDs.  Update format string specifiers.
	* linux-low.h (struct process_info, linux_attach_lwp): Likewise.
	* remote-utils.c (prepare_resume_reply): Likewise.
	* server.c (cont_thread, general_thread, step_thread)
	(thread_from_wait, old_thread_from_wait, signal_pid): Change type to
	unsigned long.
	(handle_query): Update format specifiers.
	(handle_v_cont, main): Use strtoul for thread IDs.
	* server.h (struct inferior_list_entry): Use unsigned long for ID.
	(add_thread, find_inferior_id, change_inferior_id, cont_thread)
	(general_thread, step_thread, thread_from_wait)
	(old_thread_from_wait): Update.
	* target.h (struct thread_resume): Use unsigned long for THREAD.
	(struct target_ops): Use unsigned long for arguments to attach and
	thread_alive.

Index: inferiors.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/gdbserver/inferiors.c,v
retrieving revision 1.4
diff -u -p -r1.4 inferiors.c
--- inferiors.c	11 Jun 2002 17:32:39 -0000	1.4
+++ inferiors.c	3 Mar 2005 16:10:01 -0000
@@ -1,5 +1,5 @@
 /* Inferior process information for the remote server for GDB.
-   Copyright 2002
+   Copyright 2002, 2005
    Free Software Foundation, Inc.
 
    Contributed by MontaVista Software.
@@ -66,7 +66,7 @@ for_each_inferior (struct inferior_list 
 
 void
 change_inferior_id (struct inferior_list *list,
-		    int new_id)
+		    unsigned long new_id)
 {
   if (list->head != list->tail)
     error ("tried to change thread ID after multiple threads are created");
@@ -102,7 +102,7 @@ remove_inferior (struct inferior_list *l
 }
 
 void
-add_thread (int thread_id, void *target_data)
+add_thread (unsigned long thread_id, void *target_data)
 {
   struct thread_info *new_thread
     = (struct thread_info *) malloc (sizeof (*new_thread));
@@ -160,7 +160,7 @@ find_inferior (struct inferior_list *lis
 }
 
 struct inferior_list_entry *
-find_inferior_id (struct inferior_list *list, int id)
+find_inferior_id (struct inferior_list *list, unsigned long id)
 {
   struct inferior_list_entry *inf = list->head;
 
Index: linux-low.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.33
diff -u -p -r1.33 linux-low.c
--- linux-low.c	16 Oct 2004 17:42:00 -0000	1.33
+++ linux-low.c	3 Mar 2005 16:16:25 -0000
@@ -1,5 +1,5 @@
 /* Low level interface to ptrace, for the remote server for GDB.
-   Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -112,7 +112,7 @@ get_stop_pc (void)
 }
 
 static void *
-add_process (int pid)
+add_process (unsigned long pid)
 {
   struct process_info *process;
 
@@ -168,13 +168,13 @@ linux_create_inferior (char *program, ch
 /* Attach to an inferior process.  */
 
 void
-linux_attach_lwp (int pid, int tid)
+linux_attach_lwp (unsigned long pid, unsigned long tid)
 {
   struct process_info *new_process;
 
   if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
     {
-      fprintf (stderr, "Cannot attach to process %d: %s (%d)\n", pid,
+      fprintf (stderr, "Cannot attach to process %ld: %s (%d)\n", pid,
 	       strerror (errno), errno);
       fflush (stderr);
 
@@ -202,7 +202,7 @@ linux_attach_lwp (int pid, int tid)
 }
 
 int
-linux_attach (int pid)
+linux_attach (unsigned long pid)
 {
   struct process_info *process;
 
@@ -277,7 +277,7 @@ linux_detach (void)
 
 /* Return nonzero if the given thread is still alive.  */
 static int
-linux_thread_alive (int tid)
+linux_thread_alive (unsigned long tid)
 {
   if (find_inferior_id (&all_threads, tid) != NULL)
     return 1;
@@ -441,7 +441,7 @@ linux_wait_for_event (struct thread_info
       event_child = (struct process_info *)
 	find_inferior (&all_processes, status_pending_p, NULL);
       if (debug_threads && event_child)
-	fprintf (stderr, "Got a pending child %d\n", event_child->lwpid);
+	fprintf (stderr, "Got a pending child %ld\n", event_child->lwpid);
     }
   else
     {
@@ -456,7 +456,7 @@ linux_wait_for_event (struct thread_info
       if (event_child->status_pending_p)
 	{
 	  if (debug_threads)
-	    fprintf (stderr, "Got an event from pending child %d (%04x)\n",
+	    fprintf (stderr, "Got an event from pending child %ld (%04x)\n",
 		     event_child->lwpid, event_child->status_pending);
 	  wstat = event_child->status_pending;
 	  event_child->status_pending_p = 0;
@@ -491,7 +491,7 @@ linux_wait_for_event (struct thread_info
 	  if (! WIFSTOPPED (wstat))
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "Thread %d (LWP %d) exiting\n",
+		fprintf (stderr, "Thread %ld (LWP %ld) exiting\n",
 			 event_child->tid, event_child->head.id);
 
 	      /* If the last thread is exiting, just return.  */
@@ -533,7 +533,7 @@ linux_wait_for_event (struct thread_info
 		  || WSTOPSIG (wstat) == __SIGRTMIN + 1))
 	    {
 	      if (debug_threads)
-		fprintf (stderr, "Ignored signal %d for %d (LWP %d).\n",
+		fprintf (stderr, "Ignored signal %d for %ld (LWP %ld).\n",
 			 WSTOPSIG (wstat), event_child->tid,
 			 event_child->head.id);
 	      linux_resume_one_process (&event_child->head,
@@ -735,7 +735,7 @@ retry:
    thread groups are in use, we need to use tkill.  */
 
 static int
-kill_lwp (int lwpid, int signo)
+kill_lwp (unsigned long lwpid, int signo)
 {
   static int tkill_failed;
 
@@ -772,7 +772,7 @@ send_sigstop (struct inferior_list_entry
     }
 
   if (debug_threads)
-    fprintf (stderr, "Sending sigstop to process %d\n", process->head.id);
+    fprintf (stderr, "Sending sigstop to process %ld\n", process->head.id);
 
   kill_lwp (process->head.id, SIGSTOP);
   process->sigstop_sent = 1;
@@ -783,7 +783,8 @@ wait_for_sigstop (struct inferior_list_e
 {
   struct process_info *process = (struct process_info *) entry;
   struct thread_info *saved_inferior, *thread;
-  int wstat, saved_tid;
+  int wstat;
+  unsigned long saved_tid;
 
   if (process->stopped)
     return;
@@ -863,7 +864,7 @@ linux_resume_one_process (struct inferio
   current_inferior = get_process_thread (process);
 
   if (debug_threads)
-    fprintf (stderr, "Resuming process %d (%s, signal %d, stop %s)\n", inferior_pid,
+    fprintf (stderr, "Resuming process %ld (%s, signal %d, stop %s)\n", inferior_pid,
 	     step ? "step" : "continue", signal,
 	     process->stop_expected ? "expected" : "not expected");
 
@@ -1233,7 +1234,7 @@ regsets_fetch_inferior_registers ()
 	  else
 	    {
 	      char s[256];
-	      sprintf (s, "ptrace(regsets_fetch_inferior_registers) PID=%d",
+	      sprintf (s, "ptrace(regsets_fetch_inferior_registers) PID=%ld",
 		       inferior_pid);
 	      perror (s);
 	    }
@@ -1427,7 +1428,7 @@ linux_look_up_symbols (void)
 static void
 linux_send_signal (int signum)
 {
-  extern int signal_pid;
+  extern unsigned long signal_pid;
 
   if (cont_thread > 0)
     {
@@ -1449,7 +1450,7 @@ linux_read_auxv (CORE_ADDR offset, char 
   char filename[PATH_MAX];
   int fd, n;
 
-  snprintf (filename, sizeof filename, "/proc/%d/auxv", inferior_pid);
+  snprintf (filename, sizeof filename, "/proc/%ld/auxv", inferior_pid);
 
   fd = open (filename, O_RDONLY);
   if (fd < 0)
Index: linux-low.h
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/gdbserver/linux-low.h,v
retrieving revision 1.7
diff -u -p -r1.7 linux-low.h
--- linux-low.h	31 Jan 2004 22:19:32 -0000	1.7
+++ linux-low.h	3 Mar 2005 16:16:11 -0000
@@ -1,5 +1,5 @@
 /* Internal interfaces for the GNU/Linux specific target code for gdbserver.
-   Copyright 2002, 2004 Free Software Foundation, Inc.
+   Copyright 2002, 2004, 2005 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -71,8 +71,8 @@ struct process_info
 {
   struct inferior_list_entry head;
   int thread_known;
-  int lwpid;
-  int tid;
+  unsigned long lwpid;
+  unsigned long tid;
 
   /* If this flag is set, the next SIGSTOP will be ignored (the process will
      be immediately resumed).  */
@@ -115,6 +115,6 @@ struct process_info
 
 extern struct inferior_list all_processes;
 
-void linux_attach_lwp (int pid, int tid);
+void linux_attach_lwp (unsigned long pid, unsigned long tid);
 
 int thread_db_init (void);
Index: remote-utils.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/gdbserver/remote-utils.c,v
retrieving revision 1.22
diff -u -p -r1.22 remote-utils.c
--- remote-utils.c	16 Oct 2004 17:42:00 -0000	1.22
+++ remote-utils.c	3 Mar 2005 16:10:10 -0000
@@ -1,6 +1,6 @@
 /* Remote utility routines for the remote server for GDB.
    Copyright 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004
+   2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -658,7 +658,7 @@ prepare_resume_reply (char *buf, char st
 	  /* FIXME right place to set this? */
 	  thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id;
 	  if (debug_threads)
-	    fprintf (stderr, "Writing resume reply for %d\n\n", thread_from_wait);
+	    fprintf (stderr, "Writing resume reply for %ld\n\n", thread_from_wait);
 	  /* This if (1) ought to be unnecessary.  But remote_wait in GDB
 	     will claim this event belongs to inferior_ptid if we do not
 	     specify a thread, and there's no way for gdbserver to know
@@ -666,7 +666,7 @@ prepare_resume_reply (char *buf, char st
 	  if (1 || old_thread_from_wait != thread_from_wait)
 	    {
 	      general_thread = thread_from_wait;
-	      sprintf (buf, "thread:%x;", thread_from_wait);
+	      sprintf (buf, "thread:%lx;", thread_from_wait);
 	      buf += strlen (buf);
 	      old_thread_from_wait = thread_from_wait;
 	    }
Index: server.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/gdbserver/server.c,v
retrieving revision 1.22
diff -u -p -r1.22 server.c
--- server.c	5 Mar 2004 03:44:27 -0000	1.22
+++ server.c	3 Mar 2005 16:15:56 -0000
@@ -1,5 +1,6 @@
 /* Main code for remote server for GDB.
-   Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004
+   Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004,
+   2005
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -25,11 +26,11 @@
 #include <signal.h>
 #include <sys/wait.h>
 
-int cont_thread;
-int general_thread;
-int step_thread;
-int thread_from_wait;
-int old_thread_from_wait;
+unsigned long cont_thread;
+unsigned long general_thread;
+unsigned long step_thread;
+unsigned long thread_from_wait;
+unsigned long old_thread_from_wait;
 int extended_protocol;
 int server_waiting;
 
@@ -40,7 +41,7 @@ jmp_buf toplevel;
    (user hitting Control-C in the client), and to wait for the child to exit
    when no longer debugging it.  */
 
-int signal_pid;
+unsigned long signal_pid;
 
 static unsigned char
 start_inferior (char *argv[], char *statusptr)
@@ -50,7 +51,7 @@ start_inferior (char *argv[], char *stat
 
   signal_pid = create_inferior (argv[0], argv);
 
-  fprintf (stderr, "Process %s created; pid = %d\n", argv[0],
+  fprintf (stderr, "Process %s created; pid = %ld\n", argv[0],
 	   signal_pid);
 
   signal (SIGTTOU, SIG_IGN);
@@ -102,7 +103,7 @@ handle_query (char *own_buf)
   if (strcmp ("qfThreadInfo", own_buf) == 0)
     {
       thread_ptr = all_threads.head;
-      sprintf (own_buf, "m%x", thread_ptr->id);
+      sprintf (own_buf, "m%lx", thread_ptr->id);
       thread_ptr = thread_ptr->next;
       return;
     }
@@ -111,7 +112,7 @@ handle_query (char *own_buf)
     {
       if (thread_ptr != NULL)
 	{
-	  sprintf (own_buf, "m%x", thread_ptr->id);
+	  sprintf (own_buf, "m%lx", thread_ptr->id);
 	  thread_ptr = thread_ptr->next;
 	  return;
 	}
@@ -217,7 +218,7 @@ handle_v_cont (char *own_buf, char *stat
 	}
       else if (p[0] == ':')
 	{
-	  resume_info[i].thread = strtol (p + 1, &q, 16);
+	  resume_info[i].thread = strtoul (p + 1, &q, 16);
 	  if (p == q)
 	    goto err;
 	  p = q;
@@ -432,16 +433,16 @@ main (int argc, char *argv[])
 	      switch (own_buf[1])
 		{
 		case 'g':
-		  general_thread = strtol (&own_buf[2], NULL, 16);
+		  general_thread = strtoul (&own_buf[2], NULL, 16);
 		  write_ok (own_buf);
 		  set_desired_inferior (1);
 		  break;
 		case 'c':
-		  cont_thread = strtol (&own_buf[2], NULL, 16);
+		  cont_thread = strtoul (&own_buf[2], NULL, 16);
 		  write_ok (own_buf);
 		  break;
 		case 's':
-		  step_thread = strtol (&own_buf[2], NULL, 16);
+		  step_thread = strtoul (&own_buf[2], NULL, 16);
 		  write_ok (own_buf);
 		  break;
 		default:
@@ -530,7 +531,7 @@ main (int argc, char *argv[])
 		  break;
 		}
 	    case 'T':
-	      if (mythread_alive (strtol (&own_buf[1], NULL, 16)))
+	      if (mythread_alive (strtoul (&own_buf[1], NULL, 16)))
 		write_ok (own_buf);
 	      else
 		write_enn (own_buf);
Index: server.h
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/gdbserver/server.h,v
retrieving revision 1.15
diff -u -p -r1.15 server.h
--- server.h	12 Mar 2004 20:51:21 -0000	1.15
+++ server.h	3 Mar 2005 16:10:17 -0000
@@ -1,5 +1,5 @@
 /* Common definitions for remote server for GDB.
-   Copyright 1993, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004
+   Copyright 1993, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -69,7 +69,7 @@ struct inferior_list
 };
 struct inferior_list_entry
 {
-  int id;
+  unsigned long id;
   struct inferior_list_entry *next;
 };
 
@@ -97,7 +97,7 @@ extern struct thread_info *current_infer
 void remove_inferior (struct inferior_list *list,
 		      struct inferior_list_entry *entry);
 void remove_thread (struct thread_info *thread);
-void add_thread (int thread_id, void *target_data);
+void add_thread (unsigned long thread_id, void *target_data);
 void clear_inferiors (void);
 struct inferior_list_entry *find_inferior
      (struct inferior_list *,
@@ -105,21 +105,21 @@ struct inferior_list_entry *find_inferio
 		   void *),
       void *arg);
 struct inferior_list_entry *find_inferior_id (struct inferior_list *list,
-					      int id);
+					      unsigned long id);
 void *inferior_target_data (struct thread_info *);
 void set_inferior_target_data (struct thread_info *, void *);
 void *inferior_regcache_data (struct thread_info *);
 void set_inferior_regcache_data (struct thread_info *, void *);
 void change_inferior_id (struct inferior_list *list,
-			 int new_id);
+			 unsigned long new_id);
 
 /* Public variables in server.c */
 
-extern int cont_thread;
-extern int general_thread;
-extern int step_thread;
-extern int thread_from_wait;
-extern int old_thread_from_wait;
+extern unsigned long cont_thread;
+extern unsigned long general_thread;
+extern unsigned long step_thread;
+extern unsigned long thread_from_wait;
+extern unsigned long old_thread_from_wait;
 extern int server_waiting;
 
 extern jmp_buf toplevel;
Index: target.h
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/gdbserver/target.h,v
retrieving revision 1.11
diff -u -p -r1.11 target.h
--- target.h	5 Mar 2004 03:43:19 -0000	1.11
+++ target.h	3 Mar 2005 16:16:45 -0000
@@ -1,5 +1,5 @@
 /* Target operations for the remote server for GDB.
-   Copyright 2002, 2003, 2004
+   Copyright 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
    Contributed by MontaVista Software.
@@ -31,7 +31,7 @@
 
 struct thread_resume
 {
-  int thread;
+  unsigned long thread;
 
   /* If non-zero, leave this thread stopped.  */
   int leave_stopped;
@@ -61,7 +61,7 @@ struct target_ops
      PID is the process ID to attach to, specified by the user
      or a higher layer.  */
 
-  int (*attach) (int pid);
+  int (*attach) (unsigned long pid);
 
   /* Kill all inferiors.  */
 
@@ -73,7 +73,7 @@ struct target_ops
 
   /* Return 1 iff the thread with process ID PID is alive.  */
 
-  int (*thread_alive) (int pid);
+  int (*thread_alive) (unsigned long pid);
 
   /* Resume the inferior process.  */
 


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