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]

[RFC] Extend remote protocol to allow symbol look-up service.


 
Surprising as  it may seem, there are circumstances when a remote
target stub may need to know the values of symbols in the debuggee.
The case that I'm working from is multi-threaded debugging under
Solaris and Linux.  Both platforms make use of a debugging support
library called libthread-db, which exports a debugging interface
into the native thread library.  It shields the debugger from 
knowledge about the thread library internals, but in return it 
needs to know the addresses of thread library data objects in the
child, so that it can go rooting around in them.

The scheme that I propose is this: whenever the debugger detects
a new shared library being loaded in the remote child process, 
it will send a notification to the remote stub in the form of
a 'Q' (miscelaneous set value) packet, like this:

	QSharedObject:libc.so.1

The target may as usual reply with an empty packet meaning
"I don't understand", or with an "OK" acknowledgement, but
in addition to those the target may reply with a request
for the value of a symbol:

	qSymbol:__pthread_max_threads

If the reply is of that form, the debugger will attempt a 
symbol lookup.  If successful, it will send a new declaratory
message to the target like so:

	QSymbol:<hex address>:__pthread_max_threads

Or, if the lookup is unsuccessful, 

	QSymbol::__pthread_max_threads

(indicating no address or value is available).  The target may
ask for the symbol again when a new shared library shows up.

The target's replies to the QSymbol message are the same as for
the QSharedObject message: an empty reply, an "OK" ack, or a
new request for another symbol.  Thus the process can continue
until the target doesn't need any more symbols.

Here is a patch to remote.c that would implement the debugger side
of the proposed protocol.  I have implemented the target side in
the soon-to-be-released (knock on wood) libremote library.

2001-04-17  Michael Snyder  <msnyder@redhat.com>

	* remote.c (remote_new_objfile): New function.  Called by the
	target new_objfile hook whenever a new (shared library) objfile
	is detected.  Notifies the remote target, and accepts symbol
	lookup requests.
	(remote_new_objfile_chain): Function pointer which hooks 
	remote_new_objfile into the new objfile notification chain.
	(_initialize_remote): Hook remote_new_objfile function into 
	the new objfile notification chain.

Index: remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.45
diff -c -3 -p -r1.45 remote.c
*** remote.c	2001/04/17 20:31:00	1.45
--- remote.c	2001/04/17 23:13:03
*************** build_remote_gdbarch_data (void)
*** 5691,5696 ****
--- 5691,5751 ----
    remote_address_size = TARGET_ADDR_BIT;
  }
  
+ /* Saved pointer to previous owner of the new_objfile event. */
+ static void (*remote_new_objfile_chain) (struct objfile *);
+ 
+ /* Function to be called whenever a new objfile (shlib) is detected. */
+ static void
+ remote_new_objfile (struct objfile *objfile)
+ {
+   char *msg, *reply, *prev, *tmp;
+   struct minimal_symbol *sym;
+ 
+   printf ("<remote_new_objfile: %08x>\n", (unsigned long) objfile);
+ 
+   if (remote_desc != 0)		/* Have a remote connection */
+     {
+       msg   = alloca (PBUFSIZ);
+       reply = alloca (PBUFSIZ);
+ 
+       /* Inform target of new objfile. */
+ 
+       /* NOTE: you might say that I should use SLASH_CHAR here, but
+ 	 not so!  SLASH_CHAR is defined for the host, while the shared
+ 	 libraries are relevant to the target. */
+       if (objfile)
+ 	{
+ 	  tmp = strrchr (objfile->name, '/');
+ 	  if (tmp == NULL)
+ 	    tmp = strrchr (objfile->name, '\\');
+ 	  if (tmp == NULL)
+ 	    tmp = objfile->name;
+ 	  sprintf (msg, "QSharedObject:%s", tmp);
+ 	}
+       else
+ 	strcpy (msg, "QSharedObject:");
+ 
+       putpkt (msg);
+       getpkt (reply, PBUFSIZ, 0);
+       while (strncmp (reply, "qSymbol:", 8) == 0)
+ 	{
+ 	  sym = lookup_minimal_symbol (&reply[8], NULL, NULL);
+ 	  if (sym == NULL)
+ 	    sprintf (msg, "QSymbol::%s", &reply[8]);
+ 	  else
+ 	    sprintf (msg, "QSymbol:%s:%s", 
+ 		     paddr_nz (SYMBOL_VALUE_ADDRESS (sym)),
+ 		     &reply[8]);
+ 	  putpkt (msg);
+ 	  getpkt (reply, PBUFSIZ, 0);
+ 	}
+     }
+   /* Call predecessor on chain, if any. */
+   if (remote_new_objfile_chain != 0 &&
+       remote_desc == 0)
+     remote_new_objfile_chain (objfile);
+ }
+ 
  void
  _initialize_remote (void)
  {
*************** _initialize_remote (void)
*** 5720,5725 ****
--- 5775,5784 ----
  
    init_remote_cisco_ops ();
    add_target (&remote_cisco_ops);
+ 
+   /* Hook into new objfile notification.  */
+   remote_new_objfile_chain = target_new_objfile_hook;
+   target_new_objfile_hook  = remote_new_objfile;
  
  #if 0
    init_remote_threadtests ();

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