This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFC] Extend remote protocol to allow symbol look-up service.
- To: gdb-patches at sources dot redhat dot com
- Subject: [RFC] Extend remote protocol to allow symbol look-up service.
- From: Michael Snyder <msnyder at cygnus dot com>
- Date: Tue, 17 Apr 2001 16:28:56 -0700
- CC: jtc at redback dot com
- Organization: Red Hat
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 ();