How to disable/override __builtin_operator_new/delete?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

How to disable/override __builtin_operator_new/delete?

Manuel Klimek via cfe-dev
Hi,

I'm trying to get my own global operator new/delete calls working that my memory manager plugs into.

This code is working fine on MacOS (clang) and Windows (Visual Studio), but on iOS I have a third party library (lohmann json) returning a std::string object which appears to have been allocated through my ::operator new function (I.e., my memory manager) but is being deleted through __builtin_operator_delete.  Which just results in a crash almost immediately after the app starts.

So how do I disable these particular builtin functions?

Cheers,
James


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: How to disable/override __builtin_operator_new/delete?

Manuel Klimek via cfe-dev
There is no way to disable __builtin_operator_new/delete or prevent libc++ from using it.

I would be interested to get some more details about your particular case. Ideally a reproducer
I could play with. Or at least provide some sort of stack trace and error log.

I'm not too familiar with the optimization aspects of __builtin_operator_new/delete, but the behavior
you're observing sounds like a bug. Either in LLVM/Clang/libc++ or within your build. My suspicion
is that an ODR violation is involved.

/Eric




On Wed, Mar 21, 2018 at 4:43 PM, James Robertson via cfe-dev <[hidden email]> wrote:
Hi,

I'm trying to get my own global operator new/delete calls working that my memory manager plugs into.

This code is working fine on MacOS (clang) and Windows (Visual Studio), but on iOS I have a third party library (lohmann json) returning a std::string object which appears to have been allocated through my ::operator new function (I.e., my memory manager) but is being deleted through __builtin_operator_delete.  Which just results in a crash almost immediately after the app starts.

So how do I disable these particular builtin functions?

Cheers,
James


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: How to disable/override __builtin_operator_new/delete?

Manuel Klimek via cfe-dev
Hi Eric,

I'm trying to find the time to figure out a repo case for you to take a look at.  Just got some xcode shenanigans to figure out.  :)


Our set up is as follows:

Static lib written in C++.  Our memory manager exists in here.
Framework (shared library) with mixed Swift and C++ code.  The global new/delete operators are compiled here, and the static lib is linked in as well.
App written in Swift.


As far as the callstack is concerned, it's basically this:

#0  __pthread_kill ()
#1  pthread_kill$VARIANT$mp ()
#2  abort ()
#3  free ()
#4  std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()

#5  The following five stack frames are in our C++ code...
#6
#7
#8
#9

#10 These four frames are Swift code in our framework...
#11
#12 
#13

#14 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:]
#15 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:]
#16 -[UIApplication _runWithMainScene:transitionContext:completion:]
#17 __111-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]_block_invoke
#18 +[_UICanvas _enqueuePostSettingUpdateTransactionBlock:]
#19 -[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]
#20 -[__UICanvasLifecycleMonitor_Compatability activateEventsOnly:withContext:completion:]
#21 __82-[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]_block_invoke
#22 -[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]
#23 __125-[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]_block_invoke
#24 _performActionsWithDelayForTransitionContext
#25 -[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]
#26 -[_UICanvas scene:didUpdateWithDiff:transitionContext:completion:]
#27 -[UIApplication workspace:didCreateScene:withTransitionContext:completion:]
#28 -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:]
#29 -[FBSSceneImpl _didCreateWithTransitionContext:completion:]
#30 __56-[FBSWorkspace client:handleCreateScene:withCompletion:]_block_invoke_2
#31 _dispatch_client_callout
#32 _dispatch_block_invoke_direct
#33 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__
#34 -[FBSSerialQueue _performNext]
#35 -[FBSSerialQueue _performNextFromRunLoopSource]
#36 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
#37 __CFRunLoopDoSource0
#38 __CFRunLoopDoSources0
#39 __CFRunLoopRun
#40 CFRunLoopRunSpecific
#41 GSEventRunModal
#42 UIApplicationMain
#43 main
#44 start

Nothing overly interesting to look at.  As I mentioned before, this happens during application initialisation.


The output window in xcode simply has the following message:

malloc: *** error for objectt 0x1051bc0c0: pointer being freed was not allocated


Which is partially correct.  It's a 176 byte memory block allocated by my small block allocator.  (I just managed to track it down.)


I don't think the optimiser has anything to do with this.  This is happening in debug builds.

It's smells like a compiler bug to me.  As I mentioned, the same code works fine on both MacOS, Windows, and the iOS simulator (which basically will compile to x86), so I would presume it's ARM specific - but that's merely a guess by me here.

Cheers,
James



On 22 March 2018 at 05:31, Eric Fiselier <[hidden email]> wrote:
There is no way to disable __builtin_operator_new/delete or prevent libc++ from using it.

I would be interested to get some more details about your particular case. Ideally a reproducer
I could play with. Or at least provide some sort of stack trace and error log.

I'm not too familiar with the optimization aspects of __builtin_operator_new/delete, but the behavior
you're observing sounds like a bug. Either in LLVM/Clang/libc++ or within your build. My suspicion
is that an ODR violation is involved.

/Eric




On Wed, Mar 21, 2018 at 4:43 PM, James Robertson via cfe-dev <[hidden email]> wrote:
Hi,

I'm trying to get my own global operator new/delete calls working that my memory manager plugs into.

This code is working fine on MacOS (clang) and Windows (Visual Studio), but on iOS I have a third party library (lohmann json) returning a std::string object which appears to have been allocated through my ::operator new function (I.e., my memory manager) but is being deleted through __builtin_operator_delete.  Which just results in a crash almost immediately after the app starts.

So how do I disable these particular builtin functions?

Cheers,
James


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: How to disable/override __builtin_operator_new/delete?

Manuel Klimek via cfe-dev
So it seems this was due to including the source file that contains operator new and delete in the framework instead of the app.

Moving that file into the app layer appears to have solved the problem.


Cheers,
James


On 22 March 2018 at 22:00, James Robertson <[hidden email]> wrote:
Hi Eric,

I'm trying to find the time to figure out a repo case for you to take a look at.  Just got some xcode shenanigans to figure out.  :)


Our set up is as follows:

Static lib written in C++.  Our memory manager exists in here.
Framework (shared library) with mixed Swift and C++ code.  The global new/delete operators are compiled here, and the static lib is linked in as well.
App written in Swift.


As far as the callstack is concerned, it's basically this:

#0  __pthread_kill ()
#1  pthread_kill$VARIANT$mp ()
#2  abort ()
#3  free ()
#4  std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()

#5  The following five stack frames are in our C++ code...
#6
#7
#8
#9

#10 These four frames are Swift code in our framework...
#11
#12 
#13

#14 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:]
#15 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:]
#16 -[UIApplication _runWithMainScene:transitionContext:completion:]
#17 __111-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]_block_invoke
#18 +[_UICanvas _enqueuePostSettingUpdateTransactionBlock:]
#19 -[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]
#20 -[__UICanvasLifecycleMonitor_Compatability activateEventsOnly:withContext:completion:]
#21 __82-[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]_block_invoke
#22 -[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]
#23 __125-[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]_block_invoke
#24 _performActionsWithDelayForTransitionContext
#25 -[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]
#26 -[_UICanvas scene:didUpdateWithDiff:transitionContext:completion:]
#27 -[UIApplication workspace:didCreateScene:withTransitionContext:completion:]
#28 -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:]
#29 -[FBSSceneImpl _didCreateWithTransitionContext:completion:]
#30 __56-[FBSWorkspace client:handleCreateScene:withCompletion:]_block_invoke_2
#31 _dispatch_client_callout
#32 _dispatch_block_invoke_direct
#33 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__
#34 -[FBSSerialQueue _performNext]
#35 -[FBSSerialQueue _performNextFromRunLoopSource]
#36 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
#37 __CFRunLoopDoSource0
#38 __CFRunLoopDoSources0
#39 __CFRunLoopRun
#40 CFRunLoopRunSpecific
#41 GSEventRunModal
#42 UIApplicationMain
#43 main
#44 start

Nothing overly interesting to look at.  As I mentioned before, this happens during application initialisation.


The output window in xcode simply has the following message:

malloc: *** error for objectt 0x1051bc0c0: pointer being freed was not allocated


Which is partially correct.  It's a 176 byte memory block allocated by my small block allocator.  (I just managed to track it down.)


I don't think the optimiser has anything to do with this.  This is happening in debug builds.

It's smells like a compiler bug to me.  As I mentioned, the same code works fine on both MacOS, Windows, and the iOS simulator (which basically will compile to x86), so I would presume it's ARM specific - but that's merely a guess by me here.

Cheers,
James



On 22 March 2018 at 05:31, Eric Fiselier <[hidden email]> wrote:
There is no way to disable __builtin_operator_new/delete or prevent libc++ from using it.

I would be interested to get some more details about your particular case. Ideally a reproducer
I could play with. Or at least provide some sort of stack trace and error log.

I'm not too familiar with the optimization aspects of __builtin_operator_new/delete, but the behavior
you're observing sounds like a bug. Either in LLVM/Clang/libc++ or within your build. My suspicion
is that an ODR violation is involved.

/Eric




On Wed, Mar 21, 2018 at 4:43 PM, James Robertson via cfe-dev <[hidden email]> wrote:
Hi,

I'm trying to get my own global operator new/delete calls working that my memory manager plugs into.

This code is working fine on MacOS (clang) and Windows (Visual Studio), but on iOS I have a third party library (lohmann json) returning a std::string object which appears to have been allocated through my ::operator new function (I.e., my memory manager) but is being deleted through __builtin_operator_delete.  Which just results in a crash almost immediately after the app starts.

So how do I disable these particular builtin functions?

Cheers,
James


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev