The 1st question I have is what causes the double deletion?
With the help of gdb, it's clear it's the destructor of Object causes the double delete
gdb test(gdb) run(gdb) bt#0 0x00d2f410 in __kernel_vsyscall ()#1 0x008add80 in raise () from /lib/libc.so.6#2 0x008af691 in abort () from /lib/libc.so.6#3 0x008e624b in __libc_message () from /lib/libc.so.6#4 0x008ee0f1 in _int_free () from /lib/libc.so.6#5 0x008f1bc0 in free () from /lib/libc.so.6#6 0x004bbba3 in Object::~Object (this=0x8049aa0, __in_chrg=<value optimized out>) at object.cc:11#7 0x002d4fbe in __static_initialization_and_destruction_0 (__initialize_p=0, __priority=65535) at sub2.cc:3#8 0x002d4fd9 in global destructors keyed to object() () at sub2.cc:5#9 0x002d4f10 in __do_global_dtors_aux () from ./libsub2.so#10 0x002de61c in _fini () from ./libsub2.so#11 0x008707ee in _dl_fini () from /lib/ld-linux.so.2#12 0x008b0d39 in exit () from /lib/libc.so.6#13 0x0089ae94 in __libc_start_main () from /lib/libc.so.6#14 0x08048651 in _start ()
If we put some instrumentation in object's constructor and destructor like:
cout << "Object::Object this = " << this << "; buffer = " << (int)buffer << endl;cout << "Object::~Object this = " << this << "; buffer = " << (int)buffer << endl;
It will show that the global object, "object", is actually only one object but constructed twice and destructed twice.
And the second destruction will cause the "double delete", which bothers me so much
Knowing that the global object with same name causes the double deletion, it comes to me the 2nd question
why no error or warning raised in linking
Though simple, it leaves a further question onThis one is easy, it because there is no real linking done in link time for shared objectPut an extra "-E" option when linking will make it clearThe 4th step in linkg++ -Wl,-rpath,. program.cc -L. -lsub1 -lsub2 -lobject -o testbecomesg++ -E -Wl,-rpath,. program.cc -L. -lsub1 -lsub2 -lobject -o test
And it tells> g++ -E -Wl,-rpath,. program.cc -L. -lsub1 -lsub2 -lobject -o testexecution gcc-4.1.2_p1/g++ (asb_shanghai/rncenv/linux2)g++: -rpath: linker input file unused because linking not doneg++: .: linker input file unused because linking not doneg++: -lsub1: linker input file unused because linking not doneg++: -lsub2: linker input file unused because linking not doneg++: -lobject: linker input file unused because linking not done
1) when and how the linking is done2) who calls the constructor and destructor?