THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 31/08/2012 at 06:06, xxxxxxxx wrote:
Cinema 4D Version: r14
Platform: Windows ; Mac ; Mac OSX ;
Language(s) : C++ ;
Edit: Post updated to contain the latest findings
Symbol stripping on OS X
we recently discovered a problem on OS X in a 3rd party plugin that could create a crash at startup in r14, r13, ...
The crash is quite hard to track down, as it depends on timing, memory content and is more likely to happen on Apple's latest OS X version (2/3rd of the customers running into this problem are using OS X 10.8.1).
This is what happens:
- The OS allocates memory (e.g. for a window) via new. This is is handled by the OS default implementation.
- A plugin exports symbols for new & delete. As soon as it is loaded its new & delete operators replace the OS default implementation.
- The OS is releasing memory (e.g. when closing a window). Instead of calling the OS default implementation of delete that suddenly will call the plugin's delete function.
Depending on the content of the memory block (that should be freed), crashes are possible; it just depends on the content of the memory block if this happens or not.
Why did this happen?
Here 's a selection of what might cause the trouble:
- XCode project & target settings might be conflicting, creating a mess in the build phase.
- Symbol stripping for the release compile might be disabled (check project and target settings!)
- Many of you used the R12 SDK to build plugins running on R12, R13 & R14. When we developed Cinema R12 we used XCode 3.1 and the project settings were adjusted to that. If you switched to XCode 3.2.6 and used that for build plugins based on the R12 SDK, Apple introduced an unpleasant surprise: The global symbol stripping doesn't work anymore and you don't get any warning or error about it. You have to look deep into the log files to find this remark:
"[…] nmedit: removing global symbols from a final linked no longer supported. […]"
Note: this problem might have been introduced with earlier versions of XCode 3.2.x already; we verified this behaviour in XCode 3.2.6.
How can I verify that symbol stripping worked?
nm <path of your dylib> | c++filt -p -i
command in the terminal to verify that no new/delete symbols are exported.
- Use the R13.061 SDK to build plugins for R13 & R14, if you don't use R14 specific functionality (or rely on things that changed with R14).
With the R13 SDK we re-wrote the projects from the ground up for XCode 4 (which in the end we didn't use, as XCode 4.0 wasn't production-ready) and then had to add several workarounds to the project to make XCode 3.2.x work again; luckily those workarounds circumvented the stripping problem Apple introduced in XCode 3.2 too (as we know now).
The R13 SDK can be used with XCode 3.2.6 - this is what we used for building R13 - or XCode 4.x. Note: when using XCode versions > 4.2, you might have to adapt the compiler settings, as Apple removed gcc support.
- Use the R14.025 SDK with XCode 4.2 or newer to build plugins utilizing R14 functionality (or relying on functions that have been changed with R14)
- Use XCode 3.1.x only if you want to create plugins for R12 and with the R12 SDK. Check the compiler/linker log for messages indicating that stripping doesn't work anymore and use "nm" to verify that new/delete isn't exported. Don't use XCode 3.2.x or newer to create plugins with the R12 SDK.
Settings in XCode
There is a plentora of settings in XCode and I'll only list the most important ones here; in doubt (if you're not using the cinema4dsdk project as base for your plugin) please have a look at the R13.061 SDK or R14.025 SDK projects and their settings (we tripple-checked these versions)
For the release build make sure that:
- "Deployment Post Processing" is enabled (otherwise the whole stripping process isn't initiated)
- "Strip Debug Symbols During Copy" is enabled
- "Strip Linked Product" is enabled
- "Strip Style" is set to "Non-Global Symbols"
- "Exported Symbol File" is pointing to the "export.txt" containing the "_c4d_main" symbol in your plugin (path usually is "../../resource/_api_lib/export.txt")