From patchwork Tue May 17 20:18:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 12321 Received: (qmail 37185 invoked by alias); 17 May 2016 20:18:40 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 36731 invoked by uid 89); 17 May 2016 20:18:39 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_00, FSL_HELO_HOME, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=no version=3.3.2 spammy=Maintenance, threw, H*m:tromey, Self X-HELO: gproxy10-pub.mail.unifiedlayer.com Received: from gproxy10-pub.mail.unifiedlayer.com (HELO gproxy10-pub.mail.unifiedlayer.com) (69.89.20.226) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with SMTP; Tue, 17 May 2016 20:18:24 +0000 Received: (qmail 31168 invoked by uid 0); 17 May 2016 20:18:22 -0000 Received: from unknown (HELO cmgw3) (10.0.90.84) by gproxy10.mail.unifiedlayer.com with SMTP; 17 May 2016 20:18:22 -0000 Received: from box522.bluehost.com ([74.220.219.122]) by cmgw3 with id vYJJ1s00J2f2jeq01YJM7H; Tue, 17 May 2016 14:18:22 -0600 X-Authority-Analysis: v=2.1 cv=cYhB8BzM c=1 sm=1 tr=0 a=GsOEXm/OWkKvwdLVJsfwcA==:117 a=GsOEXm/OWkKvwdLVJsfwcA==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=PnD2wP_eR3oA:10 a=_v2sUkyEFrwA:10 a=yrkiwgmsf1kA:10 a=zstS-IiYAAAA:8 a=KKAkSRfTAAAA:8 a=mDV3o1hIAAAA:8 a=LYxUrnBFnhYN9VJaNs8A:9 a=11hZ6f0lc2e_PIdd:21 a=Lr5c89oyrYXjf4bz:21 a=4G6NA9xxw8l3yy4pmD5M:22 a=cvBusfyB2V15izCimMoJ:22 a=_FVE-zBwftR9WsbkzFJk:22 Received: from [71.215.116.141] (port=57178 helo=bapiya.Home) by box522.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.86_2) (envelope-from ) id 1b2lRZ-0007dG-VI; Tue, 17 May 2016 14:18:18 -0600 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [FYI v3 3/8] Add self-test framework to gdb Date: Tue, 17 May 2016 14:18:03 -0600 Message-Id: <1463516288-26778-4-git-send-email-tom@tromey.com> In-Reply-To: <1463516288-26778-1-git-send-email-tom@tromey.com> References: <1463516288-26778-1-git-send-email-tom@tromey.com> X-Identified-User: {36111:box522.bluehost.com:elynrobi:tromey.com} {sentby:smtp auth 71.215.116.141 authed with tom+tromey.com} I wanted to unit test the Rust lexer, so I added a simple unit testing command to gdb. The intent is that self tests will only be compiled into gdb in development mode. In release mode they simply won't exist. So, this exposes $development to C code as GDB_SELF_TEST. In development mode, test functions are registered with the self test module. A test function is just a function that does some checks, and throws an exception on failure. Then this adds a new "maint selftest" command which invokes the test functions, and a new dejagnu test case that invokes it. 2016-05-17 Tom Tromey * NEWS: Add "maint selftest" entry. * selftest.h: New file. * selftest.c: New file. * maint.c: Include selftest.h. (maintenance_selftest): New function. (_initialize_maint_cmds): Add "maint selftest" command. * configure.ac (GDB_SELF_TEST): Maybe define. * config.in, configure: Rebuild. * Makefile.in (SFILES): Add selftest.c. (COMMON_OBS): Add selftest.o. 2016-05-17 Tom Tromey * gdb.texinfo (Maintenance Commands): Document "maint selftest". 2016-05-17 Tom Tromey * gdb.gdb/unittest.exp: New file. --- gdb/ChangeLog | 13 ++++++++ gdb/Makefile.in | 4 +-- gdb/NEWS | 3 ++ gdb/config.in | 3 ++ gdb/configure | 6 ++++ gdb/configure.ac | 5 +++ gdb/doc/ChangeLog | 4 +++ gdb/doc/gdb.texinfo | 5 +++ gdb/maint.c | 18 ++++++++++ gdb/selftest.c | 67 ++++++++++++++++++++++++++++++++++++++ gdb/selftest.h | 44 +++++++++++++++++++++++++ gdb/testsuite/ChangeLog | 4 +++ gdb/testsuite/gdb.gdb/unittest.exp | 17 ++++++++++ 13 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 gdb/selftest.c create mode 100644 gdb/selftest.h create mode 100644 gdb/testsuite/gdb.gdb/unittest.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6bed450..cad948f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,18 @@ 2016-05-17 Tom Tromey + * NEWS: Add "maint selftest" entry. + * selftest.h: New file. + * selftest.c: New file. + * maint.c: Include selftest.h. + (maintenance_selftest): New function. + (_initialize_maint_cmds): Add "maint selftest" command. + * configure.ac (GDB_SELF_TEST): Maybe define. + * config.in, configure: Rebuild. + * Makefile.in (SFILES): Add selftest.c. + (COMMON_OBS): Add selftest.o. + +2016-05-17 Tom Tromey + * expprint.c: Include f-lang.h. (print_subexp_standard, dump_subexp_body_standard): Handle OP_F90_RANGE. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 400d2b0..c42b9ae 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -869,7 +869,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ proc-service.list progspace.c \ prologue-value.c psymtab.c \ regcache.c reggroups.c remote.c remote-fileio.c remote-notif.c reverse.c \ - sentinel-frame.c \ + selftest.c sentinel-frame.c \ serial.c ser-base.c ser-unix.c ser-event.c skip.c \ solib.c solib-target.c source.c \ stabsread.c stack.c probe.c stap-probe.c std-regs.c \ @@ -1060,7 +1060,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ go-lang.o go-valprint.o go-typeprint.o \ jv-lang.o jv-valprint.o jv-typeprint.o jv-varobj.o \ m2-lang.o opencl-lang.o p-lang.o p-typeprint.o p-valprint.o \ - sentinel-frame.o \ + selftest.o sentinel-frame.o \ complaints.o typeprint.o \ ada-typeprint.o c-typeprint.o f-typeprint.o m2-typeprint.o \ ada-valprint.o c-valprint.o cp-valprint.o d-valprint.o f-valprint.o \ diff --git a/gdb/NEWS b/gdb/NEWS index 7bf1e1a..77dfc0c 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -40,6 +40,9 @@ skip -rfunction regular-expression maint info line-table REGEXP Display the contents of GDB's internal line table data struture. +maint selftest + Run any GDB unit tests that were compiled in. + * Support for tracepoints and fast tracepoints on s390-linux and s390x-linux was added in GDBserver, including JIT compiling fast tracepoint's conditional expression bytecode into native code. diff --git a/gdb/config.in b/gdb/config.in index dc9da0a..905caf0 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -65,6 +65,9 @@ /* Define to the default OS ABI for this configuration. */ #undef GDB_OSABI_DEFAULT +/* Define if self-testing features should be enabled */ +#undef GDB_SELF_TEST + /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA diff --git a/gdb/configure b/gdb/configure index 7ade907..c9cd3ba 100755 --- a/gdb/configure +++ b/gdb/configure @@ -16500,6 +16500,12 @@ ac_config_links="$ac_config_links $ac_config_links_1" $as_echo "#define GDB_DEFAULT_HOST_CHARSET \"UTF-8\"" >>confdefs.h +if $development; then + +$as_echo "#define GDB_SELF_TEST 1" >>confdefs.h + +fi + gdb_ac_transform=`echo "$program_transform_name" | sed -e 's/\\$\\$/\\$/g'` GDB_TRANSFORM_NAME=`echo gdb | sed -e "$gdb_ac_transform"` diff --git a/gdb/configure.ac b/gdb/configure.ac index d1930f9..4364c02 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -2348,6 +2348,11 @@ dnl At the moment, we just assume it's UTF-8. AC_DEFINE(GDB_DEFAULT_HOST_CHARSET, "UTF-8", [Define to be a string naming the default host character set.]) +if $development; then + AC_DEFINE(GDB_SELF_TEST, 1, + [Define if self-testing features should be enabled]) +fi + GDB_AC_TRANSFORM([gdb], [GDB_TRANSFORM_NAME]) GDB_AC_TRANSFORM([gcore], [GCORE_TRANSFORM_NAME]) AC_CONFIG_FILES([gcore], [chmod +x gcore]) diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index a6bd214..2db9be2 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,7 @@ +2016-05-17 Tom Tromey + + * gdb.texinfo (Maintenance Commands): Document "maint selftest". + 2016-04-27 Yao Qi * gdb.texinfo (tfind): Complete doc about tfind without diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index f74c41c..f91a609 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -34451,6 +34451,11 @@ that symbol is described. The type chain produced by this command is a recursive definition of the data type as stored in @value{GDBN}'s data structures, including its flags and contained types. +@kindex maint selftest +@cindex self tests +Run any self tests that were compiled in to @value{GDBN}. This will +print a message showing how many tests were run, and how many failed. + @kindex maint set dwarf always-disassemble @kindex maint show dwarf always-disassemble @item maint set dwarf always-disassemble diff --git a/gdb/maint.c b/gdb/maint.c index 5da1c11..d2c9346 100644 --- a/gdb/maint.c +++ b/gdb/maint.c @@ -41,6 +41,7 @@ #include "top.h" #include "timeval-utils.h" #include "maint.h" +#include "selftest.h" #include "cli/cli-decode.h" #include "cli/cli-utils.h" @@ -981,6 +982,16 @@ show_per_command_cmd (char *args, int from_tty) cmd_show_list (per_command_showlist, from_tty, ""); } + +/* The "maintenance selftest" command. */ + +static void +maintenance_selftest (char *args, int from_tty) +{ + run_self_tests (); +} + + void _initialize_maint_cmds (void) { @@ -1153,6 +1164,13 @@ testsuite can check the command deprecator. You probably shouldn't use this,\n\ If you decide you want to use it: maintenance undeprecate 'commandname'"), &maintenancelist); + add_cmd ("selftest", class_maintenance, maintenance_selftest, _("\ +Run gdb's unit tests.\n\ +Usage: maintenance selftest\n\ +This will run any unit tests that were built in to gdb.\n\ +gdb will abort if any test fails."), + &maintenancelist); + add_setshow_zinteger_cmd ("watchdog", class_maintenance, &watchdog, _("\ Set watchdog timer."), _("\ Show watchdog timer."), _("\ diff --git a/gdb/selftest.c b/gdb/selftest.c new file mode 100644 index 0000000..c63c06d --- /dev/null +++ b/gdb/selftest.c @@ -0,0 +1,67 @@ +/* GDB self-testing. + Copyright (C) 2016 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#include "defs.h" +#include "selftest.h" +#include "vec.h" + +typedef self_test_function *self_test_function_ptr; + +DEF_VEC_P (self_test_function_ptr); + +/* All the tests that have been registered. */ + +static VEC (self_test_function_ptr) *tests; + +/* See selftest.h. */ + +void +register_self_test (self_test_function *function) +{ + VEC_safe_push (self_test_function_ptr, tests, function); +} + +/* See selftest.h. */ + +void +run_self_tests (void) +{ + int i; + self_test_function_ptr func; + int failed = 0; + + for (i = 0; VEC_iterate (self_test_function_ptr, tests, i, func); ++i) + { + QUIT; + + TRY + { + (*func) (); + } + CATCH (ex, RETURN_MASK_ERROR) + { + ++failed; + exception_fprintf (gdb_stderr, ex, + _("Self test threw exception")); + } + END_CATCH + } + + printf_filtered (_("Ran %u unit tests, %d failed\n"), + VEC_length (self_test_function_ptr, tests), failed); +} diff --git a/gdb/selftest.h b/gdb/selftest.h new file mode 100644 index 0000000..2b028dd --- /dev/null +++ b/gdb/selftest.h @@ -0,0 +1,44 @@ +/* GDB self-testing. + Copyright (C) 2016 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +#ifndef SELFTEST_H +#define SELFTEST_H + +/* A test is just a function that does some checks and throws an + exception if something has gone wrong. */ + +typedef void self_test_function (void); + +/* Register a new self-test. */ + +extern void register_self_test (self_test_function *function); + +/* Run all the self tests. This print a message describing the number + of test and the number of failures. */ + +extern void run_self_tests (void); + +/* Check that VALUE is true, and, if not, throw an exception. */ + +#define SELF_CHECK(VALUE) \ + do { \ + if (!(VALUE)) \ + error (_("self-test failed at %s:%d"), __FILE__, __LINE__); \ + } while (0) + +#endif /* SELFTEST_H */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index c5ec756..0e45f19 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-05-17 Tom Tromey + + * gdb.gdb/unittest.exp: New file. + 2016-05-16 Yao Qi * gdb.base/batch-preserve-term-settings.exp: Remove variable diff --git a/gdb/testsuite/gdb.gdb/unittest.exp b/gdb/testsuite/gdb.gdb/unittest.exp new file mode 100644 index 0000000..88fd266 --- /dev/null +++ b/gdb/testsuite/gdb.gdb/unittest.exp @@ -0,0 +1,17 @@ +# Copyright 2016 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 . + +gdb_start +gdb_test "maintenance selftest" "Ran $decimal unit tests, 0 failed"