From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15174 invoked by alias); 22 Jan 2013 08:41:00 -0000 Received: (qmail 15153 invoked by uid 22791); 22 Jan 2013 08:40:54 -0000 X-SWARE-Spam-Status: No, hits=-4.4 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,SARE_SUB_OBFU_Q1,TW_CP,TW_XS X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 22 Jan 2013 08:40:48 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1TxZPS-00062k-Mb from Yao_Qi@mentor.com ; Tue, 22 Jan 2013 00:40:46 -0800 Received: from SVR-ORW-FEM-05.mgc.mentorg.com ([147.34.97.43]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Tue, 22 Jan 2013 00:40:46 -0800 Received: from qiyao.dyndns.org (147.34.91.1) by svr-orw-fem-05.mgc.mentorg.com (147.34.97.43) with Microsoft SMTP Server id 14.1.289.1; Tue, 22 Jan 2013 00:40:44 -0800 Message-ID: <50FE5054.5010904@codesourcery.com> Date: Tue, 22 Jan 2013 08:41:00 -0000 From: Yao Qi User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: Eli Zaretskii CC: Subject: Re: [PATCH 2/5] Query supported notifications by qSupported References: <1358838232-13319-1-git-send-email-yao@codesourcery.com> <1358838232-13319-3-git-send-email-yao@codesourcery.com> <83d2wxod0v.fsf@gnu.org> In-Reply-To: <83d2wxod0v.fsf@gnu.org> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2013-01/txt/msg00517.txt.bz2 On 01/22/2013 04:08 PM, Eli Zaretskii wrote: > "by commas", in plural. > Fixed. >> >+@cindex notifications, in remote protocol >> >+The remote stub supports a string of notifications which the remote stub >> >+supports. > Something is wrong with this sentence... How about this? @cindex notifications, in remote protocol The remote stub supports a string of notifications. @var{name} is the name of the notification and @var{annex} is the name of the annex, if the notification has the annex. Below is the updated version with some minor non-doc cleanups. -- Yao (齐尧) gdb/gdbserver: 2013-01-21 Yao Qi * Makefile.in (SFILES): Add "common-notif.c". (OBS): Add common-notif.o. (common-notif.o): New rule. * notif.c (notif_find_annex): New. (notif_qsupported_record): New. (+notif_qsupported_reply): New. * notif.h (notif_qsupported_reply): Declare. (notif_qsupported_record): Declare. * server.c (notif_annex_stop): Update. (handle_query): Call notif_qsupported_record and notif_qsupported_reply. gdb: 2013-01-21 Yao Qi * common/common-notif.c: New. * common/common-notif.h (struct notif_annex) : New field. * Makefile.in (iREMOTE_OBS): Append "common-notif.o". (SFILES): Add "common-notif.c". * remote-notif.c (remote_notif_parse_1): Call the parser of annex if it is supported. (remote_notif_qsupported): New. (remote_notif_qsupported_reply): New. * remote-notif.h (remote_notif_qsupported): Declare. (remote_notif_qsupported_reply): Declare. * remote.c (PACKET_notifications): New enum. (remote_notifications_feature): New. (remote_protocol_features): Add new element. (remote_query_supported): Call remote_notif_qsupported and append supported notifications to qSupported feature. (notif_client_annex_stop): Update. gdb/doc: 2013-01-21 Yao Qi * gdb.texinfo (General Query Packets): Document the new feature 'notifications' of 'qSupported' packet. Document the new feature in qSupported reply. --- gdb/Makefile.in | 9 ++- gdb/common/common-notif.c | 181 +++++++++++++++++++++++++++++++++++++++++++++ gdb/common/common-notif.h | 15 ++++ gdb/doc/gdb.texinfo | 19 +++++ gdb/gdbserver/Makefile.in | 7 +- gdb/gdbserver/notif.c | 21 +++++ gdb/gdbserver/notif.h | 2 + gdb/gdbserver/server.c | 15 ++++- gdb/remote-notif.c | 32 +++++++- gdb/remote-notif.h | 4 + gdb/remote.c | 22 +++++- 11 files changed, 318 insertions(+), 9 deletions(-) create mode 100644 gdb/common/common-notif.c diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 3bd4363..2e22ed0 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -508,7 +508,7 @@ SER_HARDWIRE = @SER_HARDWIRE@ # The `remote' debugging target is supported for most architectures, # but not all (e.g. 960) REMOTE_OBS = remote.o dcache.o tracepoint.o ax-general.o ax-gdb.o remote-fileio.o \ - remote-notif.o + remote-notif.o common-notif.o # This is remote-sim.o if a simulator is to be linked in. SIM_OBS = @SIM_OBS@ @@ -732,7 +732,8 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c printcmd.c \ proc-service.list progspace.c \ prologue-value.c psymtab.c \ - regcache.c reggroups.c remote.c remote-fileio.c remote-notif.c reverse.c \ + regcache.c reggroups.c remote.c remote-fileio.c remote-notif.c \ + common-notif.c reverse.c \ sentinel-frame.c \ serial.c ser-base.c ser-unix.c skip.c \ solib.c solib-target.c source.c \ @@ -1918,6 +1919,10 @@ common-utils.o: ${srcdir}/common/common-utils.c $(COMPILE) $(srcdir)/common/common-utils.c $(POSTCOMPILE) +common-notif.o: ${srcdir}/common/common-notif.c + $(COMPILE) $(srcdir)/common/common-notif.c + $(POSTCOMPILE) + gdb_vecs.o: ${srcdir}/common/gdb_vecs.c $(COMPILE) $(srcdir)/common/gdb_vecs.c $(POSTCOMPILE) diff --git a/gdb/common/common-notif.c b/gdb/common/common-notif.c new file mode 100644 index 0000000..4f23865 --- /dev/null +++ b/gdb/common/common-notif.c @@ -0,0 +1,181 @@ +/* Copyright (C) 2013 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifdef GDBSERVER +#include "server.h" +#else +#include "defs.h" +#endif +#include +#include "common-notif.h" +#include "gdb_assert.h" + +/* Return a string about the notifications in array NOTIFS. NUM is + the number of elements in array NOTIFS. */ + +char * +notif_supported (struct notif_base *notifs[], int num) +{ + int i; + char * p = NULL; + +#define BUF_LEN 128 + + for (i = 0; i < num; i++) + { + struct notif_base *nb = notifs[i]; + + if (p == NULL) + { + p = xmalloc (BUF_LEN); + strcpy (p, nb->notif_name); + } + else + xsnprintf (p + strlen (p), BUF_LEN - strlen (p), ",%s", + nb->notif_name); + + if (NOTIF_HAS_ANNEX (nb)) + { + int j; + + NOTIF_ITER_ANNEX (nb, j) + { + xsnprintf (p + strlen (p), BUF_LEN - strlen (p), + ".%s", nb->annexes[j].name); + } + } + } + + return p; +} + +/* Find annex in notification NB by name NAME and length LEN. + If found, return annex, otherwise return NULL. */ + +static struct notif_annex * +remote_notif_find_annex (struct notif_base *nb, + const char *name, int len) +{ + if (NOTIF_HAS_ANNEX (nb)) + { + int j; + + NOTIF_ITER_ANNEX (nb, j) + if (strncmp (name, nb->annexes[j].name, len) == 0 + && len == strlen (nb->annexes[j].name)) + return &nb->annexes[j]; + } + return NULL; +} + +/* Parse the REPLY, which is about supported annexes and + notifications in peer, and disable some annexes + if the remote stub doesn't support. */ + +void +notif_parse_supported (const char *reply, + struct notif_base *notifs[], int num) +{ + const char *p = reply; + int notif_num = 1; + char **notif_str; + int i; + + for (i = 0; reply[i] != '\0'; i++) + if (reply[i] == ',') + notif_num++; + + notif_str = xmalloc (notif_num * sizeof (char *)); + for (i = 0; i < notif_num; i++) + { + char *end = strchr (p, ','); + + if (end == NULL) + notif_str[i] = xstrdup (p); + else + { + /* Can't use xstrndup in GDBserver. */ + notif_str[i] = strndup (p, end - p); + p = end + 1; + } + } + + for (i = 0; i < notif_num; i++) + { + int j; + struct notif_base *nb = NULL; + + p = notif_str[i]; + + for (j = 0; j < num; j++) + { + int name_len = strlen (notifs[j]->notif_name); + + if (0 == strncmp (notifs[j]->notif_name, p, name_len) + && (p[name_len] == '.' || p[name_len] == 0)) + { + nb = notifs[j]; + p += name_len; + break; + } + } + + if (nb != NULL) + { + if (p[0] == 0) + { + /* No annex. */ + gdb_assert (!NOTIF_HAS_ANNEX (nb)); + nb->annexes[0].supported = 1; + } + else if (p[0] == '.') + { + gdb_assert (NOTIF_HAS_ANNEX (nb)); + + p++; + + /* Parse the rest of P and look for annexes. */ + while (p != NULL) + { + char *end = strchr (p, '.'); + struct notif_annex *annex = NULL; + + if (end != NULL) + { + annex = remote_notif_find_annex (nb, p, + end - p); + p = end + 1; + } + else + { + annex = remote_notif_find_annex (nb, p, + strlen (p)); + p = end; + } + + /* If annex is known, mark it supported, otherwise + skip it because the peer knows the annex but we + don't know. */ + if (annex != NULL) + annex->supported = 1; + } + } + else + warning (_("Unknown supported notification")); + } + } +} diff --git a/gdb/common/common-notif.h b/gdb/common/common-notif.h index 1ffa26c..8e0e0c1 100644 --- a/gdb/common/common-notif.h +++ b/gdb/common/common-notif.h @@ -32,6 +32,11 @@ struct notif_annex notification this annex belongs to. */ const char *name; + /* This annex is supported by the peer (GDB or GDBserver)? A + notification may have multiple annexes and some of them are + supported. Annex is the smallest unit of support. */ + int supported; + #ifdef GDBSERVER /* Write event EVENT to OWN_BUF. */ void (*write) (struct notif_event *event, char *own_buf); @@ -53,6 +58,10 @@ struct notif_annex #define NOTIF_HAS_ANNEX(NOTIF) ((NOTIF)->annexes[0].name != NULL) +/* Whether the annex of notification N is supported. */ + +#define NOTIF_ANNEX_SUPPORTED_P(N, INDEX) \ + ((N).annexes[INDEX].supported) /* "Base class" of a notification. It can be extended in both GDB and GDBserver to represent a type of notification. */ @@ -71,3 +80,9 @@ struct notif_base of the notification. */ struct notif_annex *annexes; }; + +char *notif_supported (struct notif_base *notifs[], int num); + +void notif_parse_supported (const char *reply, + struct notif_base *notifs[], int num); + diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 8f08e82..0c25772 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -37113,6 +37113,14 @@ description. This feature indicates whether @value{GDBN} supports the @samp{qRelocInsn} packet (@pxref{Tracepoint Packets,,Relocate instruction reply packet}). + +@item notifications +@anchor{notifications feature} +This feature indicates that @value{GDBN} supports the async remote +notifications (@pxref{Notification Packets}). If the stub sees +@samp{notifications=} with a string of supported notifications, +separated by commas, it will report notifications supported by the +stub. @end table Stubs should ignore any unknown values for @@ -37301,6 +37309,11 @@ These are the currently defined stub features and their properties: @tab @samp{-} @tab No +@item @samp{Notifications} +@tab Yes +@tab @samp{-} +@tab No + @end multitable These are the currently defined stub features, in more detail: @@ -37455,6 +37468,12 @@ See @ref{Bytecode Descriptions} for details about the bytecode. The remote stub supports running a breakpoint's command list itself, rather than reporting the hit to @value{GDBN}. +@item Notifications=@var{name}@r{[}.@var{annex}@r{]}@dots{}@r{[},@var{name}@r{[}.@var{annex}@r{]}@dots{}@r{]}@dots{} +@cindex notifications, in remote protocol +The remote stub supports a string of notifications. @var{name} is +the name of the notification and @var{annex} is the name of the annex, +if the notification has the annex. + @end table @item qSymbol:: diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index f8b1794..8533e54 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -155,7 +155,7 @@ SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \ $(srcdir)/common/vec.c $(srcdir)/common/gdb_vecs.c \ $(srcdir)/common/common-utils.c $(srcdir)/common/xml-utils.c \ $(srcdir)/common/linux-osdata.c $(srcdir)/common/ptid.c \ - $(srcdir)/common/buffer.c + $(srcdir)/common/buffer.c $(srcdir)/common/common-notif.c DEPFILES = @GDBSERVER_DEPFILES@ @@ -165,7 +165,7 @@ SOURCES = $(SFILES) TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS} OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o target.o \ - utils.o version.o vec.o gdb_vecs.o \ + utils.o version.o vec.o gdb_vecs.o common-notif.o \ mem-break.o hostio.o event-loop.o tracepoint.o \ xml-utils.o common-utils.o ptid.o buffer.o format.o \ dll.o notif.o \ @@ -517,6 +517,9 @@ linux-ptrace.o: ../common/linux-ptrace.c common-utils.o: ../common/common-utils.c $(COMPILE) $< $(POSTCOMPILE) +common-notif.o: ../common/common-notif.c + $(COMPILE) $< + $(POSTCOMPILE) vec.o: ../common/vec.c $(COMPILE) $< $(POSTCOMPILE) diff --git a/gdb/gdbserver/notif.c b/gdb/gdbserver/notif.c index 168f77d..e6b3756 100644 --- a/gdb/gdbserver/notif.c +++ b/gdb/gdbserver/notif.c @@ -182,6 +182,27 @@ notif_event_xfree (struct notif_event *event) xfree (event); } +/* Record the notifications supported by GDB. GDB_NOTIFICATIONS is a + string about notifications GDB supports. */ + +void +notif_qsupported_record (char *gdb_notifications) +{ + return notif_parse_supported (gdb_notifications, + (struct notif_base **) notifs, + ARRAY_SIZE (notifs)); +} + +/* Return a string about notifications that GDBserver supports. + Return NULL if no notification is supported. */ + +char * +notif_qsupported_reply (void) +{ + return notif_supported ((struct notif_base **) notifs, + ARRAY_SIZE (notifs)); +} + void initialize_notif (void) { diff --git a/gdb/gdbserver/notif.h b/gdb/gdbserver/notif.h index 5f9b6bc..72417aa 100644 --- a/gdb/gdbserver/notif.h +++ b/gdb/gdbserver/notif.h @@ -58,6 +58,8 @@ extern struct notif_server notif_stop; int handle_notif_ack (char *own_buf, int packet_len); void notif_write_event (struct notif_server *notif, char *own_buf); +char* notif_qsupported_reply (void); +void notif_qsupported_record (char *gdb_notifications); void notif_push (struct notif_server *np, struct notif_event *event); void notif_event_enque (struct notif_server *notif, diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index f98a780..61f08bd 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -185,7 +185,7 @@ vstop_notif_reply (struct notif_event *event, char *own_buf) static struct notif_annex notif_annex_stop[] = { - { NULL, vstop_notif_reply, }, + { NULL, 1, vstop_notif_reply, }, }; struct notif_server notif_stop = @@ -1578,6 +1578,11 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) /* GDB supports relocate instruction requests. */ gdb_supports.qRelocInsn = 1; } + else if (strncmp (p, "notifications=", 14) == 0) + { + /* Record what notifications GDB supports. */ + notif_qsupported_record (&p[14]); + } else target_process_qsupported (p); @@ -1659,6 +1664,14 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p) if (target_supports_agent ()) strcat (own_buf, ";QAgent+"); + p = notif_qsupported_reply (); + + if (p != NULL) + { + strcat (own_buf, ";Notifications="); + strcat (own_buf, p); + xfree (p); + } return; } diff --git a/gdb/remote-notif.c b/gdb/remote-notif.c index e0bc745..ae05bbf 100644 --- a/gdb/remote-notif.c +++ b/gdb/remote-notif.c @@ -75,9 +75,16 @@ remote_notif_parse_1 (struct notif_client *nc, contents in BUF. */ && buf[strlen (m->name)] == ':') { - /* Pass BUF without annex and ':'. */ - m->parse (nc, buf + strlen (m->name) + 1, event); - break; + if (m->supported) + { + /* Pass BUF without annex and ':'. */ + m->parse (nc, buf + strlen (m->name) + 1, event); + break; + } + else + warning (_("GDB gets annex '%s' of notification '%s'" + "but remote stub doesn't support"), + base->notif_name, m->name); } m = NULL; } @@ -305,6 +312,25 @@ notif_xfree (struct notif_client *notif) xfree (notif); } +/* Return a string of GDB supported features. */ + +char * +remote_notif_qsupported (void) +{ + return notif_supported ((struct notif_base **) notifs, + ARRAY_SIZE (notifs)); +} + +/* Parse the qSupported reply REPLY from the remote stub and disable + some notifications if the remote stub doesn't support. */ + +void +remote_notif_qsupported_reply (const char *reply) +{ + notif_parse_supported (reply, (struct notif_base **) notifs, + ARRAY_SIZE (notifs)); +} + /* -Wmissing-prototypes */ extern initialize_file_ftype _initialize_notif; diff --git a/gdb/remote-notif.h b/gdb/remote-notif.h index cb1636f..4859254 100644 --- a/gdb/remote-notif.h +++ b/gdb/remote-notif.h @@ -69,6 +69,10 @@ void remote_notif_register_async_event_handler (void); void remote_notif_unregister_async_event_handler (void); void remote_notif_process (struct notif_client *except); + +char * remote_notif_qsupported (void); +void remote_notif_qsupported_reply (const char *reply); + extern struct notif_client notif_client_stop; extern unsigned int notif_debug; diff --git a/gdb/remote.c b/gdb/remote.c index 92a0f27..e20ac80 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -1284,6 +1284,7 @@ enum { PACKET_qXfer_fdpic, PACKET_QDisableRandomization, PACKET_QAgent, + PACKET_notifications, PACKET_MAX }; @@ -3873,6 +3874,15 @@ remote_string_tracing_feature (const struct protocol_feature *feature, rs->string_tracing = (support == PACKET_ENABLE); } +static void +remote_notifications_feature (const struct protocol_feature *feature, + enum packet_support support, + const char *value) +{ + if (support == PACKET_ENABLE) + remote_notif_qsupported_reply (value); +} + static struct protocol_feature remote_protocol_features[] = { { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 }, { "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet, @@ -3938,6 +3948,8 @@ static struct protocol_feature remote_protocol_features[] = { { "QDisableRandomization", PACKET_DISABLE, remote_supported_packet, PACKET_QDisableRandomization }, { "QAgent", PACKET_DISABLE, remote_supported_packet, PACKET_QAgent}, + { "Notifications", PACKET_DISABLE, remote_notifications_feature, + -1 }, { "tracenz", PACKET_DISABLE, remote_string_tracing_feature, -1 }, }; @@ -4004,6 +4016,7 @@ remote_query_supported (void) if (remote_protocol_packets[PACKET_qSupported].support != PACKET_DISABLE) { char *q = NULL; + char *notifications = remote_notif_qsupported (); struct cleanup *old_chain = make_cleanup (free_current_contents, &q); q = remote_query_supported_append (q, "multiprocess+"); @@ -4013,6 +4026,10 @@ remote_query_supported (void) q = remote_query_supported_append (q, "qRelocInsn+"); + q = reconcat (q, q, ";notifications=", notifications, + (char *) NULL); + xfree (notifications); + q = reconcat (q, "qSupported:", q, (char *) NULL); putpkt (q); @@ -5211,7 +5228,10 @@ remote_notif_stop_alloc_reply (void) static struct notif_annex notif_client_annex_stop[] = { - { NULL, remote_notif_stop_parse, }, + /* Even the remote stub doesn't understand + 'qSupported:notifications=', it may still support notification + stop if it supports non-stop. */ + { NULL, 1, remote_notif_stop_parse, }, }; /* A client of notification Stop. */ -- 1.7.7.6