[PATCH 11/12] Add test mechanism for value unavailable vector.

Andrew Burgess
2013-08-12T12:32:50Z

This patch it optional, and is really just an idea. More work
might be required.

This adds a unit test like command for the value unavailable vector.
This let me build vectors and see how they were merged and ordered to
help get the code right.

Given that the amount of extra code is pretty small it might be nice to
keep this in.... what do you think?

Some possible changes would be, adding a new "unit-test" sub-command
under which this could be placed, currently the test command lives
under maintenance, but we could have "maintenance unit-test <blah>".
We could also guard the unit tests with a build flag so compiling
them in was optional.

What do folk think?

Cheers,
Andrew

gdb/ChangeLog

2013-08-09 Andrew Burgess <aburgess@broadcom.com>

* value.c (vector_test_show): New function.
(vector_test_parse_range): New function.
(vector_test_command): New function.
(_initialize_values): Add value-vector-test command.

gdb/testsuite/ChangeLog

2013-08-09 Andrew Burgess <aburgess@broadcom.com>

* gdb.base/value-unavailable-vector.exp: New file.

diff --git a/gdb/testsuite/gdb.base/value-unavailable-vector.exp
b/gdb/testsuite/gdb.base/value-unavailable-vector.exp
new file mode 100644
index 0000000..2a602eb
--- /dev/null
+++ b/gdb/testsuite/gdb.base/value-unavailable-vector.exp
@@ -0,0 +1,32 @@
+# Copyright 2013 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/>.
+
+# Test the behaviour of the gdb value unavailable bits vector.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "maintenance value-vector-test (2,2,unavailable)
(4,2,unavailable) (2,6,optimized-out)" \
+ "VECTOR: \\(2, 6, optimized-out\\)"
+
+gdb_test "maintenance value-vector-test ( 4, 2,unavailable) ( 8,
2,unavailable) (12, 2,unavailable) ( 2,11,optimized-out)" \
+ "VECTOR: \\(2, 11, optimized-out\\) \\(13, 1, unavailable\\)"
+
+gdb_test "maintenance value-vector-test ( 4, 2,unavailable) ( 8,
2,unavailable) (12, 2,optimized-out) ( 2,13,unavailable)" \
+ "VECTOR: \\(2, 10, unavailable\\) \\(12, 2, optimized-out\\) \\(14,
1, unavailable\\)"
+
+gdb_test "maintenance value-vector-test ( 4, 2,optimized-out) ( 8,
2,optimized-out) (12, 2,optimized-out) ( 2,13,unavailable)" \
+ "VECTOR: \\(2, 2, unavailable\\) \\(4, 2, optimized-out\\) \\(6, 2,
unavailable\\) \\(8, 2, optimized-out\\) \\(10, 2, unavailable\\) \\(12,
2, optimized-out\\) \\(14, 1, unavailable\\)"
diff --git a/gdb/value.c b/gdb/value.c
index ec46863..7151b61 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -43,6 +43,7 @@
#include "tracepoint.h"
#include "cp-abi.h"
#include "user-regs.h"
+#include "cli/cli-utils.h"
/* Prototypes for exported functions. */
@@ -3736,6 +3737,122 @@ value_fetch_lazy (struct value *val)
return 0;
}
+/* Internal debugging function. Used to display a vector containing the
+ unavailable and optimized out information. This is currently only used
+ by the maintenance command value-vector-test. */
+
+static void
+vector_test_show (VEC(range_s) *vector)
+{
+ if (VEC_empty (range_s, vector))
+ printf_filtered ("VECTOR is empty.\n");
+ else
+ {
+ range_s *r;
+ int i;
+
+ printf_filtered ("VECTOR:");
+ for (i = 0; VEC_iterate (range_s, vector, i, r); i++)
+ {
+ printf_filtered (" (%d, %d, %s)",
+ r->offset, r->length,
+ (r->reason == bit_range_optimized_out
+ ? "optimized-out"
+ : (r->reason == bit_range_unavailable
+ ? "unavailable"
+ : "unknown")));
+
+ if (i > 0)
+ {
+ range_s *prev = VEC_index (range_s, vector, (i - 1));
+
+ if (prev->offset + prev->length > r->offset)
+ internal_error (__FILE__, __LINE__,
+ "Inconsistent vector configuration: overlap");
+
+ if (prev->offset + prev->length == r->offset
+ && prev->reason == r->reason)
+ internal_error (__FILE__, __LINE__,
+ "Inconsistent vector configuration: unmerged");
+ }
+ }
+ printf_filtered ("\n");
+ }
+}
+
+/* Parse vector entries of the form "(START, LENGTH, TYPE)", where START
+ and LENGTH are numbers, START >= 0 && LENGTH > 0. The TYPE is a string
+ either "optimized-out", or "unavailable". */
+
+static char *
+vector_test_parse_range (char *exp, range_s *rng)
+{
+ char *tmp;
+
+ gdb_assert (exp);
+ exp = skip_spaces (exp);
+
+ memset (rng, 0, sizeof (*rng));
+
+ if (*exp != '(')
+ error ("Invalid range specification in `%s'", exp);
+ exp++;
+ /* Find the next "," character (error if non found). */
+ tmp = strchr (exp, ',');
+ if (!tmp)
+ error ("Missing `,' in `%s'", exp);
+ *tmp = '\0';
+ rng->offset = parse_and_eval_long (exp);
+ *tmp = ',';
+ exp = skip_spaces (tmp + 1);
+
+ tmp = strchr (exp, ',');
+ if (!tmp)
+ error ("Missing `,' in `%s'", exp);
+ *tmp = '\0';
+ rng->length = parse_and_eval_long (exp);
+ *tmp = ',';
+ exp = skip_spaces (tmp + 1);
+
+ tmp = strchr (exp, ')');
+ if (!tmp)
+ error ("Missing `)' in `%s'", exp);
+ *tmp = '\0';
+ if (strcasecmp (exp, "unavailable") == 0)
+ rng->reason = bit_range_unavailable;
+ else if (strcasecmp (exp, "optimized-out") == 0)
+ rng->reason = bit_range_optimized_out;
+ else
+ error ("unknown reason field in `%s'", exp);
+ *tmp = ')';
+ exp = skip_spaces (tmp + 1);
+
+ return exp;
+}
+
+/* Parse sequence of range descriptions from EXP into a vector then display
+ the resulting vector. This allows us to test the vector construction
+ algorithm. */
+
+static void
+vector_test_command (char *exp, int from_tty)
+{
+ VEC(range_s) *vector = NULL;
+
+ (void) from_tty;
+
+ while (exp && *exp != '\0')
+ {
+ range_s r;
+
+ exp = vector_test_parse_range (exp, &r);
+ insert_into_bit_range_vector (&vector, r.offset, r.length, r.reason);
+ }
+
+ vector_test_show (vector);
+ VEC_free (range_s, vector);
+}
+
void
_initialize_values (void)
{
@@ -3768,4 +3885,8 @@ VARIABLE is already initialized."));
add_prefix_cmd ("function", no_class, function_command, _("\
Placeholder command for showing help on convenience functions."),
&functionlist, "function ", 0, &cmdlist);
+
+ add_cmd ("value-vector-test", class_maintenance, vector_test_command,
+ _("Allows for testing of internal gdb unavailability vector."),
+ &maintenancelist);
}