This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[unavailable values part 1, 12/17] initial unavailable-ness tests


This adds some base partial data display tests to the testsuite.
Only globals are tested at this point, as the glue between
unavailable registers and frames and values will only come
afterwards.

Should be passing cleanly at this point.

-- 
Pedro Alves

2011-02-07  Pedro Alves  <pedro@codesourcery.com>

	gdb/testsuite/
	* gdb.trace/unavailable.cc, gdb.trace/unavailable.exp: New files.

---
 gdb/testsuite/gdb.trace/unavailable.cc  |  204 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.trace/unavailable.exp |  242 ++++++++++++++++++++++++++++++++
 2 files changed, 446 insertions(+)

Index: src/gdb/testsuite/gdb.trace/unavailable.cc
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/testsuite/gdb.trace/unavailable.cc	2011-02-07 13:14:41.776706005 +0000
@@ -0,0 +1,204 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2002, 2003, 2004, 2007, 2008, 2009, 2010, 2011
+   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 <stdlib.h>
+#include <string.h>
+
+/* Test program partial trace data visualization.  */
+
+/* Typedefs.  */
+
+typedef struct TEST_STRUCT {
+  char   memberc;
+  int    memberi;
+  float  memberf;
+  double memberd;
+} test_struct;
+
+typedef int test_array [4];
+
+/* Global variables to be collected.  */
+
+char         globalc;
+int          globali;
+float        globalf;
+double       globald;
+test_struct  globalstruct;
+test_struct *globalp;
+int          globalarr[16];
+
+/* Strings.  */
+
+const char g_const_string[] = "hello world";
+char g_string_unavail[sizeof (g_const_string)];
+char g_string_partial[sizeof (g_const_string)];
+const char *g_string_p;
+
+/* Used to check that <unavailable> is not the same as 0 in array
+   element repetitions.  */
+
+struct tuple
+{
+  int a;
+  int b;
+};
+
+struct tuple tarray[8];
+
+/* Random tests.  */
+
+struct StructA
+{
+  int a, b;
+  int array[10000];
+  void *ptr;
+  int bitfield:1;
+};
+
+struct StructB
+{
+  int d, ef;
+  StructA struct_a;
+  int s:1;
+  static StructA static_struct_a;
+  const char *string;
+};
+
+/* References.  */
+
+int g_int;
+int &g_ref = g_int;
+
+struct StructRef
+{
+  StructRef (unsigned int val) : ref(d) {}
+
+  void clear ()
+  {
+    d = 0;
+  }
+
+  unsigned int d;
+  unsigned int &ref;
+};
+
+struct StructB struct_b;
+struct StructA StructB::static_struct_a;
+
+StructRef g_structref(0x12345678);
+StructRef *g_structref_p = &g_structref;
+
+
+/* Test functions.  */
+
+static void
+begin ()	/* called before anything else */
+{
+}
+
+static void
+end ()		/* called after everything else */
+{
+}
+
+int
+globals_test_func ()
+{
+  int i = 0;
+
+  i += globalc + globali + globalf + globald;
+  i += globalstruct.memberc + globalstruct.memberi;
+  i += globalstruct.memberf + globalstruct.memberd;
+  i += globalarr[1];
+
+  return i;	/* set globals_test_func tracepoint here */
+}
+
+int
+main (int argc, char **argv, char **envp)
+{
+  int         i = 0;
+  test_struct mystruct;
+  int         myarray[4];
+
+  begin ();
+  /* Assign collectable values to global variables.  */
+  globalc = 71;
+  globali = 72;
+  globalf = 73.3;
+  globald = 74.4;
+  globalstruct.memberc = 81;
+  globalstruct.memberi = 82;
+  globalstruct.memberf = 83.3;
+  globalstruct.memberd = 84.4;
+  globalp = &globalstruct;
+
+  for (i = 0; i < 15; i++)
+    globalarr[i] = i;
+
+  mystruct.memberc = 101;
+  mystruct.memberi = 102;
+  mystruct.memberf = 103.3;
+  mystruct.memberd = 104.4;
+  myarray[0] = 111;
+  myarray[1] = 112;
+  myarray[2] = 113;
+  myarray[3] = 114;
+
+  g_int = 123;
+  memset (&struct_b, 0xaa, sizeof struct_b);
+  memset (&struct_b.static_struct_a, 0xaa, sizeof struct_b.static_struct_a);
+  struct_b.string = g_const_string;
+  memcpy (g_string_unavail, g_const_string, sizeof (g_const_string));
+  memcpy (g_string_partial, g_const_string, sizeof (g_const_string));
+  g_string_p = g_const_string;
+
+  /* Call test functions, so they can be traced and data collected.  */
+  i = 0;
+  i += globals_test_func ();
+
+  /* Set 'em back to zero, so that the collected values will be
+     distinctly different from the "realtime" (end of test) values.  */
+
+  globalc = 0;
+  globali = 0;
+  globalf = 0;
+  globald = 0;
+  globalstruct.memberc = 0;
+  globalstruct.memberi = 0;
+  globalstruct.memberf = 0;
+  globalstruct.memberd = 0;
+  globalp = 0;
+  for (i = 0; i < 15; i++)
+    globalarr[i] = 0;
+
+  memset (&struct_b, 0, sizeof struct_b);
+  memset (&struct_b.static_struct_a, 0, sizeof struct_b.static_struct_a);
+  struct_b.string = NULL;
+  memset (g_string_unavail, 0, sizeof (g_string_unavail));
+  memset (g_string_partial, 0, sizeof (g_string_partial));
+  g_string_p = NULL;
+
+  g_int = 0;
+
+  g_structref.clear ();
+  g_structref_p = NULL;
+
+  end ();
+  return 0;
+}
Index: src/gdb/testsuite/gdb.trace/unavailable.exp
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/testsuite/gdb.trace/unavailable.exp	2011-02-07 13:15:03.446706008 +0000
@@ -0,0 +1,242 @@
+# Copyright 1998, 2005, 2007, 2008, 2009, 2010, 2011
+# 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 "trace-support.exp"
+
+set testfile "unavailable"
+set srcfile ${testfile}.cc
+set executable $testfile
+set binfile $objdir/$subdir/$executable
+
+if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \
+	executable {debug nowarnings c++}] != "" } {
+    untested unavailable.exp
+    return -1
+}
+
+set ws "\[\r\n\t \]+"
+set cr "\[\r\n\]+"
+
+#
+# Utility procs
+#
+
+proc prepare_for_trace_test {} {
+    global executable
+
+    clean_restart $executable
+
+    runto_main
+
+    gdb_test "break begin" ".*" ""
+    gdb_test "break end" ".*" ""
+}
+
+proc run_trace_experiment { test_func } {
+    global gdb_prompt
+
+    gdb_test "continue" \
+	".*Breakpoint \[0-9\]+, begin .*" \
+	"advance to begin"
+
+    gdb_test_no_output "tstart" "start trace experiment"
+
+    gdb_test "continue" \
+	    "Continuing.*Breakpoint \[0-9\]+, end.*" \
+	    "run trace experiment"
+    gdb_test "tstop" \
+	    "\[\r\n\]+" \
+	    "stop trace experiment"
+    gdb_test "tfind start" \
+	    "#0  $test_func .*" \
+	    "tfind test frame"
+}
+
+#
+# Test procs
+#
+
+proc gdb_collect_globals_test { } {
+    global ws
+    global cr
+    global gdb_prompt
+    global hex
+    global pf_prefix
+
+    set old_pf_prefix $pf_prefix
+    set pf_prefix "$pf_prefix collect globals:"
+
+    prepare_for_trace_test
+
+    set testline [gdb_get_line_number "set globals_test_func tracepoint here"]
+
+    gdb_test "trace $testline" \
+	    "Tracepoint \[0-9\]+ at .*" \
+	    "set tracepoint"
+
+    gdb_trace_setactions "define actions" \
+	"" \
+	"collect struct_b.struct_a.array\[2\]" "^$" \
+	"collect struct_b.struct_a.array\[100\]" "^$" \
+	\
+	"collect tarray\[0\].a" "^$" \
+	"collect tarray\[1\].a" "^$" \
+	"collect tarray\[3\].a" "^$" \
+	"collect tarray\[3\].b" "^$" \
+	"collect tarray\[4\].b" "^$" \
+	"collect tarray\[5\].b" "^$" \
+	\
+	"collect g_string_p" "^$" \
+	"collect g_string_partial\[1\]" "^$" \
+	"collect g_string_partial\[2\]" "^$" \
+	\
+	"collect g_structref_p" "^$" \
+
+    # Begin the test.
+    run_trace_experiment globals_test_func
+
+    gdb_test "print globalc" " = <unavailable>"
+    gdb_test "print globali" " = <unavailable>"
+    gdb_test "print globalf" " = <unavailable>"
+    gdb_test "print globald" " = <unavailable>"
+
+    gdb_test "print globalstruct.memberc" " = <unavailable>"
+    gdb_test "print globalstruct.memberi" " = <unavailable>"
+    gdb_test "print globalstruct.memberf" " = <unavailable>"
+    gdb_test "print globalstruct.memberd" " = <unavailable>"
+
+    gdb_test "print globalstruct" \
+	    " = {memberc = <unavailable>, memberi = <unavailable>, memberf = <unavailable>, memberd = <unavailable>}"
+
+    gdb_test "print globalp == &globalstruct" \
+	    "value is not available" \
+	    "can't compare using non collected global pointer"
+
+    gdb_test "print globalarr\[1\]" " = <unavailable>"
+    gdb_test "print globalarr\[2\]" " = <unavailable>"
+    gdb_test "print globalarr\[3\]" " = <unavailable>"
+
+    gdb_test "print struct_b" \
+	" = {d = <unavailable>, ef = <unavailable>, struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable>, <unavailable>, -1431655766, <unavailable> <repeats 97 times>, -1431655766, <unavailable> <repeats 9899 times>}, ptr = <unavailable>, bitfield = <unavailable>}, s = <unavailable>, static static_struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable> <repeats 10000 times>}, ptr = <unavailable>, bitfield = <unavailable>}, string = <unavailable>}"
+
+    gdb_test "print /x struct_b" \
+	" = {d = <unavailable>, ef = <unavailable>, struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable>, <unavailable>, 0xaaaaaaaa, <unavailable> <repeats 97 times>, 0xaaaaaaaa, <unavailable> <repeats 9899 times>}, ptr = <unavailable>, bitfield = <unavailable>}, s = <unavailable>, static static_struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable> <repeats 10000 times>}, ptr = <unavailable>, bitfield = <unavailable>}, string = <unavailable>}"
+
+    gdb_test "print /x struct_b.struct_a" \
+	" = {a = <unavailable>, b = <unavailable>, array = {<unavailable>, <unavailable>, 0xaaaaaaaa, <unavailable> <repeats 97 times>, 0xaaaaaaaa, <unavailable> <repeats 9899 times>}, ptr = <unavailable>, bitfield = <unavailable>}"
+
+    gdb_test "print /x struct_b.struct_a.array" \
+	" = {<unavailable>, <unavailable>, 0xaaaaaaaa, <unavailable> <repeats 97 times>, 0xaaaaaaaa, <unavailable> <repeats 9899 times>}"
+
+    gdb_test "print /x struct_b.struct_a.array\[0\]" " = <unavailable>"
+
+    gdb_test "print /x struct_b.struct_a.array\[2\]" " = 0xaaaaaaaa"
+
+    # Check <unavailable> isn't confused with 0 in array element repetitions
+
+    gdb_test_no_output "set print repeat 1"
+
+    gdb_test "print /x tarray" \
+	" = \{\{a = 0x0, b = <unavailable>\} <repeats 2 times>, \{a = <unavailable>, b = <unavailable>\}, \{a = 0x0, b = 0x0\}, \{a = <unavailable>, b = 0x0\} <repeats 2 times>, \{a = <unavailable>, b = <unavailable>\} <repeats 2 times>\}" \
+	"<unavailable> is not the same as 0 in array element repetitions"
+
+    gdb_test_no_output "set print repeat 10"
+
+    # Static fields
+
+    gdb_test "print struct_b.static_struct_a" \
+	" = {a = <unavailable>, b = <unavailable>, array = {<unavailable> <repeats 10000 times>}, ptr = <unavailable>, bitfield = <unavailable>}"
+
+    # Bitfields
+
+    gdb_test "print struct_b.struct_a.bitfield" " = <unavailable>"
+
+    # References
+
+    gdb_test "print g_int" " = <unavailable>"
+
+    gdb_test "print g_ref" \
+	"\\(int &\\) @$hex: <unavailable>" \
+	"global reference shows address but not value"
+
+    gdb_test "print *&g_ref" \
+	"\\$\[0-9\]+ = <unavailable>$cr" \
+	"referenced integer was not collected (taking address of reference)"
+
+    gdb_test "print *g_structref_p" \
+	" = {d = <unavailable>, ref = <unavailable>}"
+
+    # Strings
+
+    # Const string is always available, even when not collected.
+    gdb_test "print g_const_string" \
+	" = \"hello world\"$cr" \
+	"non collected const string is still printable"
+
+    gdb_test "print g_string_p" \
+	" = $hex \"hello world\"" \
+	"printing constant string through collected pointer"
+
+    gdb_test "print g_string_unavail" \
+	" = \{<unavailable> <repeats 12 times>\}" \
+	"printing non collected string"
+
+    # Incomplete strings print as an array.
+    gdb_test "print g_string_partial" \
+	"\\$\[0-9\]+ = \{<unavailable>, 101 'e', 108 'l', <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>\}" \
+	"printing partially collected string"
+
+    # It is important for this test that the last examined value is
+    # <unavailable>, to exercise the case of the $__ convenience
+    # variable being set to <unavailable> without error.
+    set msg "examining partially collected object"
+    gdb_test_multiple "x /10x &struct_b" "$msg" {
+	-re "$hex <struct_b>:${ws}<unavailable>${ws}<unavailable>${ws}<unavailable>${ws}<unavailable>$cr$hex <struct_b\\+16>:${ws}<unavailable>${ws}<unavailable>${ws}0xaaaaaaaa${ws}<unavailable>$cr$hex <struct_b\\+32>:${ws}<unavailable>${ws}<unavailable>$cr$gdb_prompt $" {
+	    pass "$msg"
+	}
+	-re "value is not available" {
+	    fail "$msg"
+	}
+    }
+
+    gdb_test "p \$__" " = <unavailable>" "last examined value was <unavailable>"
+
+    gdb_test "tfind none" \
+	"#0  end .*" \
+	"cease trace debugging"
+
+    set pf_prefix $old_pf_prefix
+}
+
+proc gdb_trace_collection_test {} {
+    gdb_collect_globals_test
+}
+
+clean_restart $executable
+runto_main
+
+# We generously give ourselves one "pass" if we successfully
+# detect that this test cannot be run on this target!
+if { ![gdb_target_supports_trace] } then {
+    pass "Current target does not support trace"
+    return 1;
+}
+
+# Body of test encased in a proc so we can return prematurely.
+gdb_trace_collection_test
+
+# Finished!
+gdb_test "tfind none" ".*" ""


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]