Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

hook operator new

1 view
Skip to first unread message

skaller

unread,
Oct 14, 2007, 8:06:25 AM10/14/07
to
So I have another (yes I tried to find the answer but haven't yet):
how can I hook operator new()?

With malloc() we have __builtin_malloc which is a single global variable
available to all shared libraries. That's cool but there seems
no equivalent for operator new().

operator new() is a weak symbol in Elf isn't it? So it can be replaced
by a user function globally? (even in by a shared library?)

[Of course C++ Standard is quite stupid here. If you replace operator
new, how do you call the original?]

--
John Skaller <skaller at users dot sf dot net>
Try Felix, the successor to C++ http://felix.sf.net

Paul Pluzhnikov

unread,
Oct 14, 2007, 3:18:09 PM10/14/07
to
skaller <ska...@users.sf.net> writes:

> So I have another (yes I tried to find the answer but haven't yet):
> how can I hook operator new()?

This is very system-dependent.
Are you interested in Linux-only answer, or in gcc/any answer?

> With malloc() we have __builtin_malloc which is a single global variable
> available to all shared libraries.

Only on systems using glibc, and only when using dynamic linking.

> operator new() is a weak symbol in Elf isn't it?

Not for any of my g++ versions:

$ nm -A /usr/local/gcc-*/lib/libstdc++*so | grep _Znwj
/usr/local/gcc-3.1/lib/libstdc++.so:00037e20 T _Znwj
/usr/local/gcc-3.1/lib/libstdc++.so:00037ef0 T _ZnwjRKSt9nothrow_t
/usr/local/gcc-3.2/lib/libstdc++.so:00033570 T _Znwj
/usr/local/gcc-3.2/lib/libstdc++.so:00033640 T _ZnwjRKSt9nothrow_t
/usr/local/gcc-3.3.2/lib/libstdc++.so:000542b0 T _Znwj
/usr/local/gcc-3.3.2/lib/libstdc++.so:00054360 T _ZnwjRKSt9nothrow_t
/usr/local/gcc-3.3/lib/libstdc++.so:00053bd0 T _Znwj
/usr/local/gcc-3.3/lib/libstdc++.so:00053c80 T _ZnwjRKSt9nothrow_t
/usr/local/gcc-3.4.0/lib/libstdc++.so:00067330 T _Znwj
/usr/local/gcc-3.4.0/lib/libstdc++.so:000673e0 T _ZnwjRKSt9nothrow_t
/usr/local/gcc-3.4.3/lib/libstdc++.so:00066e50 T _Znwj
/usr/local/gcc-3.4.3/lib/libstdc++.so:00066f00 T _ZnwjRKSt9nothrow_t
/usr/local/gcc-3.4.6/lib/libstdc++.so:000669f0 T _Znwj
/usr/local/gcc-3.4.6/lib/libstdc++.so:00066aa0 T _ZnwjRKSt9nothrow_t
/usr/local/gcc-4.0.0/lib/libstdc++.so:00070180 T _Znwj
/usr/local/gcc-4.0.0/lib/libstdc++.so:00070220 T _ZnwjRKSt9nothrow_t
/usr/local/gcc-4.1.1/lib/libstdc++.so:00071750 T _Znwj
/usr/local/gcc-4.1.1/lib/libstdc++.so:00071800 T _ZnwjRKSt9nothrow_t
/usr/local/gcc-4.2.0/lib/libstdc++.so:00072630 T _Znwj
/usr/local/gcc-4.2.0/lib/libstdc++.so:000726d0 T _ZnwjRKSt9nothrow_t
/usr/local/gcc-4.3-20061104/lib/libstdc++.so:000736d0 T _Znwj
/usr/local/gcc-4.3-20061104/lib/libstdc++.so:00073770 T _ZnwjRKSt9nothrow_t

None of the above is weak...

> So it can be replaced by a user function globally? (even in by a shared library?)

Weak here doesn't mean what you appear to think it means.

Even though above symbols are all strong, they can still be
interposed by a user library, *provided* that library appears before
libstdc++ in runtime linker search list. To achive that, make sure
your interposer is before -lstdc++ on the link line.

> [Of course C++ Standard is quite stupid here. If you replace operator
> new, how do you call the original?]

The "standard" Linux/Solaris technique is to use dlsym(RTLD_NEXT, ...)

Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.

skaller

unread,
Oct 15, 2007, 11:51:54 AM10/15/07
to
On Sun, 14 Oct 2007 12:18:09 -0700, Paul Pluzhnikov wrote:

> skaller <ska...@users.sf.net> writes:
>
>> So I have another (yes I tried to find the answer but haven't yet): how
>> can I hook operator new()?
>
> This is very system-dependent.
> Are you interested in Linux-only answer, or in gcc/any answer?

All platforms all compilers, incl. MSVC++ .. but just
Linux/gcc will do for a start :)

>> With malloc() we have __builtin_malloc which is a single global
>> variable available to all shared libraries.
>
> Only on systems using glibc, and only when using dynamic linking.

Really? Doesn't work for static links .. hmm.



>> operator new() is a weak symbol in Elf isn't it?
>
> Not for any of my g++ versions:

Then, how can one replace it? Because that definitely does work
in a simple program.

>> So it can be replaced by a user function globally? (even in by a shared
>> library?)
>
> Weak here doesn't mean what you appear to think it means.
>
> Even though above symbols are all strong, they can still be interposed
> by a user library, *provided* that library appears before libstdc++ in
> runtime linker search list. To achive that, make sure your interposer is
> before -lstdc++ on the link line.

Well, -lstdc++ is never given on the link line, in fact, there's
no link line since most people use gcc as the link driver.

>> [Of course C++ Standard is quite stupid here. If you replace operator
>> new, how do you call the original?]
>
> The "standard" Linux/Solaris technique is to use dlsym(RTLD_NEXT, ...)

Which would only work with dynamic linkage. Hmm .. I seem to recall
Boehm gc (which has to do all this somehow) uses a special file
defining real_malloc() by calling malloc() .. and linking that
before the code that defines malloc() by suballocating and sometimes
calling real_malloc() .. ouch.

0 new messages