Summary: | setting a breakpoint on C++ member functions | ||
---|---|---|---|
Product: | gdb | Reporter: | zeitler |
Component: | c++ | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | carlton, gdb-prs, mec, sergiodj |
Priority: | P3 | ||
Version: | unknown | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Last reconfirmed: |
Description
zeitler
2003-02-03 14:08:00 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 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 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. 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. 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. 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. |