[PATCH] [SH] GDB crash in sh_is_renesas_calling_convention, TYPE_CALLING_CONVENTION (was: Prologue skipping if there is none)

Thomas Schwinge
2012-02-16T15:24:07Z

[-- Attachment #1: Type: text/plain, Size: 4520 bytes --]

Hi!

On Wed, 15 Feb 2012 14:00:15 +0000, Pedro Alves <palves@redhat.com> wrote:
> On 02/15/2012 01:51 PM, Thomas Schwinge wrote:
>
> > First, for SH GNU/Linux, when running the testsuite via gdbserver on
> > pristine sources, I'm getting a large number of ERRORs, in the 350s. Is
> > that normal or at least known? They're basically all of the kind
> > ``ERROR: Process no longer exists'', and then follow-up errors until the
> > end of the specific testcase. From a very quick glance, they all seem to
> > be happening after the testcase has instructed GDB to invoke a function,
> > such as:
> >
> > (gdb) PASS: gdb.cp/classes.exp: print g_D.p
> > call class_param.Aptr_a (&g_A)
> > ERROR: Process no longer exists
> > UNRESOLVED: gdb.cp/classes.exp: call class_param.Aptr_a (&g_A)
> > ERROR: Couldn't send call class_param.Aptr_x (&g_A) to GDB.
> >
> > This probably suggests where to begin looking unless that's know already.
>
> This means that GDB crashed. Just run the test with
>
> $ ulimit -c unlimited
> $ make check RUNTESTFLAGS="classes.exp"
>
> so that the crash ends up creating a core, and you'll probably find that
> all the ERRORs are caused by a single bug.

Indeed:

Core was generated by `sh-linux-gnu-gdb -nw -nx -data-directory /scratch/tschwing/FM_sh-linux-gnu/obj/'.
Program terminated with signal 11, Segmentation fault.
#0 0x0804c239 in sh_is_renesas_calling_convention (func_type=0xa07b154) at /scratch/tschwing/FM_sh-linux-gnu/obj/gdb-src-mainline-0-sh-linux-gnu-i686-pc-linux-gnu/gdb/sh-tdep.c:92
92 return ((func_type
(gdb) print *func_type
$1 = {pointer_type = 0x0, reference_type = 0x0, chain = 0xa07b154, instance_flags = 0, length = 1, main_type = 0xa07b16c}
(gdb) list
87 };
88
89 static int
90 sh_is_renesas_calling_convention (struct type *func_type)
91 {
92 return ((func_type
93 && TYPE_CALLING_CONVENTION (func_type) == DW_CC_GNU_renesas_sh)
94 || sh_active_calling_convention == sh_cc_renesas);
95 }
96

gdb/gdbtypes.h:

#define TYPE_CALLING_CONVENTION(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.func_stuff->calling_convention

(gdb) print *func_type->main_type
$2 = {code = TYPE_CODE_METHOD, flag_unsigned = 0, flag_nosign = 0, flag_stub = 0, flag_target_stub = 0, flag_static = 0, flag_prototyped = 0, flag_incomplete = 0, flag_varargs = 0, flag_vector = 0, flag_stub_supported = 0,
flag_gnu_ifunc = 0, flag_fixed_instance = 0, flag_objfile_owned = 1, flag_declared_class = 0, flag_flag_enum = 0, type_specific_field = TYPE_SPECIFIC_NONE, nfields = 1, vptr_fieldno = 0, name = 0x0, tag_name = 0x0, owner = {
objfile = 0xa0673b8, gdbarch = 0xa0673b8}, target_type = 0xa07a87c, flds_bnds = {fields = 0xa07b1dc, bounds = 0xa07b1dc}, vptr_basetype = 0xa06eea8, type_specific = {cplus_stuff = 0x0, gnat_stuff = 0x0, floatformat = 0x0,
func_stuff = 0x0}}
(gdb) print func_type->main_type->type_specific.func_stuff
$3 = (struct func_type *) 0x0

The cure is the same as has been applied before,
<http://sourceware.org/ml/gdb-patches/2011-11/msg00439.html>.

gdb/
2012-02-16 Thomas Schwinge <thomas@codesourcery.com>

* sh-tdep.c (sh_is_renesas_calling_convention): Fix handling of
TYPE_CALLING_CONVENTION annotation.

Index: gdb/sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.236
diff -u -p -r1.236 sh-tdep.c
--- gdb/sh-tdep.c 28 Jan 2012 18:08:20 -0000 1.236
+++ gdb/sh-tdep.c 16 Feb 2012 15:13:53 -0000
@@ -89,9 +89,24 @@ struct sh_frame_cache
static int
sh_is_renesas_calling_convention (struct type *func_type)
{
- return ((func_type
- && TYPE_CALLING_CONVENTION (func_type) == DW_CC_GNU_renesas_sh)
- || sh_active_calling_convention == sh_cc_renesas);
+ int val = 0;
+
+ if (func_type)
+ {
+ func_type = check_typedef (func_type);
+
+ if (TYPE_CODE (func_type) == TYPE_CODE_PTR)
+ func_type = check_typedef (TYPE_TARGET_TYPE (func_type));
+
+ if (TYPE_CODE (func_type) == TYPE_CODE_FUNC
+ && TYPE_CALLING_CONVENTION (func_type) == DW_CC_GNU_renesas_sh)
+ val = 1;
+ }
+
+ if (sh_active_calling_convention == sh_cc_renesas)
+ val = 1;
+
+ return val;
}

static const char *