This is the mail archive of the gdb@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]

Re: How to call operator<< functions?


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.


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