Simple application overriding global new and delete operators like this:
#include <new> #include <stdlib.h> #include <FBaseLog.h> #include <FBaseColArrayList.h> static bool MEM_LOG = false; void *operator new(::size_t size) throw(std::bad_alloc) { if (MEM_LOG) { AppLog("%d", size); } return ::malloc(size); } void *operator new [] (::size_t size) throw(std::bad_alloc) { if (MEM_LOG) { AppLog("%d", size); } return ::malloc(size); } void *operator new(::size_t size, const ::std::nothrow_t &) throw() { if (MEM_LOG) { AppLog("%d", size); } return ::malloc(size); } void *operator new [] (::size_t size, const ::std::nothrow_t &) throw() { if (MEM_LOG) { AppLog("%d", size); } return ::malloc(size); } void operator delete(void *p) throw() { if (MEM_LOG) { AppLog("%p", p); } ::free(p); } void operator delete [] (void *p) throw() { if (MEM_LOG) { AppLog("%p", p); } ::free(p); } void operator delete(void *p, const ::std::nothrow_t &) throw() { if (MEM_LOG) { AppLog("%p", p); } ::free(p); } void operator delete [] (void *p, const ::std::nothrow_t &) throw() { if (MEM_LOG) { AppLog("%p", p); } ::free(p); } void dump_global_new_delete_override_for_system_class() { MEM_LOG = true; AppLog("================================================================"); Tizen::Base::Collection::ArrayList* p = new Tizen::Base::Collection::ArrayList(); p->Construct(); delete p; AppLog("================================================================"); MEM_LOG = false; } extern "C" _EXPORT_ int OspMain(int argc, char *pArgv[]) { AppLog("Application started."); dump_global_new_delete_override_for_system_class(); return 0; }
gives different output results when running in debug mode or not:
When it's executed in debug mode (or via 'sdb launch -m debug') log contains what I expect:
06-13 17:37:53.165 : INFO / SpikeGlobalNewDelete ( 5865 : 5865 ) : int OspMain(int, char **)(28) > Application started. 06-13 17:37:53.165 : INFO / SpikeGlobalNewDelete ( 5865 : 5865 ) : void dump_global_new_delete_override_for_system_class()(19) > ================================================================ 06-13 17:37:53.165 : INFO / SpikeGlobalNewDelete ( 5865 : 5865 ) : void *operator new(::size_t)(7) > 36 06-13 17:37:53.165 : INFO / SpikeGlobalNewDelete ( 5865 : 5865 ) : void *operator new[](::size_t, const ::std::nothrow_t &)(10) > 40 06-13 17:37:53.165 : INFO / SpikeGlobalNewDelete ( 5865 : 5865 ) : void operator delete[](void *)(13) > 0x2a027c20 06-13 17:37:53.165 : INFO / SpikeGlobalNewDelete ( 5865 : 5865 ) : void operator delete(void *)(12) > 0x2a010b70 06-13 17:37:53.165 : INFO / SpikeGlobalNewDelete ( 5865 : 5865 ) : void dump_global_new_delete_override_for_system_class()(23) > ================================================================
But when it's executed in run mode (or via 'sdb launch -m run' or via the launch icon on device), log contains only:
06-13 17:38:08.540 : INFO / SpikeGlobalNewDelete ( 5879 : 5879 ) : int OspMain(int, char **)(28) > Application started. 06-13 17:38:08.540 : INFO / SpikeGlobalNewDelete ( 5879 : 5879 ) : void dump_global_new_delete_override_for_system_class()(19) > ================================================================ 06-13 17:38:08.540 : INFO / SpikeGlobalNewDelete ( 5879 : 5879 ) : void *operator new(::size_t)(7) > 36 06-13 17:38:08.540 : INFO / SpikeGlobalNewDelete ( 5879 : 5879 ) : void dump_global_new_delete_override_for_system_class()(23) > ================================================================
It happens for every class from dynamic library (in this case it is ArrayList from 'libosp-appfw.so') on real device and on emulator too.
It looks like undefined symbols of such dynamic libraries (new/delete - _Znaj/_ZnajRKSt9nothrow/_ZdaPv/etc) are still linked with standart's new/delete implementations from "libstdc++.so" instead of my executable module.
Why does it happen in run? Why debugging has a different but at least correct behavior?
How correctly to override global operators new and delete on Tizen platform?