From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31473 invoked by alias); 7 Aug 2012 07:10:09 -0000 Received: (qmail 31458 invoked by uid 22791); 7 Aug 2012 07:10:07 -0000 X-SWARE-Spam-Status: No, hits=-3.5 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,TW_BJ 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, 07 Aug 2012 07:09:53 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1SydvM-0005wY-Fr from Hui_Zhu@mentor.com for gdb-patches@sourceware.org; Tue, 07 Aug 2012 00:09:52 -0700 Received: from SVR-ORW-FEM-02.mgc.mentorg.com ([147.34.96.206]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Tue, 7 Aug 2012 00:09:52 -0700 Received: from [127.0.0.1] (147.34.91.1) by svr-orw-fem-02.mgc.mentorg.com (147.34.96.168) with Microsoft SMTP Server id 14.1.289.1; Tue, 7 Aug 2012 00:09:49 -0700 Message-ID: <5020BF3A.8030809@mentor.com> Date: Tue, 07 Aug 2012 07:10:00 -0000 From: Hui Zhu User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120724 Thunderbird/15.0 MIME-Version: 1.0 To: Subject: [RFC] Autoload-breakpoints new version [3/9] notification async Content-Type: multipart/mixed; boundary="------------060009060809080800000100" 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: 2012-08/txt/msg00214.txt.bz2 --------------060009060809080800000100 Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1009 This patch is the extend for the notification function. Current notification function cannot handle the packet when GDB doesn't want to send or receive packet from the remote target. This patch do the extend make GDB can handle the notification even if it doesn't send or receive packet. Thanks, Hui 2012-08-07 Hui Zhu * remote.c (async_client_callback): Move to the top. (async_client_context): Ditto. (remote_async_serial_handler): Ditto. (PACKET_NotificationAsync): New enum. (remote_pr): Add PACKET_NotificationAsync. (remote_open_1): Call serial_async if need. (readchar_buffer_ch): New variable. (readchar): If need, return the value of readchar_buffer_ch. (readchar_buffer_put): New function. (remote_is_async_p): Add check for PACKET_ReportAsync. (remote_notificationasync_check): New function. (remote_async_serial_handler): Add code to handle notification. (remote_async): Add check for PACKET_ReportAsync. (_initialize_remote): Add PACKET_NotificationAsync. --------------060009060809080800000100 Content-Type: text/plain; charset="us-ascii"; name="notification_async.txt" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="notification_async.txt" Content-length: 5917 --- remote.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 98 insertions(+), 10 deletions(-) --- a/remote.c +++ b/remote.c @@ -224,6 +224,11 @@ static void remote_query_supported (void static void remote_check_symbols (struct objfile *objfile); +static void (*async_client_callback) (enum inferior_event_type event_type, + void *context); +static void *async_client_context; +static serial_event_ftype remote_async_serial_handler; + void _initialize_remote (void); struct stop_reply; @@ -1297,6 +1302,7 @@ enum { PACKET_QDisableRandomization, PACKET_QAgent, PACKET_AutoloadBreakpoints, + PACKET_NotificationAsync, PACKET_MAX }; @@ -3998,6 +4004,8 @@ static struct protocol_feature remote_pr remote_string_tracing_feature, -1 }, { "AutoloadBreakpoints", PACKET_DISABLE, remote_supported_packet, PACKET_AutoloadBreakpoints }, + { "NotificationAsync", PACKET_DISABLE, remote_supported_packet, + PACKET_NotificationAsync }, }; static char *remote_support_xml; @@ -4355,6 +4363,10 @@ remote_open_1 (char *name, int from_tty, if (target_async_permitted) wait_forever_enabled_p = 1; + + if (remote_protocol_packets[PACKET_NotificationAsync].support + != PACKET_DISABLE) + serial_async (remote_desc, remote_async_serial_handler, NULL); } /* This takes a program previously attached to and detaches it. After @@ -6980,11 +6992,20 @@ remote_files_info (struct target_ops *ig /* Read a single character from the remote end. */ +static int readchar_buffer_ch = -1; + static int readchar (int timeout) { int ch; + if (readchar_buffer_ch != -1) + { + ch = readchar_buffer_ch; + readchar_buffer_ch = -1; + return ch; + } + ch = serial_readchar (remote_desc, timeout); if (ch >= 0) @@ -7007,6 +7028,17 @@ readchar (int timeout) return ch; } +/* When the function that call the readchar got a char is not for it + and other function need this char,call this function to put + this char back. Then when other function call readchar, it will + got this char first. */ + +static void +readchar_buffer_put (int ch) +{ + readchar_buffer_ch = ch; +} + /* Send the command in *BUF to the remote machine, and read the reply into *BUF. Report an error if we get an error reply. Resize *BUF using xrealloc if necessary to hold the result, and update @@ -11207,25 +11239,71 @@ remote_is_async_p (void) /* We only enable async when the user specifically asks for it. */ return 0; + if (remote_protocol_packets[PACKET_NotificationAsync].support + != PACKET_DISABLE) + return async_client_callback != NULL; + /* We're async whenever the serial device is. */ return serial_is_async_p (remote_desc); } +static int +remote_notificationasync_check (void) +{ + int c = readchar (-1); + + if (c == '%') + return 1; + + readchar_buffer_put (c); + return 0; +} + /* Pass the SERIAL event on and up to the client. One day this code will be able to delay notifying the client of an event until the point where an entire packet has been received. */ -static void (*async_client_callback) (enum inferior_event_type event_type, - void *context); -static void *async_client_context; -static serial_event_ftype remote_async_serial_handler; - static void remote_async_serial_handler (struct serial *scb, void *context) { - /* Don't propogate error information up to the client. Instead let - the client find out about the error by querying the target. */ - async_client_callback (INF_REG_EVENT, async_client_context); + /* Check if this is ReportAsync. */ + if (remote_notificationasync_check ()) + { + int val; + struct remote_state *rs = get_remote_state (); + + val = read_frame (&rs->buf, &rs->buf_size); + if (val >= 0) + { + if (remote_debug) + { + struct cleanup *old_chain; + char *str; + + str = escape_buffer (rs->buf, val); + old_chain = make_cleanup (xfree, str); + fprintf_unfiltered (gdb_stdlog, " Notification received: %s\n", + str); + do_cleanups (old_chain); + } + handle_notification (rs->buf, val); + } + else + { + if (remote_debug) + { + fprintf_unfiltered (gdb_stdlog, "putpkt: Junk: "); + fprintf_unfiltered (gdb_stdlog, "%%%s", rs->buf); + } + } + } + else + { + /* Don't propogate error information up to the client. Instead let + the client find out about the error by querying the target. */ + if (async_client_callback) + async_client_callback (INF_REG_EVENT, async_client_context); + } } static void @@ -11246,12 +11324,19 @@ remote_async (void (*callback) (enum inf { if (callback != NULL) { - serial_async (remote_desc, remote_async_serial_handler, NULL); + if (remote_protocol_packets[PACKET_NotificationAsync].support + == PACKET_DISABLE) + serial_async (remote_desc, remote_async_serial_handler, NULL); async_client_callback = callback; async_client_context = context; } else - serial_async (remote_desc, NULL, NULL); + { + if (remote_protocol_packets[PACKET_NotificationAsync].support + == PACKET_DISABLE) + serial_async (remote_desc, NULL, NULL); + async_client_callback = NULL; + } } static void @@ -11769,6 +11854,9 @@ Show the maximum size of the address (in add_packet_config_cmd (&remote_protocol_packets[PACKET_AutoloadBreakpoints], "AutoloadBreakpoints", "autoload-breakpoints", 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_NotificationAsync], + "NotificationAsync", "notification-async", 0); + /* Keep the old ``set remote Z-packet ...'' working. Each individual Z sub-packet has its own set and show commands, but users may have sets to this variable in their .gdbinit files (or in their --------------060009060809080800000100--