From: eggert@twinsun.COM (Paul Eggert)
Subject: -g doesn't use GDB extensions as advertised (GCC 2.1, SunOS 4.1.2)
Organization: GNUs Not Usenet
Distribution: gnu
Date: Fri, 10 Apr 1992 20:06:10 GMT

GCC 2.1's documentation says that on most systems that use stabs format, `-g'
enables use of extra debugging information that only GDB can use.  But the
actual code in dbxout.c generates this extra info only in certain cases.
Sometimes the extra info isn't generated even though it's needed.  Here is an
example adapted from InterViews, where the extra info isn't generated, and GDB
4.4 dumps core as a result.  This example was run on a sparc with SunOS 4.1.2.

    $ cat u.cc
    class ivResource   {
    public:
	ivResource  ();
	virtual ~ivResource  ();

	void ref() const;

	static void ref(const ivResource  *);

	void Reference() const { ref(); }
    };
    void ivResource::ref() const {}
    main() { return 0; }
    $ gcc -g u.cc
    $ gdb a.out
    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.4, Copyright 1991 Free Software Foundation, Inc...
    (gdb) b main
    Memory fault - core dumped

GDB shouldn't dump core even if GCC generates incorrect info; I've sent a
patch to bug-gdb about this.  However, GCC should generate the correct info.
The following transcript shows the output that GDB 4.4 does not expect:

    $ gcc -g -S u.cc
    $ egrep '(t17|t20)' u.s
    .stabs "$vtbl_ptr_type:t17=s8delta:6,0,16;index:6,16,16;pfn:18=*15,32,32;delta2:6,32,16;;",128,0,0,0
    .stabs "ivResource:t20=s4$vf20:21=*22=ar1;0;1;17,0;ivResource::23=##24=*20;:;2A.25=#20,15,24,1,15;:_$_10ivResource;2A*-2147483647;20;;ref::26=##15;:;2B.27=f15:PC10ivResource;2A?;Reference::26:;2B.;;~%20;",128,0,0,0

GDB 4.4 expects both instances of `:t' in the above output to be `:Tt' instead.
That is, GDB 4.4 expects the GDB extensions to be used, but they aren't being
used here.

GCC's dbxout.c has a have_used_extensions hack that causes GCC not to use the
GDB extensions sometimes.  I don't know why the hack is there, but since
the hack disagrees with GCC's documentation, I removed it; this fixed the
problems described above.  Here is the patch that I used.

===================================================================
RCS file: dbxout.c,v
retrieving revision 2.1
diff -c -r2.1 dbxout.c
*** dbxout.c	1992/03/24 10:49:21	2.1
--- dbxout.c	1992/04/10 19:00:02
***************
*** 115,127 ****
  
  static int flag_minimal_debug = 1;
  
- /* Nonzero if we have actually used any of the GDB extensions
-    to the debugging format.  The idea is that we use them for the
-    first time only if there's a strong reason, but once we have done that,
-    we use them whenever convenient.  */
- 
- static int have_used_extensions = 0;
- 
  char *getpwd ();
  
  /* Typical USG systems don't have stab.h, and they also have
--- 115,120 ----
***************
*** 554,560 ****
  	      && DECL_VIRTUAL_P (tem)
  	      && DECL_ASSEMBLER_NAME (tem))
  	    {
- 	      have_used_extensions = 1;
  	      CHARS (3 + IDENTIFIER_LENGTH (DECL_NAME (TYPE_NAME (DECL_FCONTEXT (tem)))));
  	      fputs (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)), asmfile);
  	      dbxout_type (DECL_FCONTEXT (tem), 0);
--- 547,552 ----
***************
*** 572,578 ****
  	      && (TREE_PRIVATE (tem) || TREE_PROTECTED (tem)
  		  || TREE_CODE (tem) != FIELD_DECL))
  	    {
- 	      have_used_extensions = 1;
  	      putc ('/', asmfile);
  	      putc ((TREE_PRIVATE (tem) ? '0'
  		     : TREE_PROTECTED (tem) ? '1' : '2'),
--- 564,569 ----
***************
*** 590,596 ****
  	      if (TREE_STATIC (tem) && use_gdb_dbx_extensions)
  		{
  		  char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem));
- 		  have_used_extensions = 1;
  
  #if 0 /* ??? Comment below makes it clear this is unacceptable.  */
  		  /* Adding 1 here only works on systems
--- 581,586 ----
***************
*** 1052,1058 ****
  	  {
  	    if (n_baseclasses)
  	      {
- 		have_used_extensions = 1;
  		fprintf (asmfile, "!%d,", n_baseclasses);
  		CHARS (8);
  	      }
--- 1042,1047 ----
***************
*** 1062,1068 ****
  	    tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i);
  	    if (use_gdb_dbx_extensions)
  	      {
- 		have_used_extensions = 1;
  		putc (TREE_VIA_VIRTUAL (child) ? '1'
  		      : '0',
  		      asmfile);
--- 1051,1056 ----
***************
*** 1096,1102 ****
        dbxout_type_fields (type);
        if (use_gdb_dbx_extensions && TYPE_METHODS (type) != NULL_TREE)
  	{
- 	  have_used_extensions = 1;
  	  dbxout_type_methods (type);
  	}
        putc (';', asmfile);
--- 1084,1089 ----
***************
*** 1105,1112 ****
  	  /* Avoid the ~ if we don't really need it--it confuses dbx.  */
  	  && TYPE_VFIELD (type))
  	{
- 	  have_used_extensions = 1;
- 
  	  /* Tell GDB+ that it may keep reading.  */
  	  putc ('~', asmfile);
  
--- 1092,1097 ----
***************
*** 1160,1166 ****
      case METHOD_TYPE:
        if (use_gdb_dbx_extensions)
  	{
- 	  have_used_extensions = 1;
  	  putc ('#', asmfile);
  	  CHARS (1);
  	  if (flag_minimal_debug)
--- 1145,1150 ----
***************
*** 1191,1197 ****
      case OFFSET_TYPE:
        if (use_gdb_dbx_extensions)
  	{
- 	  have_used_extensions = 1;
  	  putc ('@', asmfile);
  	  CHARS (1);
  	  dbxout_type (TYPE_OFFSET_BASETYPE (type), 0);
--- 1175,1180 ----
***************
*** 1208,1215 ****
        break;
  
      case REFERENCE_TYPE:
-       if (use_gdb_dbx_extensions)
- 	have_used_extensions = 1;
        putc (use_gdb_dbx_extensions ? '&' : '*', asmfile);
        CHARS (1);
        dbxout_type (TREE_TYPE (type), 0);
--- 1191,1196 ----
***************
*** 1398,1404 ****
  
  	  /* If there is a typedecl for this type with the same name
  	     as the tag, output an abbreviated form for that typedecl.  */
! 	  if (use_gdb_dbx_extensions && have_used_extensions
  	      && (TREE_CODE (type) == RECORD_TYPE
  		  || TREE_CODE (type) == UNION_TYPE)
  	      && (TYPE_NAME (type) == decl))
--- 1379,1385 ----
  
  	  /* If there is a typedecl for this type with the same name
  	     as the tag, output an abbreviated form for that typedecl.  */
! 	  if (use_gdb_dbx_extensions
  	      && (TREE_CODE (type) == RECORD_TYPE
  		  || TREE_CODE (type) == UNION_TYPE)
  	      && (TYPE_NAME (type) == decl))


Newsgroups: gnu.g++.bug