I have a somewhat large project that I am working on and I've discovered that someone added some code something similar to this:
std::cout << std::hex << variable << endl;
Aside from grepping through all the cout calls and manually looking at each one, is there a way to determine which offending cout line left the output stream's base as hex?
It seems that there's many different ways of setting the base so setting a breakpoint on a single function call doesn't seem to work. e.g.:
... << std::hex << ...
... << setbase(16) << ...
std::cout.setf ( std::ios::hex, std::ios::basefield );
- etc.
Is there any quick way i can tell what variable internally libstdc++ is using to store the base variable so i can set a data breakpoint on it?
UPDATE:
After playing around with the code I was finally able to come up with the solution using in part both answers from perreal and Employed Russian. Here is what I did:
First I added the following code inside my program so I could break and step into the function to get the address of the cout flags variable (_M_flags).
std::ios_base::fmtflags f;
f = std::cout.flags();
I set a breakpoint on the second line and stepped into the function and got the following libstdc++ code:
// [27.4.2.2] fmtflags state functions
/**
* @brief Access to format flags.
* @return The format control flags for both input and output
*/
fmtflags
flags() const
{ return _M_flags; }
Unfortunately gdb was unable to print out this variable but by going to the disassembly view I was able to pinpoint the address used by _M_flags:
x0x84ca2e8 <std::ios_base::flags() const> push %ebp
x0x84ca2e9 <std::ios_base::flags() const+1> mov %esp,%ebp
x0x84ca2eb <std::ios_base::flags() const+3> mov 0x8(%ebp),%eax
>x0x84ca2ee <std::ios_base::flags() const+6> mov 0xc(%eax),%eax
x0x84ca2f1 <std::ios_base::flags() const+9> pop %ebp
x0x84ca2f2 <std::ios_base::flags() const+10> ret
0xc(%eax)
contained the address of _M_flags.
After I got the address, it was fairly trivial to set a conditional hardware watchpoint on it to see when the hex bit changes and track down the offending code.
It turns out a .so object loaded at runtime via dlopen was the culprit.
I ended up using Boost IO State Savers as referenced by this question to resolve the issue.