Bug 8128 - setting a breakpoint on C++ member functions
Summary: setting a breakpoint on C++ member functions
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-02-03 14:08 UTC by zeitler
Modified: 2017-11-17 15:39 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description zeitler 2003-02-03 14:08:00 UTC
[Converted from Gnats 1023]

gdb 5.0 and 5.2 both don't allow me to set breakpoints on 
some member functions (generated with g++ 2.8.1 or 2.95.3)
e.g.

------------ snip ---------

class myClass
{
  public:
    myClass() {};
    ~myClass() {};
    void performUnblocking( short int cell_index );
    void performBlocking( int cell_index );
};

void myClass::performUnblocking( short int cell_index ) {}

void myClass::performBlocking( int cell_index ) {}

------------ snip ---------


b myClass::performUnblocking works
but myClass::performBlocking doesn't.


nm show the following names for these 2 functions:

08048500 T performBlocking__7myClassi
080484e0 T performUnblocking__7myClasss


I observe the same behavior on Solaris 5.8 and under Linux 
SuSE 7.2. I know I can set a breakpoint via the mangled
names or use completion (with Tab) but we're using gdb via
another tool that sets the breakpoints
automatically with the syntax above.


I don't know if this is a g++ or a gdb problem. g++ 3.0.4
generates mangled names that look slightly different and
setting breakpoints on these functions works just fine.

00010770 T _ZN7myClass15performBlockingEi
0001075c T _ZN7myClass17performUnblockingEs



Unfortunately the set of tools we use (vxworks Tornado,
Objectime) and other project restrictions don't allow as
to simply switch to a new g++ compiler.


Is there some workaround or gdb patch for this problem?
I appreciate any help.

Release:
unknown

Environment:
Solaris 5.8 and Linux SuSE 7.2
Comment 1 mec 2003-02-03 15:18:49 UTC
From: Michael Elizabeth Chastain <mec@shout.net>
To: zeitler@lucent.com
Cc: gdb-gnats@sources.redhat.com
Subject: Re: c++/1023: setting a breakpoint on C++ member functions
Date: Mon, 3 Feb 2003 09:18:49 -0600

 I see this bug in my test bed as well.
 
 I confirmed this with:
 
   target=native, host=i686-pc-linux-gnu, osversion=red-hat-8.0,
   gdb={5.3, HEAD%20030201}, gcc=2.95.3, binutils=2.13.2.1,
   libc=2.2.93-5-rh, gformat=stabs+
 
 The problem happens with both gdb 5.3 and gdb HEAD%20030201.
 The problem happens with stabs+.  It does not happen with dwarf-2.
 
 Workaround: try compiling with -gdwarf-2.
 
 Michael C
 
   Script started on Mon Feb  3 10:05:22 2003
 
   [mgnu@berman pr-1023]$ cat myclass.cc 
   class myClass
   {
     public:
       myClass() {};
       ~myClass() {};
       void performUnblocking( short int cell_index );
       void performBlocking( int cell_index );
   };
 
   void myClass::performUnblocking( short int cell_index ) {}
 
   void myClass::performBlocking( int cell_index ) {}
 
   int main ()
   {
     myClass mc;
     mc.performBlocking (0);
     mc.performUnblocking (0);
   }
 
   # gdb 5.3, gcc 2.95.3, -gstabs+
   [mgnu@berman pr-1023]$ /berman/migchain/install/target/native/gdb-5.3/bin/gdb mycclass.2953.2132.stabs+.exe
   GNU gdb 5.3
   Copyright 2002 Free Software Foundation, Inc.
   GDB is free software, covered by the GNU General Public License, and you are
   welcome to change it and/or 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.
   This GDB was configured as "i686-pc-linux-gnu"...
   (gdb) break myClass::performBlocking
   the class myClass does not have any method named performBlocking
   Hint: try 'myClass::performBlocking<TAB> or 'myClass::performBlocking<ESC-?>
   (Note leading single quote.)
   (gdb) break myClass::performUnblocking
   Breakpoint 1 at 0x80491b0: file myclass.cc, line 10.
   (gdb) quit
 
   # gdb HEAD%20030201, gcc 2.95.3, -gstabs+
   [mgnu@berman pr-1023]$ /berman/fsf/_today_/berman/install/target/native/gdb/HEAD/bin/gdb myclass.2953.2132.stabs+.exe
   GNU gdb 2003-02-01-cvs
   Copyright 2003 Free Software Foundation, Inc.
   GDB is free software, covered by the GNU General Public License, and you are
   welcome to change it and/or 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.
   This GDB was configured as "i686-pc-linux-gnu"...
   (gdb) break myClass::performBlocking
   the class myClass does not have any method named performBlocking
   Hint: try 'myClass::performBlocking<TAB> or 'myClass::performBlocking<ESC-?>
   (Note leading single quote.)
   (gdb) break myClass::performUnblocking
   Breakpoint 1 at 0x80491b0: file myclass.cc, line 10.
   (gdb) quit
 
   # gdb 5.3, gcc 2.95.3, -gdwarf-2
   [mgnu@berman pr-1023]$ /berman/fsf/_today_/berman/install/target/native/gdb/HEAD//bin/gdb myclass.2953.2132.stabs+.migchain/install/target/native/gdb-5.3/bin/gdb myclass.2953.2132.dwarf-2.exe
   GNU gdb 5.3
   Copyright 2002 Free Software Foundation, Inc.
   GDB is free software, covered by the GNU General Public License, and you are
   welcome to change it and/or 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.
   This GDB was configured as "i686-pc-linux-gnu"...
   (gdb) break myClass::performBlocking
   Breakpoint 1 at 0x80491b7: file myclass.cc, line 12.
   (gdb) break myClass::performUnblocking
   Breakpoint 2 at 0x80491a6: file myclass.cc, line 10.
   (gdb) quit
 
   # gdb HEAD%20030201, gcc 2.95.3, -gdwarf-2
   [mgnu@berman pr-1023]$ /berman/fsf/_today_/berman/install/target/native/gdb/HEAD/bin/gdb myclass.2953.2132.dwarf-2.exe
   GNU gdb 2003-02-01-cvs
   Copyright 2003 Free Software Foundation, Inc.
   GDB is free software, covered by the GNU General Public License, and you are
   welcome to change it and/or 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.
   This GDB was configured as "i686-pc-linux-gnu"...
   (gdb) break myClass::performBlocking
   Breakpoint 1 at 0x80491b7: file myclass.cc, line 12.
   (gdb) break myClass::performUnblocking
   Breakpoint 2 at 0x80491a6: file myclass.cc, line 10.
   (gdb) quit
   [mgnu@berman pr-1023]$ exit
 
   Script done on Mon Feb  3 10:08:46 2003

Comment 2 mec 2003-02-06 01:05:35 UTC
From: Michael Elizabeth Chastain <mec@shout.net>
To: gdb-gnats@sources.redhat.com
Cc:  
Subject: Re: c++/1023: setting a breakpoint on C++ member functions
Date: Wed, 5 Feb 2003 19:05:35 -0600

 I wrote a test script for this, gdb.c++/pr-1023.exp,
 and committed it to gdb HEAD.
 
 Michael C

Comment 3 David Carlton 2003-03-01 00:27:50 UTC
From: David Carlton <carlton@math.stanford.edu>
To: GNATS Filer <gdb-gnats@sources.redhat.com>
Cc: zeitler@lucent.com, Michael Elizabeth Chastain <mec@shout.net>,
   Daniel Jacobowitz <drow@mvista.com>
Subject: Re: c++/1023: setting a breakpoint on C++ member functions
Date: 28 Feb 2003 16:27:50 -0800

 I've had a look at this; I'm not at all familiar with stabs (or with
 stabsread.c), but here's what I've found so far.
 
 The stabs for the class declaration says:
 
 .stabs "myClass:T(0,25)=s1operator=::(0,26)=##(0,27)=&(0,25);:__as__7myClassRC7myClass;2A.;myClass::(0,28)=##(0,29)=*(0,25);:RC7myClass;2A.(0,30)=##(0,29);:;2A.(0,31)=#(0,25),(0,21),(0,29),(0,1),(0,21);:_._7myClass;2A.;performUnblocking::(0,32)=##(0,21);:s;2A.;performBlocking::(0,31):i;2A.;;",128,0,0,0
 
 Notice that neither performUnblocking or performBlocking contains a
 mangled name.  But the type for performUnblocking is listed as
 
   (0,32)=##(0,21)
 
 while the type for performBlocking is listed as
 
   (0,31)
 
 In other words, reading the stabs manual, performUnblocking has a type
 that we haven't seen before, while performBlocking has the same type
 as an earlier method.
 
 Now: enter stabsread.c:read_member_functions.  It grabs the type of
 the method in this line:
 
 	      new_sublist->fn_field.type = read_type (pp, objfile);
 
 For performUnblocking, it has to create a new type; for
 performBlocking, it can reuse a type from an earlier method.
 
 But then we get to this part of read_member_functions:
 
 	  if (TYPE_STUB (new_sublist->fn_field.type))
 	    {
 	      if (!TYPE_DOMAIN_TYPE (new_sublist->fn_field.type))
 		TYPE_DOMAIN_TYPE (new_sublist->fn_field.type) = type;
 	      new_sublist->fn_field.is_stub = 1;
 	    }
 	  new_sublist->fn_field.physname = savestring (*pp, p - *pp);
 
 The if clause looks at the type it's just found to see if the current
 method is a stub.  Then, either way, the physname is grabbed from the
 stabs, but code elsewhere in GDB only pays attention to that if we
 think the current method isn't a stub.
 
 The problem is that, while performBlocking is a stub, the earlier
 method that it shared the type with _wasn't_ a stub.  So
 performBlocking is erroneously treated as a non-stub, so the physname
 that is found is treated as the actual mangled name.  Which makes GDB
 think that the mangled name is "i", which is, of course, incorrect.
 
 I'll see if I can come up with a patch (maybe it's correct to set
 new_sublist->fn_field.is_stub based on whether or not an attempt to
 demangle the name works...), but I'm really fumbling around in the
 dark; if this prompts anybody more knowledgeable to find a solution,
 that would doubtless be a much better outcome.

Comment 4 David Carlton 2003-03-03 19:14:00 UTC
From: David Carlton <carlton@math.stanford.edu>
To: GNATS Filer <gdb-gnats@sources.redhat.com>
Cc: Michael Elizabeth Chastain <mec@shout.net>,
   Daniel Jacobowitz <drow@mvista.com>
Subject: Re: c++/1023: setting a breakpoint on C++ member functions
Date: 03 Mar 2003 11:14:00 -0800

 I tried the following patch as a sort of "proof of concept" of my
 solution (I certainly wouldn't consider it appropriate as-is even if
 it worked, for various reasons):
 
 2003-02-28  David Carlton  <carlton@math.stanford.edu>
 
 	* stabsread.c (read_member_functions): Check that physnames really
 	look like they can be demangled.
 
 Index: stabsread.c
 ===================================================================
 RCS file: /cvs/src/src/gdb/stabsread.c,v
 retrieving revision 1.57
 diff -u -p -r1.57 stabsread.c
 --- stabsread.c	25 Feb 2003 21:36:19 -0000	1.57
 +++ stabsread.c	1 Mar 2003 00:51:33 -0000
 @@ -3098,15 +3098,29 @@ read_member_functions (struct field_info
  	      p++;
  	    }
  
 -	  /* If this is just a stub, then we don't have the real name here. */
 -
  	  if (TYPE_STUB (new_sublist->fn_field.type))
  	    {
  	      if (!TYPE_DOMAIN_TYPE (new_sublist->fn_field.type))
  		TYPE_DOMAIN_TYPE (new_sublist->fn_field.type) = type;
 -	      new_sublist->fn_field.is_stub = 1;
  	    }
  	  new_sublist->fn_field.physname = savestring (*pp, p - *pp);
 +	  {
 +	    char *demangled_name
 +	      = cplus_demangle (new_sublist->fn_field.physname,
 +				DMGL_PARAMS | DMGL_ANSI);
 +
 +	    if (demangled_name == NULL)
 +	      {
 +		/* Claim that it's a stub so that other code doesn't
 +		   trust the physname.  Note that the above TYPE_STUB
 +		   test isn't reliable: see PR c++/1023.  */
 +		new_sublist->fn_field.is_stub = 1;
 +	      }
 +	    else
 +	      {
 +		xfree (demangled_name);
 +	      }
 +	  }
  	  *pp = p + 1;
  
  	  /* Set this member function's visibility fields.  */
 
 The good news is that, when doing a test suite run with GCC 2.96,
 stabs, it did fix gdb.c++/pr-1023.exp; the bad news is that a lot of
 stuff in gdb.c++/userdef.exp started failing.
 
 So clearly there's something going on here that I don't understand
 (not surprisingly, given how little I know about stabs; certainly
 having the type and the fn_field disagree about whether or not
 something is a stub sounds like a bad idea to me).  I'm going to stop
 working on this one for now, because I'm too busy to become an expert
 on stabsread.c.
Comment 5 Keith Seitz 2010-03-10 23:54:41 UTC
I am unable to reproduce this bug using GCC 3.4.6 with GDB 6.8 using either
-gdwarf-2 or -gstabs+, so I am closing this bug.
Comment 6 Sourceware Commits 2017-03-10 18:34:19 UTC
The master branch has been updated by Keith Seitz <kseitz@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5f4d10850850cd95af5e95a16848c8c07a273d88

commit 5f4d10850850cd95af5e95a16848c8c07a273d88
Author: Keith Seitz <keiths@redhat.com>
Date:   Fri Mar 10 10:32:09 2017 -0800

    c++/8218: Destructors w/arguments.
    
    For a long time now, c++/8218 has noted that GDB is printing argument types
    for destructors:
    
    (gdb) ptype A
    type = class A {
      public:
        ~A(int);
    }
    
    This happens because cp_type_print_method_args doesn't ignore artificial
    arguments.  [It ignores the first `this' pointer because it simply skips
    the first argument for any non-static function.]
    
    This patch fixes this:
    
    (gdb) ptype  A
    type = class A {
      public:
        ~A();
    }
    
    I've adjusted gdb.cp/templates.exp to account for this and added a new
    passing regexp.
    
    gdb/ChangeLog
    
    	PR c++/8218
    	* c-typeprint.c (cp_type_print_method_args): Skip artificial arguments.
    
    gdb/testsuite/ChangeLog
    
    	PR c++/8128
    	* gdb.cp/templates.exp (test_ptype_of_templates): Remove argument
    	type from destructor regexps.
    	Add a branch which actually passes the test.
    	Adjust "ptype t5i" test names.
Comment 7 Sergio Durigan Junior 2017-11-17 15:39:27 UTC
Hm, this bug has been closed, but judging by the commit log it was probably a typo/thinko.  I think bug 8218 should have been closed instead, right?