[PATCH v2] Add autoload-breakpoints [2/6] ReportAsync-test
Hui Zhu
hui_zhu@mentor.com
Sat Apr 28 07:15:00 GMT 2012
On 04/11/12 18:53, Hui Zhu wrote:
> Hi,
>
> Because make gdbsever support this control autoload-breakpoints is not very useful for it. So I add a special gdb stub the help test. It can send send ReportAsync in anytime.
>
> Thanks,
> Hui
>
> 2012-04-11 Hui Zhu <hui_zhu@mentor.com>
>
> * Makefile.in (ALL_SUBDIRS): Add gdb.remote.
> * configure (ac_config_files): Add gdb.remote/Makefile.
> * configure.ac (AC_OUTPUT): Ditto.
> * gdb.remote/Makefile.in: New file.
> * gdb.remote/reportasync-test.c: New file.
> * gdb.remote/reportasync-test.exp: New file.
>
The patch update follow the cvs-trunk.
Thanks,
Hui
2012-04-28 Hui Zhu <hui_zhu@mentor.com>
* Makefile.in (ALL_SUBDIRS): Add gdb.remote.
* configure (ac_config_files): Add gdb.remote/Makefile.
* configure.ac (AC_OUTPUT): Ditto.
* gdb.remote/Makefile.in: New file.
* gdb.remote/reportasync-test.c: New file.
* gdb.remote/reportasync-test.exp: New file.
-------------- next part --------------
---
testsuite/Makefile.in | 2
testsuite/configure | 3
testsuite/configure.ac | 2
testsuite/gdb.remote/Makefile.in | 17 +
testsuite/gdb.remote/reportasync-test.c | 371 ++++++++++++++++++++++++++++++
testsuite/gdb.remote/reportasync-test.exp | 80 ++++++
6 files changed, 472 insertions(+), 3 deletions(-)
--- a/testsuite/Makefile.in
+++ b/testsuite/Makefile.in
@@ -37,7 +37,7 @@ ALL_SUBDIRS = gdb.ada gdb.arch gdb.asm g
gdb.dwarf2 gdb.fortran gdb.gdb gdb.hp \
gdb.java gdb.linespec gdb.mi gdb.modula2 gdb.multi \
gdb.objc gdb.opencl gdb.opt gdb.pascal gdb.python gdb.server \
- gdb.stabs gdb.reverse gdb.threads gdb.trace gdb.xml \
+ gdb.stabs gdb.reverse gdb.threads gdb.trace gdb.xml gdb.remote \
$(SUBDIRS)
EXPECT = `if [ -f $${rootme}/../../expect/expect ] ; then \
--- a/testsuite/configure
+++ b/testsuite/configure
@@ -3448,7 +3448,7 @@ done
-ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.fortran/Makefile gdb.go/Makefile gdb.server/Makefile gdb.java/Makefile gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile gdb.hp/gdb.defects/Makefile gdb.linespec/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile"
+ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.fortran/Makefile gdb.go/Makefile gdb.server/Makefile gdb.java/Makefile gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile gdb.hp/gdb.defects/Makefile gdb.linespec/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile gdb.remote/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -4181,6 +4181,7 @@ do
"gdb.threads/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.threads/Makefile" ;;
"gdb.trace/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.trace/Makefile" ;;
"gdb.xml/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.xml/Makefile" ;;
+ "gdb.remote/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.remote/Makefile" ;;
*) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
--- a/testsuite/configure.ac
+++ b/testsuite/configure.ac
@@ -98,4 +98,4 @@ AC_OUTPUT([Makefile \
gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile \
gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile \
gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile \
- gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile])
+ gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile gdb.remote/Makefile])
--- /dev/null
+++ b/testsuite/gdb.remote/Makefile.in
@@ -0,0 +1,17 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = reportasync-test
+
+MISCELLANEOUS =
+
+all info install-info dvi install uninstall installcheck check:
+ @echo "Nothing to be done for $@..."
+
+clean mostlyclean:
+ rm -f *~ *.o *.x *.ci *.sl a.out core
+ rm -f $(EXECUTABLES) $(MISCELLANEOUS)
+
+distclean maintainer-clean realclean: clean
+ rm -f Makefile config.status config.log site.* gdb.log gdb.sum
+
--- /dev/null
+++ b/testsuite/gdb.remote/reportasync-test.c
@@ -0,0 +1,371 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2012 Free Software Foundation, Inc.
+
+ 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 <http://www.gnu.org/licenses/>. */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+int listen_desc = -1;
+int remote_desc = -1;
+int loop_test_begin = 0;
+int got_pkg = 0;
+int inside_send_reportasync_pkg = 0;
+
+#define INT2CHAR(h) ((h) > 9 ? (h) + 'a' - 10 : (h) + '0')
+
+int
+hex2int(unsigned char hex, int *i)
+{
+ if ((hex >= '0') && (hex <= '9'))
+ {
+ *i = hex - '0';
+ return 1;
+ }
+ if ((hex >= 'a') && (hex <= 'f'))
+ {
+ *i = hex - 'a' + 10;
+ return 1;
+ }
+ if ((hex >= 'A') && (hex <= 'F'))
+ {
+ *i = hex - 'A' + 10;
+ return 1;
+ }
+
+ return 0;
+}
+
+int readchar_buffer_ch = -1;
+
+int
+readchar (void)
+{
+ int ret;
+ unsigned char ch;
+
+ if (readchar_buffer_ch != -1)
+ {
+ ch = readchar_buffer_ch;
+ readchar_buffer_ch = -1;
+ return ch;
+ }
+
+ if (remote_desc < 0)
+ {
+ printf ("Remote socket is closed.\n");
+ exit (-1);
+ }
+
+ ret = read(remote_desc, &ch, 1);
+ if (ret == 0)
+ {
+ printf ("Remote socket is closed.\n");
+ close (remote_desc);
+ remote_desc = -1;
+ return -1;
+ }
+ else if (ret < 0)
+ {
+ perror ("Read got error");
+ exit (-errno);
+ }
+
+ return (int) ch;
+}
+
+void
+readchar_buffer_put (int ch)
+{
+ readchar_buffer_ch = ch;
+}
+
+void
+accept_remote (void)
+{
+ struct sockaddr_in sockaddr;
+ socklen_t tmp;
+
+ tmp = sizeof (sockaddr);
+ remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &tmp);
+ if (remote_desc == -1)
+ perror ("Accept failed");
+
+ /* Enable TCP keep alive process. */
+ tmp = 1;
+ setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE,
+ (char *) &tmp, sizeof (tmp));
+
+ /* Tell TCP not to delay small packets. This greatly speeds up
+ interactive response. */
+ tmp = 1;
+ setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
+ (char *) &tmp, sizeof (tmp));
+}
+
+int
+read_rsppkg(unsigned char *buf, int max_size)
+{
+ int len = 0;
+ unsigned char *bufw = NULL;
+ unsigned char csum = 0;
+
+ while (1)
+ {
+ int ch = readchar();
+ if (ch < 0)
+ return -1;
+
+ switch (ch)
+ {
+ case '$':
+ bufw = buf;
+ len = 0;
+ csum = 0;
+ if (!inside_send_reportasync_pkg)
+ {
+ if (loop_test_begin)
+ write (remote_desc, "^" , 1);
+ got_pkg = 1;
+ }
+ break;
+
+ case '#':
+ if (bufw)
+ {
+ int c1, c2;
+
+ c1 = readchar();
+ if (c1 < 0)
+ return -1;
+ c2 = readchar();
+ if (c2 < 0)
+ return -1;
+ if (!hex2int (c1, &c1) || !hex2int (c2, &c2)
+ || csum != (c1 << 4) + c2)
+ write (remote_desc, "-" , 1);
+ else
+ {
+ write (remote_desc, "+" , 1);
+ bufw[0] = '\0';
+ return 0;
+ }
+ }
+ break;
+
+ default:
+ if (bufw)
+ {
+ if (len >= max_size)
+ {
+ printf ("The GDB rsp package is too big.\n");
+ exit (-1);
+ }
+
+ bufw[0] = (unsigned char) ch;
+ csum += bufw[0];
+ len ++;
+ bufw ++;
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+
+void
+write_rsppkg (unsigned char *buf)
+{
+ int buf_size;
+ char *send_buf;
+ unsigned char csum = 0;
+ int i;
+
+ buf_size = strlen (buf);
+ send_buf = alloca(buf_size + 4);
+
+ send_buf[0] = '$';
+
+ memcpy(send_buf + 1, buf, buf_size);
+
+ for (i = 0; i < buf_size; i ++)
+ csum += buf[i];
+
+ send_buf[buf_size + 1] = '#';
+ send_buf[buf_size + 2] = INT2CHAR(csum >> 4);
+ send_buf[buf_size + 3] = INT2CHAR(csum & 0x0f);
+
+ if (write (remote_desc, send_buf, buf_size + 4) != buf_size + 4)
+ {
+ perror ("Write got error");
+ exit (-errno);
+ }
+}
+
+int
+shake_hands (void)
+{
+ int ch;
+
+ write (remote_desc, "^" , 1);
+ ch = readchar();
+ if (ch != '^')
+ {
+ if (ch > 0)
+ readchar_buffer_put (ch);
+ return -1;
+ }
+ return 0;
+}
+
+int
+send_reportasync_pkg (void)
+{
+ unsigned char rspbuf[4096];
+ static int sig_count = 0;
+
+ if (got_pkg)
+ return -1;
+
+ if (shake_hands ())
+ return -1;
+
+ inside_send_reportasync_pkg = 1;
+ sig_count ++;
+ snprintf (rspbuf, 4096, "SIG from remote %d", sig_count);
+ write_rsppkg (rspbuf);
+ read_rsppkg (rspbuf, 4096);
+ inside_send_reportasync_pkg = 0;
+ return 0;
+}
+
+static void
+handle_alrm(int signo)
+{
+ send_reportasync_pkg ();
+ alarm (1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ socklen_t tmp;
+ struct sockaddr_in sockaddr;
+ unsigned char rspbuf[4096];
+
+ if (signal (SIGALRM, handle_alrm) == SIG_ERR)
+ {
+ perror("Can't call signal");
+ exit(-errno);
+ }
+
+ /* Init listen_desc. */
+ if (argc != 2)
+ {
+ printf ("Usage: %s port\n", argv[0]);
+ exit (-1);
+ }
+ listen_desc = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (listen_desc == -1)
+ {
+ perror ("Can't open socket");
+ exit (-errno);
+ }
+ setsockopt (listen_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
+ sizeof (tmp));
+ sockaddr.sin_family = PF_INET;
+ sockaddr.sin_port = htons (atoi(argv[1]));
+ sockaddr.sin_addr.s_addr = INADDR_ANY;
+ if (bind (listen_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
+ || listen (listen_desc, 1))
+ {
+ printf ("Can't bind port\n");
+ exit (-errno);
+ }
+ else
+ printf ("Listening on %d\n", atoi(argv[1]));
+
+ accept_remote ();
+
+ while (1)
+ {
+ got_pkg = 0;
+ if (read_rsppkg (rspbuf, 4096))
+ {
+ printf ("Remote port closed.\n");
+ exit (-1);
+ }
+
+ switch (rspbuf[0])
+ {
+ case '?':
+ write_rsppkg ("S05");
+ break;
+
+ case 'g':
+ case 'm':
+ case 'p':
+ if (sizeof (long) == 8)
+ write_rsppkg ("0000000000000000");
+ else
+ write_rsppkg ("00000000");
+ break;
+
+ case 'c':
+ sleep (1);
+ got_pkg = 0;
+ if (send_reportasync_pkg ())
+ {
+ printf ("Try to send ReportAsync package got error.\n");
+ exit (-1);
+ }
+ sleep (1);
+ write_rsppkg ("S05");
+ alarm (1);
+ loop_test_begin = 1;
+ break;
+
+ case 'q':
+ if (strncmp("qSupported", rspbuf, strlen ("qSupported")) == 0)
+ write_rsppkg ("ReportAsync+");
+ else
+ {
+ if (loop_test_begin)
+ write (remote_desc, "^" , 1);
+ write_rsppkg ("");
+ }
+ break;
+
+ case 'k':
+ exit (0);
+ break;
+
+ default:
+ write_rsppkg ("");
+ break;
+ }
+
+ }
+
+ return 0;
+}
--- /dev/null
+++ b/testsuite/gdb.remote/reportasync-test.exp
@@ -0,0 +1,80 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2012 Free Software Foundation, Inc.
+
+# 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 <http://www.gnu.org/licenses/>.
+
+load_lib gdbserver-support.exp
+
+set testfile "reportasync-test"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested reportasync-test.exp
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Make sure we're disconnected, in case we're testing with an
+# extended-remote board, therefore already connected.
+gdb_test "disconnect" ".*"
+
+send_gdb "show remote report-async\n"
+gdb_expect 10 {
+ -re "Undefined show remote command" {
+ fail "ReportAsync support"
+ return
+ }
+ -re "Support for the `ReportAsync' packet is auto-detected" {
+ pass "ReportAsync support"
+ }
+}
+
+#Let GDB connect to test server
+set portnum 2345
+while 1 {
+ set server_spawn_id [remote_spawn target "$binfile $portnum"]
+ expect {
+ -i $server_spawn_id
+ -notransfer
+ -re "Listening on" {}
+ -re "Can't bind port" {
+ incr portnum
+ continue
+ }
+ }
+ break
+}
+gdb_target_cmd "remote" ":$portnum"
+
+gdb_test "continue" ".*0x00000000 in ?? ().*" "Continue with AsyncReport first time"
+
+exec sleep 2
+
+gdb_test "set debug remote 1" ".*"
+
+gdb_test "x 0" ".*Ignore a ReportAsync shake hands package because waiting a ack.*" "Fake shake hands package first time"
+
+gdb_test "set debug remote 0" ".*"
+
+gdb_test "continue" ".*0x00000000 in ?? ().*" "Continue with AsyncReport second time"
+
+gdb_test "set debug remote 1" ".*"
+
+gdb_test "tstatus" ".*Ignore a ReportAsync shake hands package because waiting a response.*" "Fake shake hands package second time"
+
More information about the Gdb-patches
mailing list