This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


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

operator<< and calls to operator new.


Allow me to explain the background of my problem.

Introduction
------------

I have written a "C++ debugging support library" that allows one to write
debug output to an arbitrary ostream.

Among other things, the library does memory allocation checks and hence
overloads operator new and defines its own malloc implementation in order
to have control over memory allocations being done.

Debug output (writing to an ostream) causes memory allocations, and
doing memory allocations does debug output; this loop is easily broken
by introducing two states in which memory can be allocated:
"user space" allocations and "internal" allocations.  Internal allocations
do not cause debug output and do not cause other allocations (actually,
they are not stored, not checked, nothing: just a plain call to libc's
malloc).  Every internal allocation must be also deallocated with the
'internal' flag set of course.

The Facts
---------

In the end we have three types of allocations:
1) "user space" allocations (simple allocations done from the application).
2) "internal" allocations (allocations done from the internal malloc routine).
3) "library call" allocations (allocations caused by writing debug output
   that we don't want to cause additional debug output: that would look ugly).

Moreover, we have two types of debug output:
4) "user space" debug output.
5) Debug output that is under my control, (possibly) done from within the
   internal malloc routine.

These have the following relationships (where '-->' means: causes):

1 --> 2 and 5
2 --> nothing
3 --> 2
4 --> 1 or 3
5 --> 3

Notes & Remarks
---------------

We can't allow '3' to cause '1' because then have a loop: 3 --> 1 --> 5 --> 3,
which would cause an infinite loop of events.

With this sheme, it is easy to see that we need both, 4 and 5.  If there was
no distinction between them (if 5 == 4) then we'd have the loop: 4 --> 1 --> 5.
Note that is the NEED for 4 --> 1 (instead of 4 --> 2) where a user calls a
user space function that allocates memory while writing debug output
[ Dout(dc::notice, "Hello" << world() ); ].  But any other allocations, like
the enlargement of a stringstream buffer if that is what we're writing to
should NOT be visible (3).

Type 3 can arguably be replaced by a 2 without causing loops, but it remains
a fact that we'd have to detect the event "allocations caused by writing debug
output" and we ARE stuck with the 4 --> 1 or 3 (or 4 --> 1 or '2').

The problem
-----------

Now, because libstdc++ version 3 doesn't give me the option to intercept
ALL memory allocations while calling any operator<<, there is no way I can
make the distinction between 1 and 3 while doing "user space" debug output (4).

I've thought about this for weeks now and I am stuck.  The only solution seems
to write my own implementation where I am sure I can control ALL memory allocations
done (as a result of calling any operator<<); but IS that possible?  I haven't
been able to exactly analyse what happens, because gdb is for some reason not
able to debug this.  If the allocations occur as part of 'ostream' then I am
*really* stuck; after all, I can't write my own implementation of ostream: I need
to offer the users to write to an ostream, period.

Conclusion?
-----------

If the allocations are solely the result of using a 'basic_string' as buffer,
then I still have a chance, by writing my own stringstream and stringbuf.

If someone knows which IO objects of libstdc++ call operator new directly and
can enlighten me, I'd appreciate that.

-- 
Carlo Wood <carlo@alinoe.com>


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