* How to call operator<< functions?
@ 2006-08-30 10:11 Michael Veksler
2006-08-30 11:13 ` Frederic RISS
2006-08-30 12:46 ` How to call operator<< functions? Daniel Jacobowitz
0 siblings, 2 replies; 23+ messages in thread
From: Michael Veksler @ 2006-08-30 10:11 UTC (permalink / raw)
To: gdb
Hello,
I have searched the web for an answer without success. The following
problem does not seem to exist. Either my configuration is broken in a
unique way or my requirements are considered weird and outrageous (so no
one tries to do similar things). Read on and tell me what you think.
I have a complex data structure MyClass (e.g. a parse tree) which I want
to examine in GDB. It is impractical to traverse and print it node by
node from GDB. For that I have written both MyClass::Print(ostream&)
and operator<< that invokes this Print. These method and operator can
print the data structure in a very nice and readable form. I can use
them to print the data into some stream when my application operates in
verbose mode.
Now I want to invoke the operator<<(ostream& , MyClass const &) function,
or alternatively the MyClass::Print(ostream&) const -- from GDB;
This does not work even with gcb-6.5, not to mention older versions. The
compiler RedHat's gcc-3.4.
Passing 'std::cout' seems impossible. Any attempt to pass std::cout
crashes. To overcome this I define my own global
ostream gecLog(cout.rdbuf());
(or something similar) and recompile the code. This lets me pass gecLog
instead of cout, and it _sometimes_ works:
(gdb) p pd.Print(gecLog)
Cannot resolve method (null)Print to any overloaded instance
-----------
Now, going through function pointers helps for some weird reason:
(gdb) p pd.Print
$13 = &MyClass::Print(std::ostream&) const
(gdb) p $13(&pd, gecLog)
Enter Print()
(gdb) p $15(&pd, std::cout)
Program received signal SIGSEGV, Segmentation fault.
0x0042cf88 in std::ostream::sentry::sentry () from /usr/lib/libstdc++.so.6
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on"
Evaluation of the expression containing the function
(MyClass::Print(std::ostream&) const) will be abandoned.
--------------------------------------
I wanted to do the same for operator<<:
(gdb) p 'operator<<(std::ostream&, MyClass const&)'
$17 = {ostream &(ostream &, const class MyClass
&)} 0x8068a00 <operator<<(std::ostream&, MyClass const&)>
(gdb) p $17(gecLog, *pd)
Program received signal SIGSEGV, Segmentation fault.
-----------------------
Now, I wanted to write a GDB macro to call Print for me. When I try to use
p $-1(&pd, gecLog)
I get a SIGSEGV (when with p $14(....) it would "just" work).
---------------------
Is there any way to overcome any of the above problems? All I want is to
pass a stream such as cerr/cout/clog to a printing function, is that
unreasonable?
Thanks
Michael
P.S.
To overcome this, I am writing a method MyClass::DebugPrint() that calls
Print(cerr). Sometimes, while debugging a piece of code, that a vital
object has <<, but no DebugPrint, and *that* really frustrates me -
especially when I loose a 60 minutes debugging session to a SIGSEGV.
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: How to call operator<< functions? 2006-08-30 10:11 How to call operator<< functions? Michael Veksler @ 2006-08-30 11:13 ` Frederic RISS 2006-08-30 13:30 ` Frederic RISS 2006-08-30 12:46 ` How to call operator<< functions? Daniel Jacobowitz 1 sibling, 1 reply; 23+ messages in thread From: Frederic RISS @ 2006-08-30 11:13 UTC (permalink / raw) To: Michael Veksler; +Cc: gdb On Wed, 2006-08-30 at 13:11 +0300, Michael Veksler wrote: > Passing 'std::cout' seems impossible. Any attempt to pass std::cout > crashes. To overcome this I define my own global > ostream gecLog(cout.rdbuf()); > (or something similar) and recompile the code. This lets me pass gecLog > instead of cout, and it _sometimes_ works: Just to reply to this little part. I've already encountered the issue with cout. In my case the _ZSt4cout symbol was present in the debugged binary and (obviously) in libstdc++. I _think_ that GDB resolved _ZSt4cout as if the symbol in the library was used whereas the one in the executable was the right one. I can't remember the reasons for this right now. As a workaround, I passed '*(ostream*)<addr>' in place of std::cout. I found <addr> using nm on my binary. This seemed to work if I remember well. It's been a while though... Hope this helps, Fred. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: How to call operator<< functions? 2006-08-30 11:13 ` Frederic RISS @ 2006-08-30 13:30 ` Frederic RISS 2006-08-30 13:40 ` Breakpoint Handling in GDB Veenu Verma (AS/EAB) 2006-08-31 11:34 ` Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) Frederic RISS 0 siblings, 2 replies; 23+ messages in thread From: Frederic RISS @ 2006-08-30 13:30 UTC (permalink / raw) To: gdb On Wed, 2006-08-30 at 13:12 +0200, Frederic RISS wrote: > I've already encountered the issue with cout. In my case the _ZSt4cout > symbol was present in the debugged binary and (obviously) in libstdc++. > I _think_ that GDB resolved _ZSt4cout as if the symbol in the library > was used whereas the one in the executable was the right one. I can't > remember the reasons for this right now. I digged an old testcase out. Very simple: -----------------------------8<----------------------------------- #include <iostream> void dump (std::ostream& os) { os << "Hello, guys!" << std::endl; } int main () { std::cout << "&std::cout is " << &std::cout << std::endl; dump (std::cout); return 0; } -----------------------------8<----------------------------------- With neither of the toolcahins I tried (all x86, gcc 4.0 and 4.1 with recent binutils) I could get the correct value for &std::cout: rf23@crx549 ~/tmp/cout % gdb --silent a.out Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) start Breakpoint 1 at 0x8048703: file cout.cc, line 11. Starting program: /home/rf23/tmp/cout/a.out main () at cout.cc:11 11 std::cout << "&std::cout is " << &std::cout << std::endl; (gdb) n &std::cout is 0x8049a78 12 dump (std::cout); (gdb) p &std::cout $1 = (ostream *) 0x582b40 p dump (std::cout) Program received signal SIGSEGV, Segmentation fault. As you can see, we get the wrong address. Thus we fail to pass the right object when calling a function. Little (re-)investigation showed that this is related to symbol versionning. In the static symtab the std::cout symbol is versioned and is recorded as such in GDB's minsym table: rf23@crx549 ~/tmp/cout % nm a.out| grep cout 49:08049a78 B _ZSt4cout@@GLIBCXX_3.4 rf23@crx549 ~/tmp/cout % nm -D a.out| grep cout 11:08049a78 B _ZSt4cout This can be confirmed from within GDB: (gdb) p &'_ZSt4cout@@GLIBCXX_3.4' $2 = (<data variable, no debug info> *) 0x8049a78 I don't know how we should handle that. Trimming the symbol versions seems wrong (and scanning each symbol for @@ has a cost). Maybe we shouldn't skip the dynamic symtab for the main executable? Not sure if it'll solve all such cases. Fred. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Breakpoint Handling in GDB 2006-08-30 13:30 ` Frederic RISS @ 2006-08-30 13:40 ` Veenu Verma (AS/EAB) 2006-08-30 13:43 ` Daniel Jacobowitz 2006-08-30 20:30 ` Michael Snyder 2006-08-31 11:34 ` Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) Frederic RISS 1 sibling, 2 replies; 23+ messages in thread From: Veenu Verma (AS/EAB) @ 2006-08-30 13:40 UTC (permalink / raw) To: gdb Hello I was going through the gdb internals on software breakpoint handling and have a question regarding that. Gdb replaces the program instruction with a trap which means target does not have any control over setting a bp. What happens if the connection with the gdb breaks down ? Does it mean that the illegal instruction won't be restored and the application will crash ? If that's the case, then how can it be handled ? Thanx Veenu ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Breakpoint Handling in GDB 2006-08-30 13:40 ` Breakpoint Handling in GDB Veenu Verma (AS/EAB) @ 2006-08-30 13:43 ` Daniel Jacobowitz 2006-08-30 20:30 ` Michael Snyder 1 sibling, 0 replies; 23+ messages in thread From: Daniel Jacobowitz @ 2006-08-30 13:43 UTC (permalink / raw) To: Veenu Verma (AS/EAB); +Cc: gdb On Wed, Aug 30, 2006 at 03:40:21PM +0200, Veenu Verma (AS/EAB) wrote: > Hello > I was going through the gdb internals on software breakpoint handling > and have a question regarding that. > Gdb replaces the program instruction with a trap which means target does > not have any control over setting a bp. > What happens if the connection with the gdb breaks down ? > Does it mean that the illegal instruction won't be restored and the > application will crash ? > If that's the case, then how can it be handled ? Implement the z0/Z0 packets in your stub instead, and then GDB will use them. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Breakpoint Handling in GDB 2006-08-30 13:40 ` Breakpoint Handling in GDB Veenu Verma (AS/EAB) 2006-08-30 13:43 ` Daniel Jacobowitz @ 2006-08-30 20:30 ` Michael Snyder 1 sibling, 0 replies; 23+ messages in thread From: Michael Snyder @ 2006-08-30 20:30 UTC (permalink / raw) To: Veenu Verma (AS/EAB); +Cc: gdb On Wed, 2006-08-30 at 15:40 +0200, Veenu Verma (AS/EAB) wrote: > Hello > I was going through the gdb internals on software breakpoint handling > and have a question regarding that. > Gdb replaces the program instruction with a trap which means target does > not have any control over setting a bp. > What happens if the connection with the gdb breaks down ? > Does it mean that the illegal instruction won't be restored and the > application will crash ? In the general case, yes, that's what it means. > If that's the case, then how can it be handled ? The newer z0/Z0 remote commands will allow the target debug agent (eg. gdbserver) to handle the breakpoints. But if you're using the original method of breakpointing by writing trap instructions into target memory, then yes, you're vulnerable to the scenario that you describe. If you can't reboot the target, you MIGHT try re-connecting with gdb, and "fixing" the trap instructions by hand. Obviously this is "at your own risk". GDB does not have any built-in capability to help with the situation that you describe. However, I *have* used the following method: 1) If possible, get the locations of the breakpoints using gdb's "info break" command. 2) WITHOUT reconnecting to the target, load the target's executable file into gdb, and examine (and record) the contents of memory at those locations, eg. like this: (gdb) print /x *(unsigned int *) 0xabcdef 3) Now reconnect to the target, and modify those locations to match what's in the original binary file, eg.: (gdb) set *(unsigned int *) 0xabcdef = <value> Again, YMMV, use at your own risk, operators are trained professionals etc. etc. Remember, there may be trap instructions that you don't know about, eg. if you were in the middle of a "next" or "finish" when you lost communication with the target. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) 2006-08-30 13:30 ` Frederic RISS 2006-08-30 13:40 ` Breakpoint Handling in GDB Veenu Verma (AS/EAB) @ 2006-08-31 11:34 ` Frederic RISS 2006-08-31 12:09 ` Michael Veksler 1 sibling, 1 reply; 23+ messages in thread From: Frederic RISS @ 2006-08-31 11:34 UTC (permalink / raw) To: gdb; +Cc: GDB Patches [-- Attachment #1: Type: text/plain, Size: 1159 bytes --] On Linux, versioned ELF symbols are stored in the static symtab with an (@)@VERSION suffix. We store such symbols with the suffix and thus fail to find them when looking up the real name. This causes failures such as the one described here: http://www.sourceware.org/ml/gdb/2006-08/msg00244.html In the general case, GDB doesn't use the dynamic symtab because it contains usually only a subset of the static table information. The attached patch make GDB store dynamic versioned symbols. Maybe this is harvests too much symbols, and we should limit it to the dynamic symbols of the main executable. It's easy enough to do, we just need to pass the 'mainline' flag to elf_symfile_read from elf_symtab_read. I've no idea if this could break something on non-Linux platforms, I've just tested on x86-linux. I'm also attaching a little testsuite patch that fails for me on current GDB and works with the patch. Opinions? 2006-08-31 Frederic Riss <frederic.riss@st.com> * elfread.c (elf_symtab_read): Read versioned symbols from the dynamic symtab. 2006-08-31 Frederic Riss <frederic.riss@st.com> * gdb.cp/userdef.exp: Test use of std::cout. [-- Attachment #2: versioned-symbols.patch --] [-- Type: text/x-patch, Size: 993 bytes --] Index: elfread.c =================================================================== RCS file: /cvs/src/src/gdb/elfread.c,v retrieving revision 1.55 diff -u -p -r1.55 elfread.c --- elfread.c 21 Feb 2006 20:38:48 -0000 1.55 +++ elfread.c 31 Aug 2006 10:50:17 -0000 @@ -211,9 +211,14 @@ elf_symtab_read (struct objfile *objfile /* If it is a nonstripped executable, do not enter dynamic symbols, as the dynamic symbol table is usually a subset - of the main symbol table. */ - if (dynamic && !stripped) + of the main symbol table. + The Linux ELF symbol versionning requires that the versioned + static symbols are suffixed with (@)@VERSION, thus the + entries we got from the static symtab for these symbols have + suffixed names. The entries in the dynamic symtab don't have + the suffix (version info is stored in .gnu_version section). */ + if (dynamic && !stripped && !((elf_symbol_type *) sym)->version) continue; if (sym->flags & BSF_FILE) { [-- Attachment #3: testsuite-cout.patch --] [-- Type: text/x-patch, Size: 719 bytes --] ? testsuite-cout.patch Index: gdb.cp/userdef.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/userdef.exp,v retrieving revision 1.6 diff -u -p -r1.6 userdef.exp --- gdb.cp/userdef.exp 10 Aug 2006 05:27:20 -0000 1.6 +++ gdb.cp/userdef.exp 31 Aug 2006 10:58:01 -0000 @@ -151,5 +151,8 @@ gdb_test "print *c" "\\\$\[0-9\]* = \\(M gdb_test "print &*c" "\\\$\[0-9\]* = \\(Member \\*\\) $hex" gdb_test "ptype &*c" "type = struct Member {\[\r\n \]+int z;\[\r\n\]+} &\\*" +# Check that we're able to use std::cout +gdb_test "print 'operator<<'(std::cout, one)" "\[\r\n\]+x = 9\[\r\n\]+y = 10\[\r\n\]+-------\[\r\n\]+\\\$\[0-9\]* = .*" + gdb_exit return 0 ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) 2006-08-31 11:34 ` Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) Frederic RISS @ 2006-08-31 12:09 ` Michael Veksler 2006-08-31 12:26 ` Frederic RISS 0 siblings, 1 reply; 23+ messages in thread From: Michael Veksler @ 2006-08-31 12:09 UTC (permalink / raw) To: Frederic RISS; +Cc: gdb, GDB Patches Frederic RISS wrote: > On Linux, versioned ELF symbols are stored in the static symtab with an > (@)@VERSION suffix. We store such symbols with the suffix and thus fail > to find them when looking up the real name. > > This causes failures such as the one described here: > http://www.sourceware.org/ml/gdb/2006-08/msg00244.html > > In the general case, GDB doesn't use the dynamic symtab because it > contains usually only a subset of the static table information. The > attached patch make GDB store dynamic versioned symbols. > > Maybe this is harvests too much symbols, and we should limit it to the > dynamic symbols of the main executable. It's easy enough to do, we just > need to pass the 'mainline' flag to elf_symfile_read from > elf_symtab_read. > > I've no idea if this could break something on non-Linux platforms, I've > just tested on x86-linux. > > I'm also attaching a little testsuite patch that fails for me on current > GDB and works with the patch. > > Opinions? > Great, now std::cout does not cause crashes. Still there is the problem of (gdb) p std::cout $1 = <incomplete type> But that's unrelated, right? The problem with this result is that it sometimes confuses GDB as described at the end of: http://sources.redhat.com/ml/gdb/2006-08/msg00271.html Michael ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) 2006-08-31 12:09 ` Michael Veksler @ 2006-08-31 12:26 ` Frederic RISS 2006-08-31 13:02 ` Michael Veksler 0 siblings, 1 reply; 23+ messages in thread From: Frederic RISS @ 2006-08-31 12:26 UTC (permalink / raw) To: Michael Veksler; +Cc: gdb On Thu, 2006-08-31 at 15:09 +0300, Michael Veksler wrote: > Great, now std::cout does not cause crashes. Still there is the problem of > > (gdb) p std::cout > $1 = <incomplete type> > > But that's unrelated, right? Yes, unrelated. This should work if you've got a version of libstdc++ compiled with debug info. If you don't, then GDB can't find std::cout's type. This works for me once the library is loaded (i.e. once the inferior is running): (gdb) p std::cout $1 = <incomplete type> (gdb) ptype std::cout type = struct std::basic_ostream<char,std::char_traits<char> > { <incomplete type> } (gdb) start Breakpoint 1 at 0x8048703: file cout.cc, line 11. Starting program: /home/rf23/tmp/cout/a.out main () at cout.cc:11 11 std::cout << "&std::cout is " << &std::cout << std::endl; (gdb) ptype std::cout type = class std::basic_ostream<char,std::char_traits<char> > : public virtual std::basic_ios<char,std::char_traits<char> > { public: void basic_ostream(int, const void **, class std::basic_streambuf<char,std::char_traits<char> > *); protected: void basic_ostream(int, const void **); public: ~basic_ostream(int, const void **); class std::basic_ostream<char,std::char_traits<char> > & operator<<(std::ostream& (*)(std::ostream&)); class std::basic_ostream<char,std::char_traits<char> > & operator<<(std::basic_ios<char, std::char_traits<char> >& (*)(std::basic_ios<char, std::char_traits<char> >&)); class std::basic_ostream<char,std::char_traits<char> > & operator<<(std::ios_base& (*)(std::ios_base&)); class std::basic_ostream<char,std::char_traits<char> > & operator<<(long); class std::basic_ostream<char,std::char_traits<char> > & operator<<(unsigned long); class std::basic_ostream<char,std::char_traits<char> > & operator<<(bool); class std::basic_ostream<char,std::char_traits<char> > & operator<<(short); class std::basic_ostream<char,std::char_traits<char> > & operator<<(unsigned short); class std::basic_ostream<char,std::char_traits<char> > & operator<<(int); class std::basic_ostream<char,std::char_traits<char> > & operator<<(unsigned int); class std::basic_ostream<char,std::char_traits<char> > & operator<<(long long); class std::basic_ostream<char,std::char_traits<char> > & operator<<(unsigned long long); class std::basic_ostream<char,std::char_traits<char> > & operator<<(double); class std::basic_ostream<char,std::char_traits<char> > & operator<<(float); class std::basic_ostream<char,std::char_traits<char> > ---Type <return> to continue, or q <return> to quit---q & operator<<(long douQuit (gdb) q ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) 2006-08-31 12:26 ` Frederic RISS @ 2006-08-31 13:02 ` Michael Veksler 2006-08-31 13:23 ` Frederic RISS 0 siblings, 1 reply; 23+ messages in thread From: Michael Veksler @ 2006-08-31 13:02 UTC (permalink / raw) To: Frederic RISS; +Cc: gdb Frederic RISS wrote: > On Thu, 2006-08-31 at 15:09 +0300, Michael Veksler wrote: > > >> Great, now std::cout does not cause crashes. Still there is the problem of >> >> (gdb) p std::cout >> $1 = <incomplete type> >> >> But that's unrelated, right? >> > > Yes, unrelated. > This should work if you've got a version of libstdc++ compiled with > debug info. If you don't, then GDB can't find std::cout's type. This > works for me once the library is loaded (i.e. once the inferior is > running): > > Sounds reasonable, however look at the end for my test. > (gdb) ptype std::cout > type = struct std::basic_ostream<char,std::char_traits<char> > { > <incomplete type> > } > (gdb) start > ... > (gdb) ptype std::cout > type = class std::basic_ostream<char,std::char_traits<char> > > : public virtual std::basic_ios<char,std::char_traits<char> > { > Take the two files from my test case in: http://sources.redhat.com/ml/gdb/2006-08/msg00271.html => gdb-6.5 -silent a.out Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) b 30 Breakpoint 1 at 0x8048a62: file cout-gdb.cpp, line 30. (gdb) r Starting program: /home/veksler/a.out Enter B::Print() this=0xbfffec00 Breakpoint 1, main () at cout-gdb.cpp:30 warning: Source file is more recent than executable. 30 return forceLink; (gdb) p x.Print(std::cout) Enter B::Print() this=0xbfffec00 $1 = void (gdb) p x.Print(myCout) Cannot resolve method B::Print to any overloaded instance (gdb) p x.Print(std::cout) Cannot resolve method B::Print to any overloaded instance (gdb) ============== What is going on here. Why the second Print(std::cout) no longer works? Let's try to rerun without exiting GDB: ============= (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/veksler/a.out Enter B::Print() this=0xbfffec00 Breakpoint 1, main () at cout-gdb.cpp:30 30 return forceLink; (gdb) p x.Print(std::cout) Cannot resolve method B::Print to any overloaded instance (gdb) =========== Still does not work!? Is it related to your patch? Michael ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) 2006-08-31 13:02 ` Michael Veksler @ 2006-08-31 13:23 ` Frederic RISS 2006-08-31 16:48 ` Frederic RISS 0 siblings, 1 reply; 23+ messages in thread From: Frederic RISS @ 2006-08-31 13:23 UTC (permalink / raw) To: Michael Veksler; +Cc: gdb On Thu, 2006-08-31 at 16:02 +0300, Michael Veksler wrote: > Take the two files from my test case in: > http://sources.redhat.com/ml/gdb/2006-08/msg00271.html > [...] > (gdb) p x.Print(std::cout) > Enter B::Print() this=0xbfffec00 > $1 = void > (gdb) p x.Print(myCout) > Cannot resolve method B::Print to any overloaded instance > (gdb) p x.Print(std::cout) > Cannot resolve method B::Print to any overloaded instance > (gdb) > ============== > What is going on here. Why the second Print(std::cout) no longer works? > Let's try to rerun without exiting GDB: Sorry, I can't reproduce that... this is working fine here. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) 2006-08-31 13:23 ` Frederic RISS @ 2006-08-31 16:48 ` Frederic RISS 2006-08-31 16:57 ` Daniel Jacobowitz 0 siblings, 1 reply; 23+ messages in thread From: Frederic RISS @ 2006-08-31 16:48 UTC (permalink / raw) To: Michael Veksler; +Cc: gdb On Thu, 2006-08-31 at 15:23 +0200, Frederic RISS wrote: > On Thu, 2006-08-31 at 16:02 +0300, Michael Veksler wrote: > > Take the two files from my test case in: > > http://sources.redhat.com/ml/gdb/2006-08/msg00271.html > > [...] > > (gdb) p x.Print(std::cout) > > Enter B::Print() this=0xbfffec00 > > $1 = void > > (gdb) p x.Print(myCout) > > Cannot resolve method B::Print to any overloaded instance > > (gdb) p x.Print(std::cout) > > Cannot resolve method B::Print to any overloaded instance > > (gdb) > > ============== > > What is going on here. Why the second Print(std::cout) no longer works? > > Let's try to rerun without exiting GDB: > > Sorry, I can't reproduce that... this is working fine here. In fact I managed to reproduce this behavour using a libstdc++ compiled without debug information. What's happening is quite strange, and it might very well be a GCC bug and not a GDB one. What happens is that you get 2 definitions of std::cout in the debug information of your example. One definition for each file. The gotcha is that neither of these definitions are complete. They're just empty shells specifying that the symbol is of type ``typedef basic_ostream<char,std::char_traits<char> > std::ostream'' without giving a clue to the debugger what this type is made of. I think GCC should emit a complete type because you use std::ostream in each of your files. The first 'p x.Print(std::cout)' works because at this point, the debugger has only read the full debug information of the first file. This file contains a definition of std::cout and the definition of B::Print which both point to the same instance of the std::ostream type. Being the same instance, even if the type is incomplete GDB resolves the overload correctly. After you've referenced 'myCout' which is defined in the second file, the debug info of the latter has been read, bringing a second definition of std::cout in the global scope. This second definition is found by further lookups of this symbol, and this time, the symbol type isn't the same instance as before. GDB tries to compare to incomplete types and of course it fails... I thought that using -feliminate-dwarf2-dups would help, but it doesn't. One thing we could do is to compare the TYPE_TAG_NAME for overload resoltion if there's no type name. During my tests, it was set to 'std::basic_ostream<char,std::char_traits<char> >' but I've read some comments stating that it shouldn't be used. Or maybe the bug is that we don't fill TYPE_NAME with that information? ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) 2006-08-31 16:48 ` Frederic RISS @ 2006-08-31 16:57 ` Daniel Jacobowitz 2006-08-31 17:41 ` Frédéric Riss 2006-08-31 19:48 ` Michael Veksler 0 siblings, 2 replies; 23+ messages in thread From: Daniel Jacobowitz @ 2006-08-31 16:57 UTC (permalink / raw) To: Frederic RISS; +Cc: Michael Veksler, gdb On Thu, Aug 31, 2006 at 06:48:04PM +0200, Frederic RISS wrote: > What happens is that you get 2 definitions of std::cout in the debug > information of your example. One definition for each file. The gotcha is > that neither of these definitions are complete. They're just empty > shells specifying that the symbol is of type > ``typedef basic_ostream<char,std::char_traits<char> > std::ostream'' > without giving a clue to the debugger what this type is made of. > I think GCC should emit a complete type because you use std::ostream in > each of your files. This is a deliberate choice on GCC's part, to reduce overly excessive debug information. There've been arguments about it in the past. My feeling is that we will end up with something like a -gfull argument to force the extra information to be emitted. GDB needs to work as well as possible anyway. > The first 'p x.Print(std::cout)' works because at this point, the > debugger has only read the full debug information of the first file. > This file contains a definition of std::cout and the definition of > B::Print which both point to the same instance of the std::ostream type. > Being the same instance, even if the type is incomplete GDB resolves the > overload correctly. > After you've referenced 'myCout' which is defined in the second file, > the debug info of the latter has been read, bringing a second definition > of std::cout in the global scope. This second definition is found by > further lookups of this symbol, and this time, the symbol type isn't the > same instance as before. GDB tries to compare to incomplete types and of > course it fails... This is a problem with GDB, that I've always been amazed we didn't hit more often. It's a very difficult problem and I don't really know what we should be doing about it. I don't know if there's a standard term for this, but I've called it type unification in the past. We need some way to figure out that these are the same type, to the best of our knowledge. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) 2006-08-31 16:57 ` Daniel Jacobowitz @ 2006-08-31 17:41 ` Frédéric Riss 2006-08-31 17:45 ` Daniel Jacobowitz 2006-08-31 19:48 ` Michael Veksler 1 sibling, 1 reply; 23+ messages in thread From: Frédéric Riss @ 2006-08-31 17:41 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: Frederic RISS, Michael Veksler, gdb Le jeudi 31 août 2006 à 12:57 -0400, Daniel Jacobowitz a écrit : > > GDB tries to compare to incomplete types and of > > course it fails... > > This is a problem with GDB, that I've always been amazed we didn't > hit more often. It's a very difficult problem and I don't really know > what we should be doing about it. I don't know if there's a standard > term for this, but I've called it type unification in the past. > > We need some way to figure out that these are the same type, to the > best of our knowledge. In the case of C++ classes (not POD objects, but classes with methods), the One Definition Rule gives us a way to identify those, doesn't it? I mean both classes are named basic_ostream<char,std::char_traits<char> > and live in the std namespace. All this is clearly described by the Dwarf tree structure. Of course in this case, we're speaking about incomplete types here, and we don't know they're really not simple structures. Thus applying this unification logic would is a bit dangerous. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) 2006-08-31 17:41 ` Frédéric Riss @ 2006-08-31 17:45 ` Daniel Jacobowitz 0 siblings, 0 replies; 23+ messages in thread From: Daniel Jacobowitz @ 2006-08-31 17:45 UTC (permalink / raw) To: Frédéric Riss; +Cc: Frederic RISS, Michael Veksler, gdb On Thu, Aug 31, 2006 at 07:41:20PM +0200, Frédéric Riss wrote: > In the case of C++ classes (not POD objects, but classes with methods), > the One Definition Rule gives us a way to identify those, doesn't it? I > mean both classes are named basic_ostream<char,std::char_traits<char> > > and live in the std namespace. All this is clearly described by the > Dwarf tree structure. > Of course in this case, we're speaking about incomplete types here, and > we don't know they're really not simple structures. Thus applying this > unification logic would is a bit dangerous. Exactly. It is impossible to get this reliably right for incomplete types. However, I think we should do the best we can. I haven't thought much about the implementation details yet though. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) 2006-08-31 16:57 ` Daniel Jacobowitz 2006-08-31 17:41 ` Frédéric Riss @ 2006-08-31 19:48 ` Michael Veksler 2006-08-31 19:52 ` Daniel Jacobowitz 1 sibling, 1 reply; 23+ messages in thread From: Michael Veksler @ 2006-08-31 19:48 UTC (permalink / raw) To: Frederic RISS, gdb Daniel Jacobowitz wrote: > On Thu, Aug 31, 2006 at 06:48:04PM +0200, Frederic RISS wrote: > >> What happens is that you get 2 definitions of std::cout in the debug >> information of your example. One definition for each file. The gotcha is >> that neither of these definitions are complete. They're just empty >> ... > This is a deliberate choice on GCC's part, to reduce overly excessive > debug information. There've been arguments about it in the past. My > From bits/ostream.tcc header file: // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. // NB: This syntax is a GNU extension. #if _GLIBCXX_EXTERN_TEMPLATE extern template class basic_ostream<char>; > feeling is that we will end up with something like a -gfull argument > to force the extra information to be emitted. GDB needs to work as > well as possible anyway. > > Reading it more, one can force full instantiation of ostream: g++ -g -D_GLIBCXX_EXTERN_TEMPLATE=0 myCout.cpp cout-gdb.cpp Now everything works, and it is not that much bigger. >> The first 'p x.Print(std::cout)' works because at this point, the >> debugger has only read the full debug information of the first file. >> This file contains a definition of std::cout and the definition of >> B::Print which both point to the same instance of the std::ostream type. >> Being the same instance, even if the type is incomplete GDB resolves the >> overload correctly. >> After you've referenced 'myCout' which is defined in the second file, >> the debug info of the latter has been read, bringing a second definition >> of std::cout in the global scope. This second definition is found by >> further lookups of this symbol, and this time, the symbol type isn't the >> same instance as before. GDB tries to compare to incomplete types and of >> course it fails... >> > > This is a problem with GDB, that I've always been amazed we didn't > hit more often. It's a very difficult problem and I don't really know > what we should be doing about it. I don't know if there's a standard > term for this, but I've called it type unification in the past. > > We need some way to figure out that these are the same type, to the > best of our knowledge. > > It sounds similar to the problem of GDB on AIX (with XCOFF). There is a PR on this: http://sources.redhat.com/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=1170&return_url=http%3A%2F%2Fsources.redhat.com%2Fcgi-bin%2Fgnatsweb.pl%3Fdatabase%3Dgdb%26cmd%3Dsubmit%2520query%26category%3Dall%26severity%3Dall%26priority%3Dall%26responsible%3Dall%26submitter_id%3Dall%26state%3Dall%26ignoreclosed%3DIgnore%2520Closed%26class%3Dall%26synopsis%3D%26multitext%3DAIX%26columns%3Dcategory%26columns%3Dstate%26columns%3Dclass%26columns%3Dresponsible%26columns%3Dsynopsis%26displaydate%3DDisplay%2520Current%2520Date%26sortby%3DResponsible%26.cgifields%3Ddisplaydate%26.cgifields%3Dignoreclosed%26.cgifields%3Doriginatedbyme%26.cgifields%3Dcolumns It happens when debug information is ordered in a different way than GDB expects. This is something that native /bin/as does, and is not a fault of gcc. According to X-COFF spec, the assembler is allowed to do this reordering. I guess that this issue happens in different places GDB, but it still has similar sound - GDB is sensitive to the order it reads debug information. -- Michael ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) 2006-08-31 19:48 ` Michael Veksler @ 2006-08-31 19:52 ` Daniel Jacobowitz 0 siblings, 0 replies; 23+ messages in thread From: Daniel Jacobowitz @ 2006-08-31 19:52 UTC (permalink / raw) To: Michael Veksler; +Cc: Frederic RISS, gdb On Thu, Aug 31, 2006 at 10:48:43PM +0300, Michael Veksler wrote: > >This is a deliberate choice on GCC's part, to reduce overly excessive > >debug information. There've been arguments about it in the past. My > > > From bits/ostream.tcc header file: > // Inhibit implicit instantiations for required instantiations, > // which are defined via explicit instantiations elsewhere. > // NB: This syntax is a GNU extension. > #if _GLIBCXX_EXTERN_TEMPLATE > extern template class basic_ostream<char>; No, that's irrelevant to what I was talking about; some parts of the debug info are done only with the class's key method. But... > >feeling is that we will end up with something like a -gfull argument > >to force the extra information to be emitted. GDB needs to work as > >well as possible anyway. > > > > > Reading it more, one can force full instantiation of ostream: > g++ -g -D_GLIBCXX_EXTERN_TEMPLATE=0 myCout.cpp cout-gdb.cpp > Now everything works, and it is not that much bigger. ...this causes the key method to be in the header for every compilation unit, IIUC. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: How to call operator<< functions? 2006-08-30 10:11 How to call operator<< functions? Michael Veksler 2006-08-30 11:13 ` Frederic RISS @ 2006-08-30 12:46 ` Daniel Jacobowitz 2006-08-30 20:05 ` Michael Veksler 1 sibling, 1 reply; 23+ messages in thread From: Daniel Jacobowitz @ 2006-08-30 12:46 UTC (permalink / raw) To: Michael Veksler; +Cc: gdb As a general note: the most useful thing to accompany any bug report is a test case! :-) We can't fix them without tests. On Wed, Aug 30, 2006 at 01:11:43PM +0300, Michael Veksler wrote: > Passing 'std::cout' seems impossible. Any attempt to pass std::cout > crashes. To overcome this I define my own global > ostream gecLog(cout.rdbuf()); > (or something similar) and recompile the code. This lets me pass gecLog > instead of cout, and it _sometimes_ works: Fred's response seems reasonable; that might be the problem, or it might be something else. If you have a testcase, please post it. > (gdb) p pd.Print(gecLog) > Cannot resolve method (null)Print to any overloaded instance Ditto. I've never seen this error before. > -------------------------------------- > I wanted to do the same for operator<<: > (gdb) p 'operator<<(std::ostream&, MyClass const&)' > $17 = {ostream &(ostream &, const class MyClass > &)} 0x8068a00 <operator<<(std::ostream&, MyClass const&)> > (gdb) p $17(gecLog, *pd) > Program received signal SIGSEGV, Segmentation fault. > ----------------------- You can just use "print gecLog << *pd". Does that work better? Anyway, I would have expected calling the operator to work. With tests for these bugs we can make the next GDB release the best ever for C++. > Print(cerr). Sometimes, while debugging a piece of code, that a vital > object has <<, but no DebugPrint, and *that* really frustrates me - > especially when I loose a 60 minutes debugging session to a SIGSEGV. You might want to use set unwindonsignal, then, as it suggests. There's some risk associated, but it usually works. You can also use "return" to get out of the called function, but make sure you tell GDB not to pass the sigsegv when you continue. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: How to call operator<< functions? 2006-08-30 12:46 ` How to call operator<< functions? Daniel Jacobowitz @ 2006-08-30 20:05 ` Michael Veksler 2006-08-30 20:24 ` Daniel Jacobowitz 0 siblings, 1 reply; 23+ messages in thread From: Michael Veksler @ 2006-08-30 20:05 UTC (permalink / raw) To: Michael Veksler, gdb Daniel Jacobowitz wrote: > As a general note: the most useful thing to accompany any bug report is > a test case! :-) We can't fix them without tests. > You are right. At the end of this mail there is a complete test case for about 50% of the reported problems. I'll have to work harder for a simple test case for the other 50%. > On Wed, Aug 30, 2006 at 01:11:43PM +0300, Michael Veksler wrote: > >> I wanted to do the same for operator<<: >> (gdb) p 'operator<<(std::ostream&, MyClass const&)' >> $17 = {ostream &(ostream &, const class MyClass >> &)} 0x8068a00 <operator<<(std::ostream&, MyClass const&)> >> (gdb) p $17(gecLog, *pd) >> Program received signal SIGSEGV, Segmentation fault. >> > You can just use "print gecLog << *pd". Does that work better? > Anyway, I would have expected calling the operator to work. > > Does not work, look at my complete report below. > With tests for these bugs we can make the next GDB release the > best ever for C++. > Would be great. >> Print(cerr). Sometimes, while debugging a piece of code, that a vital >> object has <<, but no DebugPrint, and *that* really frustrates me - >> especially when I loose a 60 minutes debugging session to a SIGSEGV. >> > > You might want to use set unwindonsignal, then, as it suggests. > There's some risk associated, but it usually works. You can also > use "return" to get out of the called function, but make sure you tell > GDB not to pass the sigsegv when you continue. > > Thanks this might help 95% of the time. In some cases I get std::bad_alloc uncaught exception during Print (again, when it should have worked). I doubt that these 5% of crashes can be recovered from. Not a big deal, as it is only about 5..10%. The complete test case is comprised of c++ source file (compiled with RHEL4's gcc-3.4 using "g++ -g "), and of screen trace. Should I open a PR, or several PRs? Maybe someone else that can split my single test case into subtopics, each to fit its own PR? Does it make sense to create test case for the missing 50% of the crashes I have seen, or will it be better to wait and see if they get fixed by other PRs? =================== => cat cout-gdb.cpp #include <iostream> using namespace std; ostream myCout(cout.rdbuf()); struct A { virtual void Print(ostream &out) const = 0; }; struct B : public A { virtual void Print(ostream &out) const { out << "Enter B::Print() this=" << this << endl; } }; ostream & operator<<(ostream & out, const A& data) { data.Print(out); } int main() { B x; const A & ref_x = x; ref_x.Print(myCout); return 0; } => gdb-6.5 -silent a.out Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) b 27 Breakpoint 1 at 0x8048a26: file cout-gdb.cpp, line 27. (gdb) r Starting program: /home/veksler/a.out Enter B::Print() this=0xbfffec00 Breakpoint 1, main () at cout-gdb.cpp:27 27 return 0; (gdb) p x.Print(myCout) Program received signal SIGSEGV, Segmentation fault. 0x0042cf88 in std::ostream::sentry::sentry () from /usr/lib/libstdc++.so.6 The program being debugged was signaled while in a function called from GDB. GDB remains in the frame where the signal was received. To change this behavior use "set unwindonsignal on" Evaluation of the expression containing the function (B::Print(std::ostream&) const) will be abandoned. (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/veksler/a.out Enter B::Print() this=0xbfffec00 Breakpoint 1, main () at cout-gdb.cpp:27 27 return 0; (gdb) p ref_x.Print(myCout) Program received signal SIGSEGV, Segmentation fault. 0x0042cf88 in std::ostream::sentry::sentry () from /usr/lib/libstdc++.so.6 The program being debugged was signaled while in a function called from GDB. GDB remains in the frame where the signal was received. To change this behavior use "set unwindonsignal on" Evaluation of the expression containing the function (B::Print(std::ostream&) const) will be abandoned. (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/veksler/a.out Enter B::Print() this=0xbfffec00 Breakpoint 1, main () at cout-gdb.cpp:27 27 return 0; (gdb) p ref_x.Print Cannot take address of method Print. (gdb) p x.Print $1 = &B::Print(std::ostream&) const (gdb) p $1(&x, myCout) Enter B::Print() this=0xbfffec00 $2 = void (gdb) set $a=x.Print (gdb) p $a(&x, myCout) Program received signal SIGSEGV, Segmentation fault. 0x08527e78 in ?? () The program being debugged was signaled while in a function called from GDB. GDB remains in the frame where the signal was received. To change this behavior use "set unwindonsignal on" Evaluation of the expression containing the function (at 0x8527e78) will be abandoned. (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/veksler/a.out Enter B::Print() this=0xbfffec00 Breakpoint 1, main () at cout-gdb.cpp:27 27 return 0; (gdb) p myCout << x Structure has no component named operator<<. (gdb) p 'operator<<(std::ostream&, A const&)' (myCout, x) Enter B::Print() this=0xbfffec00 $3 = (ostream &) @0x8049260: <incomplete type> <<<<<< The above sometimes won't work (will be reproduced later) >>>> (gdb) p &'_ZSt4cout@@GLIBCXX_3.4' $4 = (<data variable, no debug info> *) 0x8049160 (gdb) p &std::cout $5 = (ostream *) 0x47cfc0 (gdb) p x.Print $6 = &B::Print(std::ostream&) const (gdb) p $6(&x, '_ZSt4cout@@GLIBCXX_3.4') Enter B::Print() this=0xbfffec00 $7 = void (gdb) p $6(&x, std::cout) Program received signal SIGSEGV, Segmentation fault. ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: How to call operator<< functions? 2006-08-30 20:05 ` Michael Veksler @ 2006-08-30 20:24 ` Daniel Jacobowitz 2006-08-30 20:45 ` Michael Veksler 0 siblings, 1 reply; 23+ messages in thread From: Daniel Jacobowitz @ 2006-08-30 20:24 UTC (permalink / raw) To: Michael Veksler; +Cc: gdb On Wed, Aug 30, 2006 at 11:05:43PM +0300, Michael Veksler wrote: > Should I open a PR, or several PRs? > Maybe someone else that can split my single test case into subtopics, > each to fit its own PR? > Does it make sense to create test case for the missing 50% of the > crashes I have seen, or will it be better to wait and see if they get > fixed by other PRs? Let's look at one thing at a time. The first two crashes should, I think, be addressed by this patch. Could you try it? Some of the later crashes are caused by this: (gdb) set $a = x.Print (gdb) p $a $7 = <error reading variable> I have a whole lot of patches related to member functions, that I haven't had time to merge yet - and I would not like to look at this until I've done that. -- Daniel Jacobowitz CodeSourcery 2006-08-30 Daniel Jacobowitz <dan@codesourcery.com> * infcall.c (call_function_by_hand): Check for function pointer types. Index: src/gdb/infcall.c =================================================================== --- src.orig/gdb/infcall.c 2006-08-30 16:19:00.000000000 -0400 +++ src/gdb/infcall.c 2006-08-30 16:18:43.000000000 -0400 @@ -337,6 +337,9 @@ call_function_by_hand (struct value *fun struct cleanup *caller_regcache_cleanup; struct frame_id dummy_id; + if (TYPE_CODE (ftype) == TYPE_CODE_PTR) + ftype = check_typedef (TYPE_TARGET_TYPE (ftype)); + if (!target_has_execution) noprocess (); ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: How to call operator<< functions? 2006-08-30 20:24 ` Daniel Jacobowitz @ 2006-08-30 20:45 ` Michael Veksler 2006-08-30 20:54 ` Daniel Jacobowitz 0 siblings, 1 reply; 23+ messages in thread From: Michael Veksler @ 2006-08-30 20:45 UTC (permalink / raw) To: Michael Veksler, gdb Daniel Jacobowitz wrote: > On Wed, Aug 30, 2006 at 11:05:43PM +0300, Michael Veksler wrote: > > Let's look at one thing at a time. > > The first two crashes should, I think, be addressed by this patch. > Could you try it? > With the patch it works: (gdb) p x.Print(myCout) Enter B::Print() this=0xbfffec00 $1 = void (gdb) p ref_x.Print(myCout) Enter B::Print() this=0xbfffec00 $2 = void Great progress. The most annoying and common failures I have used to be seeing is no more. The other annoying issues sorted by decreasing annoyance : - this->Print is not always found (I'll try to create a small test-case later). - std::cout related crashes - print myCout << x --- won't work need to resort to print 'operator<<........'(myCout, x) > Some of the later crashes are caused by this: > > (gdb) set $a = x.Print > (gdb) p $a > $7 = <error reading variable> > > I have a whole lot of patches related to member functions, that I > haven't had time to merge yet - and I would not like to look at this > until I've done that. > > This is less critical since this was an attempt to overcome the other bug. Thanks, Michael ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: How to call operator<< functions? 2006-08-30 20:45 ` Michael Veksler @ 2006-08-30 20:54 ` Daniel Jacobowitz 2006-08-31 12:05 ` Michael Veksler 0 siblings, 1 reply; 23+ messages in thread From: Daniel Jacobowitz @ 2006-08-30 20:54 UTC (permalink / raw) To: Michael Veksler; +Cc: gdb On Wed, Aug 30, 2006 at 11:45:33PM +0300, Michael Veksler wrote: > Great progress. The most annoying and common failures I have used to be > seeing is no more. I will test and commit the patch (but not right this moment). > The other annoying issues sorted by decreasing annoyance : > - this->Print is not always found (I'll try to create a small test-case > later). I think my other changes will help here, though I'm not sure. > - std::cout related crashes Fred's pegged this one I suspect. This is a serious bug and we need to fix it, but it will be a bit tricky. > - print myCout << x --- won't work need to resort to > print 'operator<<........'(myCout, x) I think that foo::operator<< is supported, but operator<<(foo&,...) isn't. Or else something's wrong with the support. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: How to call operator<< functions? 2006-08-30 20:54 ` Daniel Jacobowitz @ 2006-08-31 12:05 ` Michael Veksler 0 siblings, 0 replies; 23+ messages in thread From: Michael Veksler @ 2006-08-31 12:05 UTC (permalink / raw) To: Michael Veksler, gdb Daniel Jacobowitz wrote: > On Wed, Aug 30, 2006 at 11:45:33PM +0300, Michael Veksler wrote: >> Great progress. The most annoying and common failures I have used to >> be seeing is no more. > > I will test and commit the patch (but not right this moment). > No hurry, I have managed for eight years, I can cope with it a bit more. >> The other annoying issues sorted by decreasing annoyance : >> - this->Print is not always found (I'll try to create a small >> test-case later). > > I think my other changes will help here, though I'm not sure. I doubt they will. I have produced a complete test case for that. See below. >> - std::cout related crashes > > Fred's pegged this one I suspect. This is a serious bug and we need to > fix it, but it will be a bit tricky. My following test case may be related to this. >> - print myCout << x --- won't work need to resort to >> print 'operator<<........'(myCout, x) > > I think that foo::operator<< is supported, but operator<<(foo&,...) > isn't. Or else something's wrong with the support. Well, it works without the std:: as the prefix of operator<<. I hoped that just using << (as in C++) would just work. ========== Here is the test case. => cat cout-gdb2.cpp #include <iostream> using namespace std; extern int forceLink; struct A { virtual void Print(ostream &out) const = 0; }; struct B : public A { virtual void Print(ostream &out) const ; }; void B::Print(ostream &out) const { out << "Enter B::Print() this=" << this << endl; } ostream & operator<<(ostream & out, const A& data) { data.Print(out); } int main() { B x; const A & ref_x = x; ref_x.Print(cout); return forceLink; } => cat myCout.cpp #include <iostream> using namespace std; ostream myCout(cout.rdbuf()); // A trick to force the linker put this object file into the executable int forceLink=0; => g++ -g cout-gdb.cpp myCout.cpp => gdb-6.5 -silent a.out Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) b 30 Breakpoint 1 at 0x8048a62: file cout-gdb.cpp, line 30. (gdb) r Starting program: /home/veksler/a.out Enter B::Print() this=0xbfffec00 Breakpoint 1, main () at cout-gdb.cpp:30 30 return forceLink; (gdb) p myCout $1 = <incomplete type> (gdb) p x.Print(myCout) Cannot resolve method B::Print to any overloaded instance (gdb) p x.Print $2 = &B::Print(std::ostream&) const (gdb) p $2(&x, myCout) Enter B::Print() this=0xbfffec00 $3 = void (gdb) ^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2006-08-31 19:52 UTC | newest] Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2006-08-30 10:11 How to call operator<< functions? Michael Veksler 2006-08-30 11:13 ` Frederic RISS 2006-08-30 13:30 ` Frederic RISS 2006-08-30 13:40 ` Breakpoint Handling in GDB Veenu Verma (AS/EAB) 2006-08-30 13:43 ` Daniel Jacobowitz 2006-08-30 20:30 ` Michael Snyder 2006-08-31 11:34 ` Get versioned minsyms from dynamic symtab (Was: Re: How to call operator<< functions?) Frederic RISS 2006-08-31 12:09 ` Michael Veksler 2006-08-31 12:26 ` Frederic RISS 2006-08-31 13:02 ` Michael Veksler 2006-08-31 13:23 ` Frederic RISS 2006-08-31 16:48 ` Frederic RISS 2006-08-31 16:57 ` Daniel Jacobowitz 2006-08-31 17:41 ` Frédéric Riss 2006-08-31 17:45 ` Daniel Jacobowitz 2006-08-31 19:48 ` Michael Veksler 2006-08-31 19:52 ` Daniel Jacobowitz 2006-08-30 12:46 ` How to call operator<< functions? Daniel Jacobowitz 2006-08-30 20:05 ` Michael Veksler 2006-08-30 20:24 ` Daniel Jacobowitz 2006-08-30 20:45 ` Michael Veksler 2006-08-30 20:54 ` Daniel Jacobowitz 2006-08-31 12:05 ` Michael Veksler
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox