[Converted from Gnats 911] Would like to be able to call user-defined operators in gdb when debugging c++ code. I understand that it isn't feasible to implicitly call user-defined operators when the operators are used in a statement. However, it would be nice if gdb could understand an explicit call to the operator. For example: (gdb) print my_class_ref.operator==(my_other_class_ref) Release: 5.3 How-To-Repeat: (gdb) print my_class_ref.operator==(my_other_class_ref) There is no member or method named operator.
State-Changed-From-To: open->analyzed State-Changed-Why: I mailed in some analysis (see the audit trail). Basically, c-exp.y does not understand that 'operator==' is a lexeme in the expression 'f0.operator==(f1)', so == gets parsed as a binop.
From: Michael Elizabeth Chastain <mec@shout.net> To: gdb-gnats@sources.redhat.com Cc: Subject: Re: gdb/911: calling user-defined operators in gdb Date: Wed, 8 Jan 2003 13:29:55 -0600 I see this happening on my system with both dwarf-2 and stabs+. target=native, host=i686-pc-linux-gnu, osversion=red-hat-8.0 gdb=5.3, gcc=3.2.1, binutils=2.13.2.1, libc=vendor gformat => (dwarf-2, stabs+) The first typescript shows this happening with a test program. The direct form works: (gdb) print f0 == f0 $1 = true (gdb) print f0 == f1 $2 = false You can also work around the bug by quoting: (gdb) print f0.'operator=='(f0) $1 = true (gdb) print f0.'operator=='(f1) $2 = false It's still a bug that 'f0.operator==(f1)' does not work and gives a bogus error message. The bug still happens with gdb HEAD%20030107. The second script shows some information from debugging gdb. gdb is evaluating an expression with a BINOP_EQUAL node. A quick look at c-exp.y shows that the lexer and the parser have no code to support for C++ operator functions, so the expression parser is parsing this as '(f0.operator) == (f1)'. Michael C === Script started on Wed Jan 8 13:59:55 2003 [mec@berman gdb-pr-911]$ cat operator.cc class Foo { public: Foo (int); bool operator == (const Foo &); private: int i_; }; Foo::Foo (int i) : i_ (i) { ; } bool Foo::operator==(const Foo & f1) { bool equals; equals = this->i_ == f1.i_; return equals; } void marker () { ; } int main () { Foo f0 (0); Foo f1 (1); marker (); return 0; } [mec@berman gdb-pr-911]$ /berman/migchain/install/target/native/gcc-3.2.1-binutills-2.13.2.1/bin/g++ -v -gdwarf-2 -o operator.dwarf-2.exe operator.cc Reading specs from /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/specs Configured with: /berman/migchain/source/gcc-3.2.1/configure --prefix=/berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1 --disable-shared --with-gnu-as --with-as=/berman/migchain/install/target/native/binutils-2.13.2.1/bin/as --with-gnu-ld --with-ld=/berman/migchain/install/target/native/binutils-2.13.2.1/bin/ld Thread model: posix gcc version 3.2.1 /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/cc1plus -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=1 -D__GXX_ABI_VERSION=102 -D__ELF__ -Dunix -D__gnu_linux__ -Dlinux -D__ELF__ -D__unix__ -D__gnu_linux__ -D__linux__ -D__unix -D__linux -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 -D_GNU_SOURCE -Acpu=i386 -Amachine=i386 -Di386 -D__i386 -D__i386__ -D__tune_i686__ -D__tune_pentiumpro__ operator.cc -D__GNUG__=3 -D__DEPRECATED -D__EXCEP TIONS -quiet -dumpbase operator.cc -gdwarf-2 -version -o /tmp/cc6B1PfJ.s GNU CPP version 3.2.1 (cpplib) (i386 Linux/ELF) GNU C++ version 3.2.1 (i686-pc-linux-gnu) compiled by GNU C version 3.2.1. ignoring nonexistent directory "/berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/i686-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/include/c++/3.2.1 /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/include/c++/3.2.1/i686-pc-linux-gnu /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/include/c++/3.2.1/backward /usr/local/include /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/include /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include /usr/include End of search list. /berman/migchain/install/target/native/binutils-2.13.2.1/bin/as -V -Qy -o /tmp/ccM3aTPl.o /tmp/cc6B1PfJ.s GNU assembler version 2.13.2.1 (i686-pc-linux-gnu) using BFD version 2.13.2.1 /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o operator.dwarf-2.exe /usr/lib/crt1.o /usr/lib/crti.o /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/crtbegin.o -L/berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1 -L/berman/migchain/install/target/native/gcc-3.2.1-binutils -2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/../../.. /tmp/ccM3aTPl.o -lstdc++ -lm -lgcc -lc -lgcc /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/crtend.o /usr/lib/crtn.o [mec@berman gdb-pr-911]$ /berman/migchain/install/target/native/gcc-3.2.1-binutills-2.13.2.1/bin/g++ -v -gstabs+ -o operator.stabs+.exe operator.cc Reading specs from /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/specs Configured with: /berman/migchain/source/gcc-3.2.1/configure --prefix=/berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1 --disable-shared --with-gnu-as --with-as=/berman/migchain/install/target/native/binutils-2.13.2.1/bin/as --with-gnu-ld --with-ld=/berman/migchain/install/target/native/binutils-2.13.2.1/bin/ld Thread model: posix gcc version 3.2.1 /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/cc1plus -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=1 -D__GXX_ABI_VERSION=102 -D__ELF__ -Dunix -D__gnu_linux__ -Dlinux -D__ELF__ -D__unix__ -D__gnu_linux__ -D__linux__ -D__unix -D__linux -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 -D_GNU_SOURCE -Acpu=i386 -Amachine=i386 -Di386 -D__i386 -D__i386__ -D__tune_i686__ -D__tune_pentiumpro__ operator.cc -D__GNUG__=3 -D__DEPRECATED -D__EXCEP TIONS -quiet -dumpbase operator.cc -gstabs+ -version -o /tmp/ccwQn4rL.s GNU CPP version 3.2.1 (cpplib) (i386 Linux/ELF) GNU C++ version 3.2.1 (i686-pc-linux-gnu) compiled by GNU C version 3.2.1. ignoring nonexistent directory "/berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/i686-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/include/c++/3.2.1 /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/include/c++/3.2.1/i686-pc-linux-gnu /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/include/c++/3.2.1/backward /usr/local/include /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/include /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include /usr/include End of search list. /berman/migchain/install/target/native/binutils-2.13.2.1/bin/as -V -Qy -o /tmp/ccVE5NoA.o /tmp/ccwQn4rL.s GNU assembler version 2.13.2.1 (i686-pc-linux-gnu) using BFD version 2.13.2.1 /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o operator.stabs+.exe /usr/lib/crt1.o /usr/lib/crti.o /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/crtbegin.o -L/berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1 -L/berman/migchain/install/target/native/gcc-3.2.1-binutils- 2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/../../.. /tmp/ccVE5NoA.o -lstdc++ -lm -lgcc -lc -lgcc /berman/migchain/install/target/native/gcc-3.2.1-binutils-2.13.2.1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/crtend.o /usr/lib/crtn.o [mec@berman gdb-pr-911]$ /berman/migchain/install/target/native/gdb-5.3/bin/gdb operator.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 marker Breakpoint 1 at 0x8048393: file operator.cc, line 26. (gdb) run Starting program: /berman/home/mec/gdb-pr-911/operator.dwarf-2.exe Breakpoint 1, marker() () at operator.cc:26 26 } (gdb) up #1 0x080483d1 in main () at operator.cc:32 32 marker (); (gdb) print f0 $1 = {i_ = 0} (gdb) print f1 $2 = {i_ = 1} (gdb) print f0.operator==(f1) There is no member or method named operator. (gdb) quit The program is running. Exit anyway? (y or n) y [mec@berman gdb-pr-911]$ /berman/migchain/install/target/native/gdb-5.3/bin/gdb operator.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 marker Breakpoint 1 at 0x8048393: file operator.cc, line 26. (gdb) run Starting program: /berman/home/mec/gdb-pr-911/operator.stabs+.exe Breakpoint 1, marker() () at operator.cc:26 26 } (gdb) up #1 0x080483d1 in main () at operator.cc:32 32 marker (); (gdb) print f0 $1 = {i_ = 0} (gdb) print f1 $2 = {i_ = 1} (gdb) print f0.operator==(f1) There is no member or method named operator. (gdb) quit The program is running. Exit anyway? (y or n) y [mec@berman gdb-pr-911]$ exit exit Script done on Wed Jan 8 14:03:13 2003 === (gdb) print f0.operator==(f1) Breakpoint 1, value_struct_elt (argp=0xbfffed60, args=0x0, name=0x83643ec "operator", static_memfuncp=0x0, err=0xbfffed60 "xL5\bàL5\b\200±\022BТ\022B") at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/valops.c:2443 2443 COERCE_ARRAY (*argp); [top] bt 10 #0 value_struct_elt (argp=0xbfffed60, args=0x0, name=0x83643ec "operator", static_memfuncp=0x0, err=0xbfffed60 "xL5\bàL5\b\200±\022BТ\022B") at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/valops.c:2443 #1 0x08098908 in evaluate_subexp_standard (expect_type=0x83643c0, exp=0x83643c0, pos=0xbffff1d4, noside=EVAL_NORMAL) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/eval.c:1070 #2 0x08094de6 in evaluate_subexp (expect_type=0xbfffed60, exp=0x8354c78, pos=0xbfffed60, noside=3221220704) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/eval.c:69 #3 0x08095d23 in evaluate_subexp_standard (expect_type=0x83643c0, exp=0x83643c0, pos=0xbffff1d4, noside=EVAL_NORMAL) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/eval.c:1455 #4 0x08094de6 in evaluate_subexp (expect_type=0xbfffed60, exp=0x8354c78, pos=0xbfffed60, noside=3221220704) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/eval.c:69 #5 0x0809500f in evaluate_expression (exp=0xbfffed60) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/eval.c:158 #6 0x080a4049 in print_command_1 (exp=0x826189e "f0.operator==(f1)", inspect=0, voidprint=1) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/printcmd.c:907 #7 0x080a40d1 in print_command (exp=0xbfffed60 "xL5\bàL5\b\200±\022BТ\022B", from_tty=1) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/printcmd.c:951 #8 0x08075e89 in do_cfunc (c=0xbfffed60, args=0xbfffed60 "xL5\bàL5\b\200±\022BТ\022B", from_tty=-1073746592) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/cli/cli-decode.c:53 #9 0x08077cec in cmd_func (cmd=0x826baf0, args=0xbfffed60 "xL5\bàL5\b\200±\022BТ\022B", from_tty=-1073746592) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/cli/cli-decode.c:1523 (More stack frames follow...) [top] frame 1 #1 0x08098908 in evaluate_subexp_standard (expect_type=0x83643c0, exp=0x83643c0, pos=0xbffff1d4, noside=EVAL_NORMAL) at /berman/fsf/_today_/source/gdb/HEAD/src/gdb/eval.c:1070 1070 return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string, [top] print exp $1 = (struct expression *) 0x83643c0 [top] print *exp $2 = {language_defn = 0x821eb80, nelts = 14, elts = {{opcode = BINOP_EQUAL, symbol = 0xe, longconst = 14, doubleconst = -0.590133193756729029967553863121668e+2639, string = 14 '\016', type = 0xe, internalvar = 0xe, block = 0xe}}}
FWIW, this seems to be fixed on archer-keiths-expr-cumulative. This is in the archer repository. We'll be pushing this upstream soon... (gdb) p f0.operator==(f1) $3 = false
I have verified that this has been fixed between 6.8 and 7.1: (gdb) p a == b $1 = false (gdb) p a.operator==(b) $2 = false