[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