[rfa/testsuite] gdb1250.exp, new test script

Michael Elizabeth Chastain
2003-07-15T16:14:02Z

Rats, I said I would do this yesterday. Here it is: a new test script
for PR gdb/1250.

http://sources.redhat.com/gdb/bugs/1250

This is the bug where gdb loses its marbles when backtracing through a
function which calls a noreturn function such as 'abort'. The calling
function has no epilog after the call to 'abort', so when gdb looks at
the frame for that function, gdb sees the first instruction of the
*next* function and uses information for that function instead.

This happens in gdb.base/corefile.exp but I think it is nice to have a
specific test for it.

I tested this on native i686-pc-linux-gnu with gdb HEAD, gcc 2.95.3 and
v3, dwarf-2 and stabs+.

It PASSed with gcc 2.95.3 because gcc 2.95.3 does not optimize away the
epilog. I think that this is okay. The gdb user really just wants to
put breakpoints on things like 'abort' and 'exit' and have it work, and
if it works because the compiler is simple, that is okay.

It KFAILed with all the gcc 3.3's that I used.

I would like to commit this to HEAD, wait a few days or a week, and then
commit it to gdb_6_0-branch.

OK to commit?

Michael C

===

# Copyright 2003 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.

# Tests for PR gdb/1250.
# 2003-07-15 Michael Chastain <mec@shout.net>

# This file is part of the gdb testsuite.

if $tracelevel then {
strace $tracelevel
}

#
# test running programs
#
set prms_id 0
set bug_id 0

set testfile "gdb1250"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}

if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}

gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}

if ![runto abort] then {
perror "couldn't run to breakpoint"
continue
}

# See http://sources.redhat.com/gdb/bugs/1250
#
# In a nutshell: the function 'beta' ends with a call to 'abort', which
# is a noreturn function. So the last instruction of 'beta' is a call
# to 'abort'. When gdb looks for information about the caller of
# 'beta', it looks at the instruction after the call to 'abort' -- which
# is the first instruction of 'alpha'! So gdb uses the wrong frame
# information. It thinks that the test program is in 'alpha' and that
# the prologue "push %ebp / mov %esp,%ebp" has not been executed yet,
# and grabs the wrong values.
#
# By the nature of the bug, it could pass if the C compiler is not smart
# enough to implement 'abort' as a noreturn function. This is okay.
# The real point is that users often put breakpoints on noreturn
# functions such as 'abort' or some kind of exitting function, and those
# breakpoints should work.

gdb_test_multiple "backtrace" "backtrace from abort" {
-re "#0.*abort.*\r\n#1.*beta.*\r\n#2.*alpha.*\r\n#3.*main.*\r\n$gdb_prompt $" {
pass "backtrace from abort"
}
-re "#0.*abort.*\r\n#1.*beta.*\r\n$gdb_prompt $" {
# This happens with gdb HEAD as of 2003-07-13, with gcc 3.3,
# binutils 2.14, either -gdwarf-2 or -gstabs+, on native
# i686-pc-linux-gnu.
#
# gdb gets 'abort' and 'beta' right and then goes into the
# weeds.
kfail "gdb/1250" "backtrace from abort"
}
}

===

/* Test program for stack trace through noreturn function.

Copyright 2003 Free Software Foundation, Inc.

This file is part of the gdb testsuite.

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.

This file was written by Michael Elizabeth Chastain (mec@shout.net). */

#include <stdlib.h>

int global = 0;

void gamma (int *parray)
{
return;
}

void beta ()
{
int array [4];
array [0] = global++;
array [1] = global++;
array [2] = global++;
array [3] = global++;
gamma (array);
abort ();
}

int alpha ()
{
global++;
beta ();
return 0;
}

int main ()
{
int i;
global++;
i = alpha ();
return i;
}