diff options
author | Gary Benson <gbenson@redhat.com> | 2018-06-08 18:06:46 +0100 |
---|---|---|
committer | Gary Benson <gbenson@redhat.com> | 2018-06-08 18:06:46 +0100 |
commit | 5045b3d78903d1f6faa4cb511fa801e50dfacf48 (patch) | |
tree | c9d0de294605fc4784caf427f95d799f62088ce3 /gdb/testsuite | |
parent | 2f4f025ff15b900706c8597060003a506107cf23 (diff) | |
download | gdb-5045b3d78903d1f6faa4cb511fa801e50dfacf48.zip gdb-5045b3d78903d1f6faa4cb511fa801e50dfacf48.tar.gz gdb-5045b3d78903d1f6faa4cb511fa801e50dfacf48.tar.bz2 |
linux: Add maintenance commands to test libthread_db
This commit adds two new commands which may be used to test thread
debugging libraries used by GDB:
* "maint check libthread-db" tests the thread debugging library GDB
is using for the current inferior.
* "maint set/show check-libthread-db" selects whether libthread_db
tests should be run automatically as libthread_db is auto-loaded.
The default is to not run tests automatically.
The test itself is a basic integrity check exercising all libthread_db
functions used by GDB on GNU/Linux systems. By extension this also
exercises the proc_service functions provided by GDB that libthread_db
uses.
This functionality is useful for NPTL developers and libthread_db
developers. It could also prove useful investigating bugs reported
against GDB where the thread debugging library or GDB's proc_service
layer is suspect.
gdb/ChangeLog:
* linux-thread-db.c (valprint.h): New include.
(struct check_thread_db_info): New structure.
(check_thread_db_on_load, tdb_testinfo): New static globals.
(check_thread_db, check_thread_db_callback): New functions.
(try_thread_db_load_1): Run integrity checks if requested.
(maintenance_check_libthread_db): New function.
(_initialize_thread_db): Register "maint check libthread-db"
and "maint set/show check-libthread-db".
* NEWS: Mention the above new commands.
gdb/doc/ChangeLog:
* gdb.texinfo (Maintenance Commands): Document "maint check
libthread-db" and "maint set/show check-libthread-db".
gdb/testsuite/ChangeLog:
* gdb.threads/check-libthread-db.exp: New file.
* gdb.threads/check-libthread-db.c: Likewise.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/check-libthread-db.c | 67 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/check-libthread-db.exp | 114 |
3 files changed, 186 insertions, 0 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index eea782f..2324673 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-06-08 Gary Benson <gbenson@redhat.com> + + * gdb.threads/check-libthread-db.exp: New file. + * gdb.threads/check-libthread-db.c: Likewise. + 2018-06-05 Tom Tromey <tom@tromey.com> * gdb.base/default.exp: Update expected "show version" output. diff --git a/gdb/testsuite/gdb.threads/check-libthread-db.c b/gdb/testsuite/gdb.threads/check-libthread-db.c new file mode 100644 index 0000000..85a97a9 --- /dev/null +++ b/gdb/testsuite/gdb.threads/check-libthread-db.c @@ -0,0 +1,67 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2017-2018 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> +#include <pthread.h> +#include <errno.h> + +static void +break_here (void) +{ +} + +static void * +thread_routine (void *arg) +{ + errno = 42; + + break_here (); + + while (1) + sleep (1); + + return NULL; +} + +int +main (int argc, char *argv) +{ + pthread_t the_thread; + int err; + + err = pthread_create (&the_thread, NULL, thread_routine, NULL); + if (err != 0) + { + fprintf (stderr, "pthread_create: %s (%d)\n", strerror (err), err); + exit (EXIT_FAILURE); + } + + errno = 23; + + err = pthread_join (the_thread, NULL); + if (err != 0) + { + fprintf (stderr, "pthread_join: %s (%d)\n", strerror (err), err); + exit (EXIT_FAILURE); + } + + exit (EXIT_SUCCESS); +} diff --git a/gdb/testsuite/gdb.threads/check-libthread-db.exp b/gdb/testsuite/gdb.threads/check-libthread-db.exp new file mode 100644 index 0000000..ddd9c27 --- /dev/null +++ b/gdb/testsuite/gdb.threads/check-libthread-db.exp @@ -0,0 +1,114 @@ +# Copyright 2017-2018 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/>. + +# This test only works for native processes on GNU/Linux. +if {[target_info gdb_protocol] != "" || ![istarget *-linux*]} { + continue +} + +standard_testfile + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ + executable debug] != "" } { + return -1 +} + +with_test_prefix "user-initiated check" { + + # User-initiated check with libthread_db not loaded. + clean_restart ${binfile} + + gdb_test "maint show check-libthread-db" \ + "Whether to check libthread_db at load time is off." + + gdb_test_no_output "set stop-on-solib-events 1" + gdb_run_cmd + gdb_test "" \ + ".*Stopped due to shared library event.*no libraries added or removed.*" + + gdb_test "maint check libthread-db" \ + "No libthread_db loaded" \ + "no libpthread.so loaded" + + + # User-initiated check with NPTL uninitialized. + # libthread_db should fake a single thread with th_unique == NULL. + gdb_test "continue" \ + ".*Stopped due to shared library event.*Inferior loaded .*libpthread.*" + + gdb_test_sequence "maint check libthread-db" \ + "libpthread.so not initialized" { + "\[\r\n\]+Running libthread_db integrity checks:" + "\[\r\n\]+\[ \]+Got thread 0x0 => \[0-9\]+ => 0x0 ... OK" + "\[\r\n\]+libthread_db integrity checks passed." + } + + # User-initiated check with NPTL fully operational. + gdb_test_no_output "set stop-on-solib-events 0" + gdb_breakpoint break_here + gdb_continue_to_breakpoint break_here + + gdb_test_sequence "maint check libthread-db" \ + "libpthread.so fully initialized" { + "\[\r\n\]+Running libthread_db integrity checks:" + "\[\r\n\]+\[ \]+Got thread 0x\[1-9a-f\]\[0-9a-f\]+ => \[0-9\]+ => 0x\[1-9a-f\]\[0-9a-f\]+; errno = 23 ... OK" + "\[\r\n\]+\[ \]+Got thread 0x\[1-9a-f\]\[0-9a-f\]+ => \[0-9\]+ => 0x\[1-9a-f\]\[0-9a-f\]+; errno = 42 ... OK" + "\[\r\n\]+libthread_db integrity checks passed." + } +} + +with_test_prefix "automated load-time check" { + + # Automated load-time check with NPTL uninitialized. + with_test_prefix "libpthread.so not initialized" { + clean_restart ${binfile} + + gdb_test_no_output "maint set check-libthread-db 1" + gdb_test_no_output "set debug libthread-db 1" + gdb_breakpoint break_here + gdb_run_cmd + + gdb_test_sequence "" \ + "check debug libthread-db output" { + "\[\r\n\]+Running libthread_db integrity checks:" + "\[\r\n\]+\[ \]+Got thread 0x0 => \[0-9\]+ => 0x0 ... OK" + "\[\r\n\]+libthread_db integrity checks passed." + "\[\r\n\]+[Thread debugging using libthread_db enabled]" + } + } + + # Automated load-time check with NPTL fully operational. + with_test_prefix "libpthread.so fully initialized" { + clean_restart ${binfile} + + gdb_test_no_output "maint set check-libthread-db 1" + gdb_test_no_output "set debug libthread-db 1" + + set test_spawn_id [spawn_wait_for_attach $binfile] + set testpid [spawn_id_get_pid $test_spawn_id] + + gdb_test_sequence "attach $testpid" \ + "check debug libthread-db output" { + "\[\r\n\]+Running libthread_db integrity checks:" + "\[\r\n\]+\[ \]+Got thread 0x\[1-9a-f\]\[0-9a-f\]+ => \[0-9\]+ => 0x\[1-9a-f\]\[0-9a-f\]+ ... OK" + "\[\r\n\]+\[ \]+Got thread 0x\[1-9a-f\]\[0-9a-f\]+ => \[0-9\]+ => 0x\[1-9a-f\]\[0-9a-f\]+ ... OK" + "\[\r\n\]+libthread_db integrity checks passed." + "\[\r\n\]+[Thread debugging using libthread_db enabled]" + } + + gdb_exit + kill_wait_spawned_process $test_spawn_id + } +} |