From: pfieland@citron.sw.stratus.com (Peggy Fieland)
Subject: (none)
Organization: GNUs Not Usenet
Distribution: gnu
Date: Wed, 12 Aug 1992 19:58:33 GMT

Gdb-4.6 segfaults in create_array_type if the element_type passed
to it has a null objfile.   This occurs on gdb-4.6 on Stratus FTX.

Note objfile can be null if the
type is a primitive type created by c-exp.y at initialization time.
In general, this won't occur on  Sun, since Sun uses stabs, and
stabs post the names of the "fundamental types" for an objfile
to the symbol table; however, in the dwarf case, the fundamental
types are handled differently, and c-exp.y ends up passing the
primitive type to create_array_type.

Here is a test program:

struct a_struct
{
 int i;
};

main()
{
int i;
i = 10;

}

Here is a sample debugging session:

GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.6, Copyright 1992 Free Software Foundation, Inc...
(gdb) b main
Breakpoint 1 at 0x229c: file hello.c, line 9.
(gdb) r
Starting program: /tmp_mnt/net/citron/home/citron/pfieland/gdb-4.6/tests/a.out

Breakpoint 1, main () at hello.c:9
9       i = 10;
(gdb) p sizeof(long)
$1 = 4
(gdb) p sizeof(short[3])
Segmentation fault (core dumped)

% gdb gdb46 core
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.5, Copyright 1992 Free Software Foundation, Inc...
Warning: core file may not match specified executable file.
Core was generated by `gdb46'.
Program terminated with signal 11, Segmentation fault.
Cannot access memory at address 0x0.
#0  0x3e454 in create_array_type (element_type=0x148f08, number=3) at ../../../gdb-4.6/gdb/gdbtypes.c:318
../../../gdb-4.6/gdb/gdbtypes.c:318: No such file or directory.
(gdb) directory /net/citron/home/tools/gnu/gdb-4.6/gdb
lSource directories searched: /net/citron/home/tools/gnu/gdb-4.6/gdb:$cdir:$cwd
(gdb) list
313       TYPE_TARGET_TYPE (result_type) = element_type;
314       TYPE_LENGTH (result_type) = number * TYPE_LENGTH (element_type);
315       TYPE_NFIELDS (result_type) = 1;
316       TYPE_FIELDS (result_type) = (struct field *)
317         obstack_alloc (&TYPE_OBJFILE (result_type) -> type_obstack,
318                        sizeof (struct field));
319
320       {
321         /* Create range type.  */
322         range_type = alloc_type (TYPE_OBJFILE (result_type));
(gdb) p *result_type
$1 = {code = TYPE_CODE_ARRAY, name = 0x0, length = 6, objfile = 0x0, target_type = <unknown struct>,
  pointer_type = <unknown struct>, reference_type = <unknown struct>, function_type = <unknown struct>,
  flags = 0, nfields = 1, fields = 0x0, vptr_basetype = <unknown struct>, vptr_fieldno = -1,
  type_specific = {arg_types = 0x0, cplus_stuff = 0x0}}
(gdb) p *element_type
$2 = {code = TYPE_CODE_INT, name = 0x11bfc1 "short", length = 2, objfile = 0x0,
  target_type = <unknown struct>, pointer_type = <unknown struct>, reference_type = <unknown struct>,
  function_type = <unknown struct>, flags = 0, nfields = 0, fields = 0x0, vptr_basetype = <unknown struct>,
  vptr_fieldno = -1, type_specific = {arg_types = 0x0, cplus_stuff = 0x0}}

Here is a fix:

*** /home/tools/gnu/gdb-4.6/gdb/gdbtypes.c	Tue Jul 14 03:34:24 1992
--- gdb-4.6/gdb/gdbtypes.c	Wed Aug 12 10:17:40 1992
***************
*** 313,321 ****
    TYPE_TARGET_TYPE (result_type) = element_type;
    TYPE_LENGTH (result_type) = number * TYPE_LENGTH (element_type);
    TYPE_NFIELDS (result_type) = 1;
!   TYPE_FIELDS (result_type) = (struct field *)
!     obstack_alloc (&TYPE_OBJFILE (result_type) -> type_obstack,
! 		   sizeof (struct field));
  
    {
      /* Create range type.  */
--- 315,329 ----
    TYPE_TARGET_TYPE (result_type) = element_type;
    TYPE_LENGTH (result_type) = number * TYPE_LENGTH (element_type);
    TYPE_NFIELDS (result_type) = 1;
!   /* Peggy Fieland. Sometimes primitive types are passed to this
!      routine, and they have null TYPE_OBJFILEs. */
!   if (TYPE_OBJFILE(result_type) != NULL)
!      TYPE_FIELDS (result_type) = (struct field *)
!         obstack_alloc (&TYPE_OBJFILE (result_type) -> type_obstack,
!                        sizeof (struct field));
!   else
!      TYPE_FIELDS (result_type) = (struct field *)
!         xmalloc(sizeof (struct field));
  
    {
      /* Create range type.  */
***************
*** 327,335 ****
      TYPE_LENGTH (range_type) = sizeof (int);
  
      TYPE_NFIELDS (range_type) = 2;
!     TYPE_FIELDS (range_type) = (struct field *)
!       obstack_alloc (&TYPE_OBJFILE (range_type) -> type_obstack,
! 		     2 * sizeof (struct field));
      TYPE_FIELD_BITPOS (range_type, 0) = 0; /* FIXME */
      TYPE_FIELD_BITPOS (range_type, 1) = number-1; /* FIXME */
      TYPE_FIELD_TYPE (range_type, 0) = builtin_type_int; /* FIXME */
--- 335,348 ----
      TYPE_LENGTH (range_type) = sizeof (int);
  
      TYPE_NFIELDS (range_type) = 2;
!     if (TYPE_OBJFILE(range_type) != NULL)  /* see comment above */
!        TYPE_FIELDS (range_type) = (struct field *)
!           obstack_alloc (&TYPE_OBJFILE (range_type) -> type_obstack,
!                          2 * sizeof (struct field));
!     else
!        TYPE_FIELDS (range_type) = (struct field *)
!           xmalloc(2 * sizeof (struct field));
!        
      TYPE_FIELD_BITPOS (range_type, 0) = 0; /* FIXME */
      TYPE_FIELD_BITPOS (range_type, 1) = number-1; /* FIXME */
      TYPE_FIELD_TYPE (range_type, 0) = builtin_type_int; /* FIXME */

Newsgroups: gnu.gdb.bug