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  <tom@tromey.com>
 
+	* 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  <tom@tromey.com>
+
 	* 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  <tom@tromey.com>
+
+	* gdb.texinfo (Maintenance Commands): Document "maint selftest".
+
 2016-04-27  Yao Qi  <yao.qi@linaro.org>
 
 	* 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 <http://www.gnu.org/licenses/>.  */
+
+#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 <http://www.gnu.org/licenses/>.  */
+
+#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  <tom@tromey.com>
+
+	* gdb.gdb/unittest.exp: New file.
+
 2016-05-16  Yao Qi  <yao.qi@linaro.org>
 
 	* 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 <http://www.gnu.org/licenses/>.
+
+gdb_start
+gdb_test "maintenance selftest" "Ran $decimal unit tests, 0 failed"
