- Fix "??" resolving of symbols from (non-prelinked) debuginfo packages.

- Fix "??" resolving of symbols from overlapping functions (nanosleep(3)).
- Also disable testcase "checkpoint.exp" for a possible kernel Bug 207002.
- Improved testsuite results by the testsuite provided by the courtesy of
    BEA.
- Related: rhbz#179399
Note: i386 test results of the BEA testsuite uuencode(1)d for `gdb2fail.sh'
    are too bogus, retest (RHTS?) required on the matching kernel.
    `WONTFIX' by makem.
This commit is contained in:
Jan Kratochvil 2006-11-02 22:58:41 +00:00
parent 5b4413efb9
commit b048379f11
4 changed files with 1299 additions and 2 deletions

938
gdb-6.5-BEA-testsuite.patch Normal file
View File

@ -0,0 +1,938 @@
Index: ./gdb/testsuite/gdb.threads/threadcrash.c
===================================================================
RCS file: gdb/testsuite/gdb.threads/threadcrash.c
diff -N gdb/testsuite/gdb.threads/threadcrash.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.threads/threadcrash.c 31 Oct 2006 17:54:38 -0000
@@ -0,0 +1,301 @@
+/*
+ * The point of this program is to crash in a multi-threaded app.
+ * There are seven threads, doing the following things:
+ * * Spinning
+ * * Spinning inside a signal handler
+ * * Spinning inside a signal handler executing on the altstack
+ * * In a syscall
+ * * In a syscall inside a signal handler
+ * * In a syscall inside a signal handler executing on the altstack
+ * * Finally, the main thread crashes in main, with no frills.
+ *
+ * These are the things threads in JRockit tend to be doing. If gdb
+ * can handle those things, both in core files and during live
+ * debugging, that will help (at least) JRockit development.
+ *
+ * Let the program create a core file, then load the core file into
+ * gdb. Inside gdb, you should be able to do something like this:
+ *
+ * (gdb) t a a bt
+ *
+ * Thread 7 (process 4352):
+ * #0 0x001ba7dc in __nanosleep_nocancel () from /lib/tls/libc.so.6
+ * #1 0x001ba5ff in sleep () from /lib/tls/libc.so.6
+ * #2 0x080488a2 in makeSyscall (ignored=0x0) at threadcrash.c:118
+ * #3 0x006aadec in start_thread () from /lib/tls/libpthread.so.0
+ * #4 0x001ed19a in clone () from /lib/tls/libc.so.6
+ *
+ * Thread 6 (process 4353):
+ * #0 0x001ba7dc in __nanosleep_nocancel () from /lib/tls/libc.so.6
+ * #1 0x001ba5ff in sleep () from /lib/tls/libc.so.6
+ * #2 0x0804898f in syscallingSighandler (signo=10, info=0xb6be76f0, context=0xb6be7770)
+ * at threadcrash.c:168
+ * #3 <signal handler called>
+ * #4 0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0
+ * #5 0x08048a51 in makeSyscallFromSighandler (ignored=0x0) at threadcrash.c:204
+ * #6 0x006aadec in start_thread () from /lib/tls/libpthread.so.0
+ * #7 0x001ed19a in clone () from /lib/tls/libc.so.6
+ *
+ * Thread 5 (process 4354):
+ * #0 0x001ba7dc in __nanosleep_nocancel () from /lib/tls/libc.so.6
+ * #1 0x001ba5ff in sleep () from /lib/tls/libc.so.6
+ * #2 0x08048936 in syscallingAltSighandler (signo=3, info=0x959cd70, context=0x959cdf0)
+ * at threadcrash.c:144
+ * #3 <signal handler called>
+ * #4 0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0
+ * #5 0x080489e2 in makeSyscallFromAltSighandler (ignored=0x0) at threadcrash.c:190
+ * #6 0x006aadec in start_thread () from /lib/tls/libpthread.so.0
+ * #7 0x001ed19a in clone () from /lib/tls/libc.so.6
+ *
+ * Thread 4 (process 4355):
+ * #0 spin (ignored=0x0) at threadcrash.c:242
+ * #1 0x006aadec in start_thread () from /lib/tls/libpthread.so.0
+ * #2 0x001ed19a in clone () from /lib/tls/libc.so.6
+ *
+ * Thread 3 (process 4356):
+ * #0 spinningSighandler (signo=12, info=0xb4de46f0, context=0xb4de4770) at threadcrash.c:180
+ * #1 <signal handler called>
+ * #2 0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0
+ * #3 0x08048b2f in spinFromSighandler (ignored=0x0) at threadcrash.c:232
+ * #4 0x006aadec in start_thread () from /lib/tls/libpthread.so.0
+ * #5 0x001ed19a in clone () from /lib/tls/libc.so.6
+ *
+ * Thread 2 (process 4357):
+ * #0 spinningAltSighandler (signo=14, info=0x959ee50, context=0x959eed0) at threadcrash.c:156
+ * #1 <signal handler called>
+ * #2 0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0
+ * #3 0x08048ac0 in spinFromAltSighandler (ignored=0x0) at threadcrash.c:218
+ * #4 0x006aadec in start_thread () from /lib/tls/libpthread.so.0
+ * #5 0x001ed19a in clone () from /lib/tls/libc.so.6
+ *
+ * Thread 1 (process 4351):
+ * #0 0x08048cf3 in main (argc=1, argv=0xbfff9d74) at threadcrash.c:273
+ * (gdb)
+ */
+
+#include <pthread.h>
+#include <signal.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define SIGSYSCALL_ALT SIGQUIT
+#define SIGSYSCALL SIGUSR1
+#define SIGSPIN_ALT SIGALRM
+#define SIGSPIN SIGUSR2
+
+typedef void (*sigaction_t)(int, siginfo_t *, void *);
+
+static void installHandler(int signo, sigaction_t handler, int onAltstack) {
+ struct sigaction action;
+ sigset_t sigset;
+ int result;
+ stack_t altstack;
+ stack_t oldaltstack;
+
+ memset(&action, 0, sizeof(action));
+ memset(&altstack, 0, sizeof(altstack));
+ memset(&oldaltstack, 0, sizeof(oldaltstack));
+
+ if (onAltstack) {
+ altstack.ss_sp = malloc(SIGSTKSZ);
+ assert(altstack.ss_sp != NULL);
+ altstack.ss_size = SIGSTKSZ;
+ altstack.ss_flags = 0;
+ result = sigaltstack(&altstack, &oldaltstack);
+ assert(result == 0);
+ assert(oldaltstack.ss_flags == SS_DISABLE);
+ }
+
+ sigemptyset(&sigset);
+
+ action.sa_handler = NULL;
+ action.sa_sigaction = handler;
+ action.sa_mask = sigset;
+ action.sa_flags = SA_SIGINFO;
+ if (onAltstack) {
+ action.sa_flags |= SA_ONSTACK;
+ }
+
+ result = sigaction(signo, &action, NULL);
+ assert(result == 0);
+}
+
+static void installNormalHandler(int signo, sigaction_t handler) {
+ installHandler(signo, handler, 0);
+}
+
+static void installAlthandler(int signo, sigaction_t handler) {
+ installHandler(signo, handler, 1);
+}
+
+static void *makeSyscall(void *ignored) {
+ (void)ignored;
+
+ sleep(42);
+
+ fprintf(stderr, "%s: returning\n", __FUNCTION__);
+ return NULL;
+}
+
+/* Return true if we're currently executing on the altstack */
+static int onAltstack(void) {
+ stack_t stack;
+ int result;
+
+ result = sigaltstack(NULL, &stack);
+ assert(result == 0);
+
+ return stack.ss_flags & SS_ONSTACK;
+}
+
+static void syscallingAltSighandler(int signo, siginfo_t *info, void *context) {
+ (void)signo;
+ (void)info;
+ (void)context;
+
+ if (!onAltstack()) {
+ printf("%s() not running on altstack!\n", __FUNCTION__);
+ }
+
+ sleep(42);
+}
+
+static void spinningAltSighandler(int signo, siginfo_t *info, void *context) {
+ (void)signo;
+ (void)info;
+ (void)context;
+
+ if (!onAltstack()) {
+ printf("%s() not running on altstack!\n", __FUNCTION__);
+ }
+
+ while (1);
+}
+
+static void syscallingSighandler(int signo, siginfo_t *info, void *context) {
+ (void)signo;
+ (void)info;
+ (void)context;
+
+ if (onAltstack()) {
+ printf("%s() running on altstack!\n", __FUNCTION__);
+ }
+
+ sleep(42);
+}
+
+static void spinningSighandler(int signo, siginfo_t *info, void *context) {
+ (void)signo;
+ (void)info;
+ (void)context;
+
+ if (onAltstack()) {
+ printf("%s() running on altstack!\n", __FUNCTION__);
+ }
+
+ while (1);
+}
+
+static void *makeSyscallFromAltSighandler(void *ignored) {
+ (void)ignored;
+
+ int result;
+
+ installAlthandler(SIGSYSCALL_ALT, syscallingAltSighandler);
+
+ result = pthread_kill(pthread_self(), SIGSYSCALL_ALT);
+ assert(result == 0);
+
+ fprintf(stderr, "%s: returning\n", __FUNCTION__);
+ return NULL;
+}
+
+static void *makeSyscallFromSighandler(void *ignored) {
+ (void)ignored;
+
+ int result;
+
+ installNormalHandler(SIGSYSCALL, syscallingSighandler);
+
+ result = pthread_kill(pthread_self(), SIGSYSCALL);
+ assert(result == 0);
+
+ fprintf(stderr, "%s: returning\n", __FUNCTION__);
+ return NULL;
+}
+
+static void *spinFromAltSighandler(void *ignored) {
+ (void)ignored;
+
+ int result;
+
+ installAlthandler(SIGSPIN_ALT, spinningAltSighandler);
+
+ result = pthread_kill(pthread_self(), SIGSPIN_ALT);
+ assert(result == 0);
+
+ fprintf(stderr, "%s: returning\n", __FUNCTION__);
+ return NULL;
+}
+
+static void *spinFromSighandler(void *ignored) {
+ (void)ignored;
+
+ int result;
+
+ installNormalHandler(SIGSPIN, spinningSighandler);
+
+ result = pthread_kill(pthread_self(), SIGSPIN);
+ assert(result == 0);
+
+ fprintf(stderr, "%s: returning\n", __FUNCTION__);
+ return NULL;
+}
+
+static void *spin(void *ignored) {
+ (void)ignored;
+
+ while (1);
+
+ fprintf(stderr, "%s: returning\n", __FUNCTION__);
+ return NULL;
+}
+
+int main(int argc, char *argv[]) {
+ int result;
+ pthread_t thread;
+ volatile int bad;
+
+ result = pthread_create(&thread, NULL, makeSyscall, NULL);
+ assert(result == 0);
+ result = pthread_create(&thread, NULL, makeSyscallFromSighandler, NULL);
+ assert(result == 0);
+ result = pthread_create(&thread, NULL, makeSyscallFromAltSighandler, NULL);
+ assert(result == 0);
+ result = pthread_create(&thread, NULL, spin, NULL);
+ assert(result == 0);
+ result = pthread_create(&thread, NULL, spinFromSighandler, NULL);
+ assert(result == 0);
+ result = pthread_create(&thread, NULL, spinFromAltSighandler, NULL);
+ assert(result == 0);
+
+ // Give threads some time to get going
+ sleep(3);
+
+ // Crash
+ bad = *(int*)7;
+
+ /* Workaround: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29628
+ Simulate use to ensure `DW_AT_location' for them:
+ readelf -a --debug threadcrash|grep -A5 -w argc
+ --> DW_AT_location : 2 byte block: 71 0 (DW_OP_breg1: 0)
+ This case verified on: gcc-4.1.1-30.i386
+ Keep it late to ensure persistency in the registers. */
+ bad = (int) argc;
+ bad = (unsigned long) argv;
+
+ return 0;
+}
Index: ./gdb/testsuite/gdb.threads/threadcrash.exp
===================================================================
RCS file: gdb/testsuite/gdb.threads/threadcrash.exp
diff -N gdb/testsuite/gdb.threads/threadcrash.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.threads/threadcrash.exp 31 Oct 2006 17:54:38 -0000
@@ -0,0 +1,37 @@
+# threadcrash.exp - The point of this program is to crash in a multi-threaded app.
+
+
+set testfile threadcrash
+set srcfile ${testfile}.c
+set shellfile ${srcdir}/${subdir}/${testfile}.sh
+set binfile ${objdir}/${subdir}/${testfile}
+
+set GDB_abs ${GDB}
+if [regexp "^\[^/\]" ${GDB_abs}] {
+ set GDB_abs $env(PWD)/${GDB_abs}
+}
+
+if [istarget "*-*-linux"] then {
+ set target_cflags "-D_MIT_POSIX_THREADS"
+} else {
+ set target_cflags ""
+}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ return -1
+}
+
+# ${shellfile} argument must not contain any directories.
+set fd [open "|bash ${shellfile} ${binfile} $GDB -nw $GDBFLAGS" r]
+while { [gets $fd line] >= 0 } {
+ if [regexp " PASS: (.*)$" $line trash message] {
+ pass $message
+ } elseif [regexp " FAIL: (.*)$" $line trash message] {
+ fail $message
+ }
+}
+catch {
+ close $fd
+}
+
+return 0
Index: ./gdb/testsuite/gdb.threads/threadcrash.sh
===================================================================
RCS file: gdb/testsuite/gdb.threads/threadcrash.sh
diff -N gdb/testsuite/gdb.threads/threadcrash.sh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.threads/threadcrash.sh 31 Oct 2006 17:54:38 -0000
@@ -0,0 +1,324 @@
+#! /bin/bash
+
+# NOTE: threadcrash.c *must* be built with debugging symbols
+#
+# The point of this shell script is to crash treadcrash.c, load the
+# resulting core file into gdb and verify that gdb can extract enough
+# information from the core file.
+#
+# The return code from this script is the number of failed tests.
+
+LOG=gdbresult.log
+
+if [ $# = 0 ] ; then
+ echo >&2 Syntax: $0 \<name of threadcrash binary\> [\<gdb binary\> \<args...\>]
+ exit 1
+fi
+RUNME="$1"
+shift
+GDB="${*:-gdb}"
+
+
+pf_prefix=""
+function pf_prefix() {
+ pf_prefix="$*"
+}
+
+set_test=""
+function set_test() {
+ if [ -n "$set_test" ] ; then
+ echo >&2 "DEJAGNU-BASH ERROR: set_test already set"
+ exit 1
+ fi
+ set_test="$*"
+ if [ -n "$pf_prefix" ] ; then
+ set_test="$pf_prefix: $set_test"
+ fi
+}
+
+# INTERNAL
+function record_test {
+ if [ -z "$set_test" ] ; then
+ echo >&2 "DEJAGNU-BASH ERROR: set_test not set"
+ exit 1
+ fi
+ # Provide the leading whitespace delimiter:
+ echo " $1: $set_test"
+ set_test=""
+}
+
+function pass() {
+ record_test PASS
+}
+function fail() {
+ record_test FAIL
+}
+
+
+# Verify that the gdb output doesn't contain $1.
+function mustNotHave() {
+ local BADWORD=$1
+ set_test gdb output contains "$BADWORD"
+ if grep -q "$BADWORD" $LOG ; then
+ fail
+ return 1
+ fi
+ pass
+ return 0
+}
+
+# Verify that the gdb output contains exactly $1 $2s.
+function mustHaveCorrectAmount() {
+ local WANTEDNUMBER=$1
+ local GOODWORD=$2
+ local ACTUALNUMBER=$(grep "$GOODWORD" $LOG | wc -l)
+ set_test gdb output contained $ACTUALNUMBER \""$GOODWORD"\", not $WANTEDNUMBER as expected
+ if [ $ACTUALNUMBER != $WANTEDNUMBER ] ; then
+ fail
+ return 1
+ fi
+ pass
+ return 0
+}
+
+# Verify that the gdb output contains seven threads
+function mustHaveSevenThreads() {
+ NTHREADS=$(egrep "^Thread [1-7] \(" $LOG | wc -l)
+ set_test gdb output contains $NTHREADS threads, not 7 as expected
+ if [ $NTHREADS != 7 ] ; then
+ fail
+ return 1
+ fi
+ pass
+ return 0
+}
+
+# Verify that the gdb output has all parameters on consecutive lines
+function mustHaveSequence() {
+ SEQUENCE="$*"
+ NPARTS=$#
+ grep "$1" -A$((NPARTS - 1)) $LOG > matches.log
+
+ while [ $# -gt 1 ] ; do
+ shift
+ ((NPARTS--))
+ grep "$1" -A$((NPARTS - 1)) matches.log > temp.log
+ mv temp.log matches.log
+ done
+ LASTPART=$1
+
+ set_test gdb output does not contain the sequence: $SEQUENCE
+ if ! grep -q "$LASTPART" matches.log ; then
+ fail
+ return 1
+ fi
+ pass
+ return 0
+}
+
+# Verify that $LOG contains all information we want
+function verifyLog() {
+ local FAILURES=0
+
+ mustNotHave '??' || ((FAILURES++))
+ mustHaveCorrectAmount 12 threadcrash.c: || ((FAILURES++))
+
+ mustHaveSevenThreads || ((FAILURES++))
+ mustHaveSequence sleep "makeSyscall (ignored=" || ((FAILURES++))
+
+ mustHaveSequence sleep "syscallingSighandler (signo=" "signal handler called" 0x || ((FAILURES++))
+ mustHaveSequence pthread_kill "makeSyscallFromSighandler (ignored=" || ((FAILURES++))
+
+ mustHaveSequence sleep "syscallingAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++))
+ mustHaveSequence pthread_kill "makeSyscallFromAltSighandler (ignored=" || ((FAILURES++))
+
+ mustHaveSequence Thread "spin (ignored=" || ((FAILURES++))
+
+ mustHaveSequence "spinningSighandler (signo=" "signal handler called" 0x || ((FAILURES++))
+ mustHaveSequence pthread_kill "spinFromSighandler (ignored=" || ((FAILURES++))
+
+ mustHaveSequence "spinningAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++))
+ mustHaveSequence pthread_kill "spinFromAltSighandler (ignored=" || ((FAILURES++))
+
+ mustHaveSequence Thread "main (argc=1, argv=" || ((FAILURES++))
+
+ return $FAILURES
+}
+
+# Put result of debugging a core file in $LOG
+function getLogFromCore() {
+ # Make sure we get a core file
+ set_test Make sure we get a core file
+ if ! ulimit -c unlimited ; then
+ fail
+ exit 1
+ fi
+ pass
+
+ # Run the crasher
+ ./$(basename "$RUNME")
+ EXITCODE=$?
+
+ # Verify that we actually crashed
+ set_test $RUNME should have been killed by a signal, got non-signal exit code $EXITCODE
+ if [ $EXITCODE -lt 128 ] ; then
+ fail
+ exit 1
+ fi
+ pass
+
+ # Verify that we got a core file
+ set_test $RUNME did not create a core file
+ if [ ! -r core* ] ; then
+ fail
+ exit 1
+ fi
+ pass
+
+ # Run gdb
+ cat > gdbscript.gdb <<EOF
+set width 0
+t a a bt 100
+quit
+EOF
+ cat gdbscript.gdb /dev/zero | $GDB -nx "./$(basename "$RUNME")" core* > $LOG
+ EXITCODE=$?
+
+ set_test gdb exited with error code
+ if [ $EXITCODE != 0 ] ; then
+ ((FAILURES++))
+ echo >&2 gdb exited with error code $EXITCODE
+ fail
+ fi
+ pass
+}
+
+# Put result of debugging a gcore file in $LOG
+function getLogFromGcore() {
+ # Create the core file
+ rm -f core*
+ cat > gdbscript.gdb <<EOF
+handle SIGQUIT pass noprint nostop
+handle SIGUSR1 pass noprint nostop
+handle SIGUSR2 pass noprint nostop
+handle SIGALRM pass noprint nostop
+run
+gcore
+quit
+EOF
+ cat gdbscript.gdb /dev/zero | $GDB -nx "./$(basename "$RUNME")" > /dev/null
+ EXITCODE=$?
+
+ set_test gdb exited with error code when creating gcore file
+ if [ $EXITCODE != 0 ] ; then
+ ((FAILURES++))
+ echo >&2 gdb exited with error code $EXITCODE when creating gcore file
+ fail
+ fi
+ pass
+
+ # Verify that we got a core file from gcore
+ set_test gdb gcore did not create a core file
+ if [ ! -r core* ] ; then
+ fail
+ exit 1
+ fi
+ pass
+
+ # Run gdb on the gcore file
+ cat > gdbscript.gdb <<EOF
+set width 0
+t a a bt 100
+quit
+EOF
+ cat gdbscript.gdb /dev/zero | $GDB -nx "./$(basename "$RUNME")" core* > $LOG
+ EXITCODE=$?
+
+ set_test gdb exited with error code when examining gcore file
+ if [ $EXITCODE != 0 ] ; then
+ ((FAILURES++))
+ echo >&2 gdb exited with error code $EXITCODE when examining gcore file
+ fail
+ fi
+ pass
+}
+
+# Put result of debugging a core file in $LOG
+function getLogFromLiveProcess() {
+ # Run gdb
+ cat > gdbscript.gdb <<EOF
+handle SIGQUIT pass noprint nostop
+handle SIGUSR1 pass noprint nostop
+handle SIGUSR2 pass noprint nostop
+handle SIGALRM pass noprint nostop
+set width 0
+run
+t a a bt 100
+quit
+EOF
+ cat gdbscript.gdb /dev/zero | $GDB -nx "./$(basename "$RUNME")" > $LOG
+ EXITCODE=$?
+
+ set_test gdb exited with error code
+ if [ $EXITCODE != 0 ] ; then
+ ((FAILURES++))
+ echo >&2 gdb exited with error code $EXITCODE
+ fail
+ fi
+ pass
+}
+
+####### Main program follows #####################
+
+# Make sure we don't clobber anybody else's (core) file(s)
+WORKDIR=/tmp/$PPID
+mkdir -p $WORKDIR
+cp "$RUNME" $WORKDIR
+cd $WORKDIR
+
+# Count problems
+FAILURES=0
+
+echo === Testing gdb vs core file...
+pf_prefix core file
+getLogFromCore
+verifyLog
+((FAILURES+=$?))
+pf_prefix
+echo === Core file tests done.
+
+echo
+
+echo === Testing gdb vs gcore file...
+pf_prefix gcore file
+getLogFromGcore
+verifyLog
+((FAILURES+=$?))
+pf_prefix
+echo === Gcore file tests done.
+
+echo
+
+echo === Testing gdb vs live process...
+pf_prefix live process
+getLogFromLiveProcess
+verifyLog
+((FAILURES+=$?))
+pf_prefix
+echo === Live process tests done.
+
+# Executive summary
+echo
+if [ $FAILURES == 0 ] ; then
+ echo All tests passed!
+else
+ echo $FAILURES tests failed!
+ echo
+ echo Make sure the threadcrash binary contains debugging information \(build with \"gcc -g\"\).
+fi
+
+# Clean up
+cd /
+rm -rf $WORKDIR
+
+exit $FAILURES
Index: ./gdb/testsuite/gdb.threads/threadcrash.sh-orig
===================================================================
RCS file: gdb/testsuite/gdb.threads/threadcrash.sh-orig
diff -N gdb/testsuite/gdb.threads/threadcrash.sh-orig
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.threads/threadcrash.sh-orig 31 Oct 2006 17:54:38 -0000
@@ -0,0 +1,248 @@
+#! /bin/bash
+
+# NOTE: threadcrash.c *must* be built with debugging symbols
+#
+# The point of this shell script is to crash treadcrash.c, load the
+# resulting core file into gdb and verify that gdb can extract enough
+# information from the core file.
+#
+# The return code from this script is the number of failed tests.
+
+LOG=gdbresult.log
+
+if [ $# != 1 ] ; then
+ echo > /dev/stderr Syntax: $0 \<name of threadcrash binary\>
+ exit 1
+fi
+RUNME="$1"
+
+# Verify that the gdb output doesn't contain $1.
+function mustNotHave() {
+ local BADWORD=$1
+ if grep -q "$BADWORD" $LOG ; then
+ echo >> /dev/stderr WARNING: gdb output contains "$BADWORD"
+ return 1
+ fi
+ return 0
+}
+
+# Verify that the gdb output contains exactly $1 $2s.
+function mustHaveCorrectAmount() {
+ local WANTEDNUMBER=$1
+ local GOODWORD=$2
+ local ACTUALNUMBER=$(grep "$GOODWORD" $LOG | wc -l)
+ if [ $ACTUALNUMBER != $WANTEDNUMBER ] ; then
+ echo >> /dev/stderr WARNING: gdb output contained $ACTUALNUMBER \""$GOODWORD"\", not $WANTEDNUMBER as expected
+ return 1
+ fi
+ return 0
+}
+
+# Verify that the gdb output contains seven threads
+function mustHaveSevenThreads() {
+ NTHREADS=$(egrep "^Thread [1-7] \(" $LOG | wc -l)
+ if [ $NTHREADS != 7 ] ; then
+ echo >> /dev/stderr WARNING: gdb output contains $NTHREADS threads, not 7 as expected
+ return 1
+ fi
+ return 0
+}
+
+# Verify that the gdb output has all parameters on consecutive lines
+function mustHaveSequence() {
+ SEQUENCE="$*"
+ NPARTS=$#
+ grep "$1" -A$((NPARTS - 1)) $LOG > matches.log
+
+ while [ $# -gt 1 ] ; do
+ shift
+ ((NPARTS--))
+ grep "$1" -A$((NPARTS - 1)) matches.log > temp.log
+ mv temp.log matches.log
+ done
+ LASTPART=$1
+
+ if ! grep -q "$LASTPART" matches.log ; then
+ echo >> /dev/stderr WARNING: gdb output does not contain the sequence: $SEQUENCE
+ return 1
+ fi
+ return 0
+}
+
+# Verify that $LOG contains all information we want
+function verifyLog() {
+ local FAILURES=0
+
+ mustNotHave '??' || ((FAILURES++))
+ mustHaveCorrectAmount 12 threadcrash.c: || ((FAILURES++))
+
+ mustHaveSevenThreads || ((FAILURES++))
+ mustHaveSequence sleep "makeSyscall (ignored=" || ((FAILURES++))
+
+ mustHaveSequence sleep "syscallingSighandler (signo=" "signal handler called" 0x || ((FAILURES++))
+ mustHaveSequence pthread_kill "makeSyscallFromSighandler (ignored=" || ((FAILURES++))
+
+ mustHaveSequence sleep "syscallingAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++))
+ mustHaveSequence pthread_kill "makeSyscallFromAltSighandler (ignored=" || ((FAILURES++))
+
+ mustHaveSequence Thread "spin (ignored=" || ((FAILURES++))
+
+ mustHaveSequence "spinningSighandler (signo=" "signal handler called" 0x || ((FAILURES++))
+ mustHaveSequence pthread_kill "spinFromSighandler (ignored=" || ((FAILURES++))
+
+ mustHaveSequence "spinningAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++))
+ mustHaveSequence pthread_kill "spinFromAltSighandler (ignored=" || ((FAILURES++))
+
+ mustHaveSequence Thread "main (argc=1, argv=" || ((FAILURES++))
+
+ return $FAILURES
+}
+
+# Put result of debugging a core file in $LOG
+function getLogFromCore() {
+ # Make sure we get a core file
+ ulimit -c unlimited || exit 1
+
+ # Run the crasher
+ ./$(basename "$RUNME")
+ EXITCODE=$?
+
+ # Verify that we actually crashed
+ if [ $EXITCODE -lt 128 ] ; then
+ echo >> /dev/stderr ERROR: $RUNME should have been killed by a signal, got non-signal exit code $EXITCODE
+ exit 1
+ fi
+
+ # Verify that we got a core file
+ if [ ! -r core* ] ; then
+ echo >> /dev/stderr ERROR: $RUNME did not create a core file
+ exit 1
+ fi
+
+ # Run gdb
+ cat > gdbscript.gdb <<EOF
+set width 0
+t a a bt 100
+quit
+EOF
+ cat gdbscript.gdb /dev/zero | gdb -nx "./$(basename "$RUNME")" core* > $LOG
+ EXITCODE=$?
+
+ if [ $EXITCODE != 0 ] ; then
+ ((FAILURES++))
+ echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE
+ fi
+}
+
+# Put result of debugging a gcore file in $LOG
+function getLogFromGcore() {
+ # Create the core file
+ rm -f core*
+ cat > gdbscript.gdb <<EOF
+handle SIGQUIT pass noprint nostop
+handle SIGUSR1 pass noprint nostop
+handle SIGUSR2 pass noprint nostop
+handle SIGALRM pass noprint nostop
+run
+gcore
+quit
+EOF
+ cat gdbscript.gdb /dev/zero | gdb -nx "./$(basename "$RUNME")" > /dev/null
+ EXITCODE=$?
+
+ if [ $EXITCODE != 0 ] ; then
+ ((FAILURES++))
+ echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE when creating gcore file
+ fi
+
+ # Verify that we got a core file from gcore
+ if [ ! -r core* ] ; then
+ echo >> /dev/stderr ERROR: gdb gcore did not create a core file
+ exit 1
+ fi
+
+ # Run gdb on the gcore file
+ cat > gdbscript.gdb <<EOF
+set width 0
+t a a bt 100
+quit
+EOF
+ cat gdbscript.gdb /dev/zero | gdb -nx "./$(basename "$RUNME")" core* > $LOG
+ EXITCODE=$?
+
+ if [ $EXITCODE != 0 ] ; then
+ ((FAILURES++))
+ echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE when examining gcore file
+ fi
+}
+
+# Put result of debugging a core file in $LOG
+function getLogFromLiveProcess() {
+ # Run gdb
+ cat > gdbscript.gdb <<EOF
+handle SIGQUIT pass noprint nostop
+handle SIGUSR1 pass noprint nostop
+handle SIGUSR2 pass noprint nostop
+handle SIGALRM pass noprint nostop
+set width 0
+run
+t a a bt 100
+quit
+EOF
+ cat gdbscript.gdb /dev/zero | gdb -nx "./$(basename "$RUNME")" > $LOG
+ EXITCODE=$?
+
+ if [ $EXITCODE != 0 ] ; then
+ ((FAILURES++))
+ echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE
+ fi
+}
+
+####### Main program follows #####################
+
+# Make sure we don't clobber anybody else's (core) file(s)
+WORKDIR=/tmp/$PPID
+mkdir -p $WORKDIR
+cp "$RUNME" $WORKDIR
+cd $WORKDIR
+
+# Count problems
+FAILURES=0
+
+echo === Testing gdb vs core file...
+getLogFromCore
+verifyLog
+((FAILURES+=$?))
+echo === Core file tests done.
+
+echo
+
+echo === Testing gdb vs gcore file...
+getLogFromGcore
+verifyLog
+((FAILURES+=$?))
+echo === Gcore file tests done.
+
+echo
+
+echo === Testing gdb vs live process...
+getLogFromLiveProcess
+verifyLog
+((FAILURES+=$?))
+echo === Live process tests done.
+
+# Executive summary
+echo
+if [ $FAILURES == 0 ] ; then
+ echo All tests passed!
+else
+ echo $FAILURES tests failed!
+ echo
+ echo Make sure the threadcrash binary contains debugging information \(build with \"gcc -g\"\).
+fi
+
+# Clean up
+cd /
+rm -rf $WORKDIR
+
+exit $FAILURES

143
gdb-6.5-relativedebug.patch Normal file
View File

@ -0,0 +1,143 @@
2006-10-29 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb/symtab.c (matching_bfd_sections): Fix VMA matching for objects
loaded at a different address than stored on the disk.
2006-10-29 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/relativedebug.c, gdb.base/relativedebug.exp: New file,
resolving of PC in libc pause(3) (with possibly different on-disk VMA).
Index: ./gdb/symtab.c
===================================================================
--- ./gdb/symtab.c 17 Oct 2006 20:17:44 -0000 1.148
+++ ./gdb/symtab.c 29 Oct 2006 22:29:21 -0000
@@ -739,8 +739,11 @@ matching_bfd_sections (asection *first,
if (bfd_get_section_size (first) != bfd_get_section_size (second))
return 0;
+ /* In-memory addresses may start at a different offset, relativize them. */
if (bfd_get_section_vma (first->owner, first)
- != bfd_get_section_vma (second->owner, second))
+ - bfd_get_start_address (first->owner)
+ != bfd_get_section_vma (second->owner, second)
+ - bfd_get_start_address (second->owner))
return 0;
if (bfd_get_section_name (first->owner, first) == NULL
Index: ./gdb/testsuite/gdb.base/relativedebug.c
===================================================================
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.base/relativedebug.c 29 Oct 2006 22:29:21 -0000
@@ -0,0 +1,37 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2006 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+
+
+static void handler (int signo)
+{
+ abort ();
+}
+
+int main (void)
+{
+ signal (SIGALRM, handler);
+ alarm (1);
+ pause ();
+ pause ();
+ return 0;
+}
Index: ./gdb/testsuite/gdb.base/relativedebug.exp
===================================================================
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.base/relativedebug.exp 29 Oct 2006 22:29:21 -0000
@@ -0,0 +1,68 @@
+# Copyright 2006 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile relativedebug
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# pause () -> SIGALRM -> handler () -> abort ()
+
+gdb_test "run" \
+ ".*Program received signal SIGABRT, Aborted..*" \
+ "run"
+
+# incorrect (#6):
+# (gdb) bt
+# #0 0x00325402 in __kernel_vsyscall ()
+# #1 0x00718f20 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
+# #2 0x0071a801 in *__GI_abort () at abort.c:88
+# #3 0x0804841f in handler (signo=14) at ./gdb.base/relativedebug.c:27
+# #4 <signal handler called>
+# #5 0x00325402 in __kernel_vsyscall ()
+# #6 0x0077ebc6 in ?? () from /lib/i686/nosegneg/libc.so.6
+# #7 0x08048455 in main () at ./gdb.base/relativedebug.c:34
+# (gdb)
+
+# correct (#6):
+# (gdb) bt
+# #0 0x00b33402 in __kernel_vsyscall ()
+# #1 0x00718f20 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
+# #2 0x0071a801 in *__GI_abort () at abort.c:88
+# #3 0x0804841f in handler (signo=14) at ./gdb.base/relativedebug.c:27
+# #4 <signal handler called>
+# #5 0x00b33402 in __kernel_vsyscall ()
+# #6 0x0077ebc6 in __pause_nocancel () from /lib/i686/nosegneg/libc.so.6
+# #7 0x08048455 in main () at ./gdb.base/relativedebug.c:34
+# (gdb)
+
+gdb_test "bt" \
+ ".*\[^a-zA-Z\]pause\[^a-zA-Z\].*" \
+ "pause(3) seen there"

View File

@ -0,0 +1,195 @@
2006-10-30 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb/minsyms.c (lookup_minimal_symbol_by_pc_section): Handle
overlapping non-zero sized functions (for glibc `__nanosleep').
2006-10-30 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.arch/i386-size-overlap.c, gdb.arch/i386-size-overlap.exp: New
file, provide nested (overlapping) functions for the PC resolving.
--- gdb-6.5/gdb/minsyms.c-orig 2006-10-31 08:21:32.000000000 -0500
+++ gdb-6.5/gdb/minsyms.c 2006-10-31 08:24:37.000000000 -0500
@@ -464,6 +464,7 @@
objfile's minimal symbol table. See if it is the best one
overall. */
+ while (0
/* Skip any absolute symbols. This is apparently what adb
and dbx do, and is needed for the CM-5. There are two
known possible problems: (1) on ELF, apparently end, edata,
@@ -473,8 +474,27 @@
NeXT are absolute. If we want special handling for this
it probably should be triggered by a special
mst_abs_or_lib or some such. */
- while (hi >= 0
- && msymbol[hi].type == mst_abs)
+ || (hi >= 0
+ && msymbol[hi].type == mst_abs)
+ /* We are behind the current symbol's size.
+ Try the previous symbol - if it is non-zero sized one it
+ may overlap the current one and reach our PC.
+ It occurs for GNU/Linux glibc `__nanosleep' overlapping
+ later `__nanosleep_nocancel' with PC at 0077ec66:
+ Num: Value Size Type Bind Vis Ndx Name
+ 7247: 0077ec20 124 FUNC WEAK DEFAULT 11 __nanosleep
+ 4651: 0077ec2a 32 FUNC LOCAL DEFAULT 11 __nanosleep_nocancel
+ Test `gdb.arch/i386-size' + `gdb.arch/i386-unwind'.
+ Limit it only for the overlapping cases as we could harm
+ the zero-sized symbols detection logic around.
+ */
+ || (hi > 0
+ && MSYMBOL_SIZE (&msymbol[hi]) != 0
+ && pc >= (SYMBOL_VALUE_ADDRESS (&msymbol[hi])
+ + MSYMBOL_SIZE (&msymbol[hi]))
+ && pc < (SYMBOL_VALUE_ADDRESS (&msymbol[hi - 1])
+ + MSYMBOL_SIZE (&msymbol[hi - 1])))
+ )
--hi;
/* If "section" specified, skip any symbol from wrong section */
Index: ./gdb/testsuite/gdb.arch/i386-size-overlap.c
===================================================================
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.arch/i386-size-overlap.c 30 Oct 2006 12:41:35 -0000
@@ -0,0 +1,53 @@
+/* Overlapping symbol sizes test program.
+
+ Copyright 2006 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifdef SYMBOL_PREFIX
+#define SYMBOL(str) SYMBOL_PREFIX #str
+#else
+#define SYMBOL(str) #str
+#endif
+
+void
+trap (void)
+{
+ asm ("int $0x03");
+}
+
+/* Jump from a function with its symbol size set, to a function
+ named by a local label. GDB should report the `main' function
+ even for the rest, after the global `inner' ends. */
+
+asm(".text\n"
+ " .align 8\n"
+ " .globl " SYMBOL (main) "\n"
+ SYMBOL (main) ":\n"
+ " pushl %ebp\n"
+ " mov %esp, %ebp\n"
+ " call .Lfunc\n"
+ " ret\n"
+ SYMBOL (inner) ":\n"
+ " ret\n"
+ " .size " SYMBOL (inner) ", .-" SYMBOL (inner) "\n"
+ ".Lfunc:\n"
+ " pushl %ebp\n"
+ " mov %esp, %ebp\n"
+ " call " SYMBOL (trap) "\n"
+ " .size " SYMBOL (main) ", .-" SYMBOL (main) "\n");
Index: ./gdb/testsuite/gdb.arch/i386-size-overlap.exp
===================================================================
RCS file: gdb/testsuite/gdb.arch/i386-size-overlap.exp
diff -N gdb/testsuite/gdb.arch/i386-size-overlap.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.arch/i386-size-overlap.exp 30 Oct 2006 12:41:35 -0000
@@ -0,0 +1,79 @@
+# Copyright 2006 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+# Test that GDB can handle overlapping sizes of symbols.
+
+if ![istarget "i?86-*-*"] then {
+ verbose "Skipping i386 unwinder tests."
+ return
+}
+
+set testfile "i386-size-overlap"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# some targets have leading underscores on assembly symbols.
+# TODO: detect this automatically
+set additional_flags ""
+if [istarget "i?86-*-cygwin*"] then {
+ set additional_flags "additional_flags=-DSYMBOL_PREFIX=\"_\""
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+ executable [list debug $additional_flags]] != "" } {
+ untested "i386-size"
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# We use gdb_run_cmd so this stands a chance to work for remote
+# targets too.
+gdb_run_cmd
+
+gdb_expect {
+ -re "Program received signal SIGTRAP.*$gdb_prompt $" {
+ pass "run past main"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "run past main"
+ }
+ timeout {
+ fail "run past main (timeout)"
+ }
+}
+
+set message "backtrace shows the outer function"
+gdb_test_multiple "backtrace 10" $message {
+ -re "#1\[ \t]*$hex in inner.*$gdb_prompt $" {
+ fail $message
+ }
+ -re "#1\[ \t]*$hex in main.*$gdb_prompt $" {
+ pass $message
+ }
+}

View File

@ -11,7 +11,7 @@ Name: gdb
Version: 6.5
# The release always contains a leading reserved number, start it at 0.
Release: 13%{?dist}
Release: 14%{?dist}
License: GPL
Group: Development/Debuggers
@ -286,6 +286,17 @@ Patch201: gdb-6.5-gcore-i386-on-amd64.patch
# Fix deadlock accessing last address space byte; for corrupted backtraces.
Patch203: gdb-6.5-last-address-space-byte.patch
# Fix "??" resolving of symbols from (non-prelinked) debuginfo packages.
# "gdb-6.5-matching_bfd_sections.patch" is a prerequisited CVS backport.
Patch205: gdb-6.5-matching_bfd_sections.patch
Patch206: gdb-6.5-relativedebug.patch
# Fix "??" resolving of symbols from overlapping functions (nanosleep(3)).
Patch207: gdb-6.5-symbols-overlap.patch
# Improved testsuite results by the testsuite provided by the courtesy of BEA.
Patch208: gdb-6.5-BEA-testsuite.patch
BuildRequires: ncurses-devel glibc-devel gcc make gzip texinfo dejagnu gettext
BuildRequires: flex bison sharutils
@ -399,6 +410,10 @@ and printing their data.
%patch200 -p1
%patch201 -p1
%patch203 -p1
%patch205 -p1
%patch206 -p1
%patch207 -p1
%patch208 -p1
# Change the version that gets printed at GDB startup, so it is RedHat
# specific.
@ -476,7 +491,7 @@ echo ====================TESTING=========================
cd gdb/testsuite
# Need to use a single --ignore option, second use overrides first.
# "chng-syms.exp" for possibly avoiding Linux kernel crash - Bug 207002.
make -k check RUNTESTFLAGS='--ignore "bigcore.exp chng-syms.exp"' || :
make -k check RUNTESTFLAGS='--ignore "bigcore.exp chng-syms.exp checkpoint.exp"' || :
for t in sum log; do
ln gdb.$t gdb-%{_target_platform}.$t || :
done
@ -560,6 +575,12 @@ fi
# don't include the files in include, they are part of binutils
%changelog
* Sat Nov 2 2006 Jan Kratochvil <jan.kratochvil@redhat.com> - 6.5-14
- Fix "??" resolving of symbols from (non-prelinked) debuginfo packages.
- Fix "??" resolving of symbols from overlapping functions (nanosleep(3)).
- Also disable testcase "checkpoint.exp" for a possible kernel Bug 207002.
- Improved testsuite results by the testsuite provided by the courtesy of BEA.
* Sat Oct 14 2006 Jan Kratochvil <jan.kratochvil@redhat.com> - 6.5-13
- Fix deadlock accessing last address space byte; for corrupted backtraces.