This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Breaking in a c++ method with current language set to c.


Hi all,

I got a fail in gdb.cp/psmang.exp while debugging gdbserver, related to the fact
that I have debug info in my c startup files, which in turn made me have the
current language set to c.  The test tried to do a break like,

break A::method

, which failed, because the current way of finding struct/union methods doesn't
take into account the language of A.  When we get to linespec.c:find_method, if
we know that A is a c++ class, we know that 'method' is a c++ method.

I've looked at several ways to fix it, and all but this one turned out more
invasive than I hoped for, because current_language is used in a several places
(in symtab.c).  Instead, I simply wrapped linespec.c:find_method with a
set_language (lang of A), guarded with a cleanup.

With class A from the new testcase in the patch,

before:
(gdb) set lang c
(gdb) b A::method
the class A does not have any method named method
Hint: try 'A::method<TAB> or 'A::method<ESC-?>
(Note leading single quote.)

after:
(gdb) set lang c
[0] cancel
[1] all
[2] A::method(A*) at main.cc:17
[3] A::method(int) at main.cc:12
[4] A::method() at main.cc:7


Tested on i686-pc-cygwin,


OK?

Cheers,
Pedro Alves
gdb/

2007-03-05  Pedro Alves  <pedro_alves@portugalmail.pt>

	* linespec.c (find_method_1): Renamed from find_method.
	(set_language_ptr): New.
	(find_method): New as wrapper around find_method_1.

gdb/testsuite/

2007-03-05  Pedro Alves  <pedro_alves@portugalmail.pt>

	* gdb.cp/method2.cc: New test.
	* gdb.cp/method2.exp: New test.
	* gdb.cp/Makefile.in (EXECUTABLES): Add method2.

---
 gdb/linespec.c                   |   40 +++++++++++++++++++++-
 gdb/testsuite/gdb.cp/Makefile.in |    2 -
 gdb/testsuite/gdb.cp/method2.cc  |   27 +++++++++++++++
 gdb/testsuite/gdb.cp/method2.exp |   70 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 137 insertions(+), 2 deletions(-)

Index: src/gdb/linespec.c
===================================================================
--- src.orig/gdb/linespec.c	2007-03-05 02:42:26.000000000 +0000
+++ src/gdb/linespec.c	2007-03-05 02:50:50.000000000 +0000
@@ -37,6 +37,7 @@
 #include "objc-lang.h"
 #include "linespec.h"
 #include "exceptions.h"
+#include "language.h"
 
 /* We share this one with symtab.c, but it is not exported widely. */
 
@@ -1398,7 +1399,7 @@ lookup_prefix_sym (char **argptr, char *
    symbol is SYM_CLASS.  */
 
 static struct symtabs_and_lines
-find_method (int funfirstline, char ***canonical, char *saved_arg,
+find_method_1 (int funfirstline, char ***canonical, char *saved_arg,
 	     char *copy, struct type *t, struct symbol *sym_class)
 {
   struct symtabs_and_lines values;
@@ -1461,6 +1462,43 @@ find_method (int funfirstline, char ***c
     }
 }
 
+static void
+set_language_ptr (void *language)
+{
+  enum language *l = language;
+  set_language (*l);
+}
+
+/* A wrapper for find_method_1 that sets the current language
+   temporarily to the language of SYM_CLASS.  */
+
+static struct symtabs_and_lines
+find_method (int funfirstline, char ***canonical, char *saved_arg,
+	     char *copy, struct type *t, struct symbol *sym_class)
+{
+  struct symtabs_and_lines result;
+
+  if (SYMBOL_LANGUAGE (sym_class) != current_language->la_language
+      && SYMBOL_LANGUAGE (sym_class) != language_unknown)
+    {
+      enum language saved_current_language = current_language->la_language;
+      struct cleanup *cleanups;
+      set_language (SYMBOL_LANGUAGE (sym_class));
+      cleanups = make_cleanup (set_language_ptr, &saved_current_language);
+      result = find_method_1 (funfirstline, canonical, saved_arg,
+			      copy, t, sym_class);
+      do_cleanups (cleanups);
+    }
+  else
+    {
+      result = find_method_1 (funfirstline, canonical, saved_arg,
+			      copy, t, sym_class);
+    }
+
+  return result;
+}
+
+
 /* Find all methods named COPY in the class whose type is T, and put
    them in SYM_ARR.  Return the number of methods found.  */
 
Index: src/gdb/testsuite/gdb.cp/method2.cc
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/testsuite/gdb.cp/method2.cc	2007-03-05 02:50:50.000000000 +0000
@@ -0,0 +1,27 @@
+struct A
+{
+  void method ();
+  void method (int a);
+  void method (A* a);
+};
+
+void
+A::method ()
+{
+}
+
+void
+A::method (int a)
+{
+}
+
+void
+A::method (A* a)
+{
+}
+
+int
+main (int argc, char** argv)
+{
+  return 0;
+}
Index: src/gdb/testsuite/gdb.cp/method2.exp
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/testsuite/gdb.cp/method2.exp	2007-03-05 03:19:40.000000000 +0000
@@ -0,0 +1,70 @@
+# Copyright 2007
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This file is part of the gdb testsuite
+
+# This tests setting a break in an ambiguous c++ method with
+# current_language set to c.
+
+if { [skip_cplus_tests] } { continue }
+
+set testfile "method2"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+     untested method2.exp
+     return -1
+}
+
+if [get_compiler_info $binfile "c++"] {
+  return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+proc test_break { lang } {
+    global gdb_prompt
+
+    gdb_test "set lang $lang" \
+	"" \
+	"setting language $lang"
+
+    send_gdb "break A::method\n"
+    gdb_expect {
+	-re ".0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2. A::method\\(A\\*\\) at .*\[\r\n\]*.3. A::method\\(int\\) at .*\[\r\n\]*\[\r\n\]*.4. A::method\\(\\) at .*\[\r\n\]*> $" {
+	    gdb_test "0" \
+		"canceled" \
+		"breaking in method ($lang)"
+	}
+	-re ".*$gdb_prompt $" { fail "breaking in method ($lang)" }
+	default { fail "breaking in method ($lang) (timeout)" }
+    }
+}
+
+test_break "c"
+test_break "c++"
+
+gdb_continue_to_end "continue to end"
Index: src/gdb/testsuite/gdb.cp/Makefile.in
===================================================================
--- src.orig/gdb/testsuite/gdb.cp/Makefile.in	2006-07-13 05:31:42.000000000 +0100
+++ src/gdb/testsuite/gdb.cp/Makefile.in	2007-03-05 02:54:12.000000000 +0000
@@ -4,7 +4,7 @@ srcdir = @srcdir@
 EXECUTABLES = ambiguous annota2 anon-union cplusfuncs cttiadd \
 	derivation inherit local member-ptr method misc \
         overload ovldbreak ref-typ ref-typ2 templates userdef virtfunc namespace \
-	ref-types ref-params
+	ref-types ref-params method2
 
 all info install-info dvi install uninstall installcheck check:
 	@echo "Nothing to be done for $@..."

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]