overloading operator new in shared libs (madness)

overloading operator new in shared libs (madness)

Post by Michael Bruschkewit » Sat, 14 Jun 2003 21:14:23



Hello,
I have to combine different libs which each overloading operator new and
delete. I made them shared, and everything works fine when I'm using ld
for the creation of the shared libs.

Unfortunaltely, this keeps static objects in the libs un-constructed.

So I used gcc -fpic -shared for creating the libs, but this merges the
overloaded operators.
w/o -fpic I get these errors about relocation of constants.
I read about an option -z text for this case, but I can't find docu for
this option in man gcc.

I append an example output and example file, the content of f1.cpp and
f2.cpp is similar to the functions in _main.cpp, except the output-
strings.

I searched google for hours, but I couldn't find a solution.

Regards,
Michael Bruschkewitz

gcc3.2.1,Solaris 8 on Intel

//////////////// _main.cpp ///////////////////////
#include "f1.h"
#include "f2.h"
#include <iostream>
void * operator new(size_t sz) throw(std::bad_alloc) {
        printf("new (_main.cpp) called, sz = %d\n",sz);
        return malloc(sz); }
void operator delete(void * p) throw() {
        printf("delete (_main.cpp) called, content = %d\n",(*(int*)p));
        free(p); }
void f() {
        printf("in f()\n");
        int * p = new int;
        *p = 42;
        delete p;
        printf("leave f()\n"); }
int main() {
        f();    f1();   f2();  
        return 0; }
/////////////////  sample output ////////////////////
bash-2.03$ make
gcc -g -c _main.cpp -o _main.o
gcc -g -c f1.cpp -o f1.o
ld -G f1.o -o s1.so
gcc -g -c f2.cpp -o f2.o
ld -G f2.o -o s2.so
gcc s1.so s2.so _main.o -lstdc++ -o t1

bash-2.03$ ./t1
new (_main.cpp) called, sz = 2    // possibly from iostream
new (_main.cpp) called, sz = 2  // possibly from iostream
in f()
new (_main.cpp) called, sz = 4
delete (_main.cpp) called, content = 42
leave f()
in f1()
new (f1.cpp) called, sz = 4
delete (f1.cpp) called, content = 11
leave f1()
in f2()
new (f2.cpp) called, sz = 4
delete (f2.cpp) called, content = 22
leave f2()

bash-2.03$ make clean
bash-2.03$ # change makefile
bash-2.03$ make
gcc -g -fPIC -c _main.cpp -o _main.o
gcc -g -fPIC -c f1.cpp -o f1.o
gcc -fPIC -shared -G f1.o -o s1.so
gcc -g -fPIC -c f2.cpp -o f2.o
gcc -fPIC -shared -G f2.o -o s2.so
gcc s1.so s2.so _main.o -lstdc++ -o t1

bash-2.03$ ./t1
new (_main.cpp) called, sz = 2
new (_main.cpp) called, sz = 2
in f()
new (_main.cpp) called, sz = 4
delete (_main.cpp) called, content = 42
leave f()
in f1()
new (_main.cpp) called, sz = 4
delete (_main.cpp) called, content = 11
leave f1()
in f2()
new (_main.cpp) called, sz = 4
delete (_main.cpp) called, content = 22
leave f2()
bash-2.03$

 
 
 

overloading operator new in shared libs (madness)

Post by Paul Pluzhnik » Sun, 15 Jun 2003 07:55:43



> I have to combine different libs which each overloading operator new and
> delete.

This is a sure path to madness. Why do you want to do that?

Quote:> I made them shared, and everything works fine when I'm using ld
> for the creation of the shared libs.

What is your definition of "works fine" ?

Quote:> So I used gcc

Using gcc to build C++ is a *bad idea* ... Use g++ instead.

Quote:>  -fpic -shared for creating the libs, but this merges the
> overloaded operators.

Huh? What do you mean by "merges"?

Quote:> w/o -fpic I get these errors about relocation of constants.
> I read about an option -z text for this case, but I can't find docu for
> this option in man gcc.

The '-z text' is not a gcc option. Try "man ld".

The '-z text' is something gcc adds to shared links. Adding it again will
not help you with "text relocations remain". And you *should* build
shared libraries with -fPIC.

Quote:> I append an example output and example file, the content of f1.cpp and
> f2.cpp is similar to the functions in _main.cpp, except the output-
> strings.

You didn't explain what behaviour you are trying to achieve, nor what
behaviour you currently have. It is rather difficult to suggest a solution
to an unknown problem.

Quote:> bash-2.03$ ./t1
> new (_main.cpp) called, sz = 2
> new (_main.cpp) called, sz = 2
> in f()
> new (_main.cpp) called, sz = 4

Ok, we can deduce that the "sane" thing is happening -- the first instance
of ::new() (the one from main executable) is used everywhere.

Apparently you are trying to achieve Win32-like behaviour, where each
DLL uses the copy "statically linked" into it (which is what happens
without /MD flag).

If indeed that was your goal, read "man ld" and look for -Bsymbolic
(note: use -Wl,-Bsymbolic when using gcc/g++, as -B means something totally
different to gcc). Also read the "linker scripts" section in Solaris
"Linker and Libraries Guide".

Cheers,

 
 
 

overloading operator new in shared libs (madness)

Post by Michael Bruschkewi » Mon, 16 Jun 2003 00:40:22




> > I have to combine different libs which each overloading operator new and
> > delete.
> This is a sure path to madness. Why do you want to do that?

I'm emulating a embedded API on Win2k, Solaris for testing and
debugging purposes.
The original source code contains overloaded new/delete.
The allocation space for new is limited, delete is forbidden
(-->exit).
The emulation (which resides in a DLL, or shared object) uses STL,
which uses new/delete.
This was the base problem, shared object should not use overloaded
operator.

Quote:> > I made them shared, and everything works fine when I'm using ld
> > for the creation of the shared libs.

> What is your definition of "works fine" ?

Each lib uses its own operators.

Quote:> >  -fpic -shared for creating the libs, but this merges the
> > overloaded operators.

> Huh? What do you mean by "merges"?

I meant everytime operators from "main" are used.

Quote:> The '-z text' is not a gcc option. Try "man ld".

There I found it, but thought it would be there in gcc, anyway.

Quote:> You didn't explain what behaviour you are trying to achieve, nor what
> behaviour you currently have. It is rather difficult to suggest a solution
> to an unknown problem.

I wanted this Windows-DLL-like behaviour, as you guessed very well.

Quote:> If indeed that was your goal, read "man ld" and look for -Bsymbolic
> (note: use -Wl,-Bsymbolic when using gcc/g++, as -B means something totally
> different to gcc). Also read the "linker scripts" section in Solaris
> "Linker and Libraries Guide".

I read, and I hope this will solve my problem. I can't check for now
because I'm currently adding new disks into my boxes.

Thank you for now,
Michael B.

 
 
 

overloading operator new in shared libs (madness)

Post by Michael Bruschkewit » Fri, 20 Jun 2003 18:29:48




Quote:> If indeed that was your goal, read "man ld" and look for -Bsymbolic
> (note: use -Wl,-Bsymbolic when using gcc/g++, as -B means something totally
> different to gcc). Also read the "linker scripts" section in Solaris
> "Linker and Libraries Guide".

-Wl,-Bsymbolic was the exact thing that helped.
Thank you very much.

Michael B.

 
 
 

overloading operator new in shared libs (madness)

Post by Michael Bruschkewit » Fri, 20 Jun 2003 20:41:14


This is the right way.
Using -Wl,-Bsymbolic I got the following (app.1) output, where every
shared object uses its own operators new/delete. So far, everything is
ok.

But, if I don't have overloaded new and delete in s1.so, the function
f1() from f1.cpp uses the overloaded operators from _main.o (app.1), but
I need here the predefined operators (from libstdc++.so).

How can I avoid the using of the overloaded operators from _main.cpp in
f1.cpp? (I'm already searching "Linker and Libraries Guide" from AB2,
but this are more than 200 pages, w/o man-pages for ld etc.!)

Michael B.

(app.1)
bash-2.03$ make
g++ -g -fPIC -c _main.cpp -o _main.o
# create s1.so from f1.cpp
g++ -g -fPIC -c f1.cpp -o f1.o
g++ -shared -G  -Wl,-Bsymbolic f1.o -o s1.so
# create s2.so from f2.cpp
g++ -g -fPIC -c f2.cpp -o f2.o
g++ -shared -G  -Wl,-Bsymbolic f2.o -o s2.so
# bind together
g++ -lstdc++ _main.o s1.so s2.so -o t1
bash-2.03$ ./t1
in f()
new (_main.cpp) called, sz = 4
delete (_main.cpp) called, content = 42
leave f()
in f1()
new (f1.cpp) called, sz = 4
delete (f1.cpp) called, content = 11
leave f1()
in f2()
new (f2.cpp) called, sz = 4
delete (f2.cpp) called, content = 22
leave f2()
bash-2.03$

(app.2)
in f()
new (_main.cpp) called, sz = 4
delete (_main.cpp) called, content = 42
leave f()
in f1()
new (_main.cpp) called, sz = 4 <---------------
delete (_main.cpp) called, content = 11 <---------------
leave f1()
in f2()
new (f2.cpp) called, sz = 4
delete (f2.cpp) called, content = 22
leave f2()

 
 
 

overloading operator new in shared libs (madness)

Post by Michael Bruschkewit » Fri, 20 Jun 2003 21:28:05


Sorry for replying myself, but I found the solution right now.
(Possibly I should use multiple names ;)

Using -Wl,-Bsymbolic,-Bdirect I got the result I wanted.

I append the output for explanation (app.1)

Thanks again, Paul, for your hint.

Michael B.

(app.1)
bash-2.03$ make
g++ -g -fPIC -c _main.cpp -o _main.o
g++ -g -fPIC -c f1.cpp -o f1.o
g++ -shared -G  -Wl,-Bsymbolic,-Bdirect f1.o -o s1.so
g++ -g -fPIC -c f2.cpp -o f2.o
g++ -shared -G  -Wl,-Bsymbolic,-Bdirect f2.o -o s2.so
g++ _main.o s1.so s2.so -lstdc++ -o t1
bash-2.03$ ./t1
in f()
new (_main.cpp) called, sz = 4
delete (_main.cpp) called, content = 42
leave f()
in f1()
leave f1()
in f2()
new (f2.cpp) called, sz = 4
delete (f2.cpp) called, content = 22
leave f2()
bash-2.03$

 
 
 

1. overloaded operator new, STL and shared objects (more madness)

Hello,
I ran into the "STL vs. overloaded operator new" problem, found it
mentioned at google, but didn't found a solution. This problem didn't
occur on windows, so the solution maybe some ld-option-"magic", or
something "inside" C++.

I'm using gcc 3.2.3 on Solaris 8 (IA86) and VC++ 6 on W2k.
The problem occurs not on Windows, but this maybe because I used DLL's
there where linkage differs. On Solaris I use shared objects.

I have overloaded operator new, made some logging inside (using
std::string(char*)), but this again introduces the overloaded operator
new, which logs, and introduces std::string(char*), which finally
dead-loCKs.

For C++:
Is it possible to avoid the usage of overloaded new in STL?
Is this a well-known bug or something similar?
Are there STL-Implementations which don't have this problem?
(Maybe portSTL?)

For Unix:
Operator new is overloaded in main.a, log-function is in slib.so,
built like this (compiled with -fPIC, -z muldefs is necessary because
of other "magic"):
g++ -shared -Wl,-Bdirect,-Bsymbolic -z muldefs -G -lstdc++ DEBUG/*.o
-o DEBUG/slib.so
g++ -z muldefs slib.so main.a -z muldefs -lstdc++ -o prog
I don't know why this std::string(char*) is not bound to the shared
object (-Bdirect?).

Sure, it would be possible to avoid the usage of STL inside the
logging function, but this hides the problem only and I don't know if
a similar problem will occur at another place, where it's not so easy
to be found.

Regards,
Michael B.

2. Problems with serial communication

3. overloaded "operator new" not working - why?

4. Looking for a driver for a Iomega Zip (parallel port)?

5. Can ISP detect when dial-ins are 'overloaded' ?

6. Network newbie question

7. Virtual Consoles

8. Problem overloading operator<< for template class

9. operator overloading syntax question

10. Help - shared libs lib****.so.4 lib***.so.5

11. static lib works fine, but why not the shared lib version

12. /usr/lib/gcc-lib/i386-linux and /usr/lib/gcc-lib/i486-linux