This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[gdbserver] avoid nested strtok calls in handling of qSupported
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 1 Jun 2010 13:54:20 +0100
- Subject: [gdbserver] avoid nested strtok calls in handling of qSupported
target_process_qsupported may, (and does so on linux x86, ) call
strtok to split the xmlRegisters=foo,bar feature string. Nesting
strtok (str,...) calls is a no-no, since the inner strtok messes
up the global state of the outer call.
(This happened to go unnoticed because gdb was sending
multiprocess+;xmlRegisters=... in that order. I noticed the breakage
since gdb is now sending "multiprocess+;xmlRegisters=...;qRelocInsn+"
and the outer strtok was failing to see the qRelocInsn+ token.)
Applied.
--
Pedro Alves
2010-06-01 Pedro Alves <pedro@codesourcery.com>
* server.c (handle_query) <qSupported>: Do two passes over the
qSupported string to avoid nesting strtok.
---
gdb/gdbserver/server.c | 48 ++++++++++++++++++++++++++++++++++--------------
1 file changed, 34 insertions(+), 14 deletions(-)
Index: src/gdb/gdbserver/server.c
===================================================================
--- src.orig/gdb/gdbserver/server.c 2010-06-01 12:55:52.000000000 +0100
+++ src/gdb/gdbserver/server.c 2010-06-01 13:41:39.000000000 +0100
@@ -1346,20 +1346,40 @@ handle_query (char *own_buf, int packet_
feature will follow a ':', and latter features will follow
';'. */
if (*p == ':')
- for (p = strtok (p + 1, ";");
- p != NULL;
- p = strtok (NULL, ";"))
- {
- if (strcmp (p, "multiprocess+") == 0)
- {
- /* GDB supports and wants multi-process support if
- possible. */
- if (target_supports_multi_process ())
- multi_process = 1;
- }
- else
- target_process_qsupported (p);
- }
+ {
+ char **qsupported = NULL;
+ int count = 0;
+ int i;
+
+ /* Two passes, to avoid nested strtok calls in
+ target_process_qsupported. */
+ for (p = strtok (p + 1, ";");
+ p != NULL;
+ p = strtok (NULL, ";"))
+ {
+ count++;
+ qsupported = xrealloc (qsupported, count * sizeof (char *));
+ qsupported[count - 1] = xstrdup (p);
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ p = qsupported[i];
+ if (strcmp (p, "multiprocess+") == 0)
+ {
+ /* GDB supports and wants multi-process support if
+ possible. */
+ if (target_supports_multi_process ())
+ multi_process = 1;
+ }
+ else
+ target_process_qsupported (p);
+
+ free (p);
+ }
+
+ free (qsupported);
+ }
sprintf (own_buf, "PacketSize=%x;QPassSignals+", PBUFSIZ - 1);