Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed NDEBUG-dependent SimTK::StateImpl members #738

Merged
merged 1 commit into from
Mar 24, 2023
Merged

Removed NDEBUG-dependent SimTK::StateImpl members #738

merged 1 commit into from
Mar 24, 2023

Conversation

adamkewley
Copy link
Contributor

@adamkewley adamkewley commented Jun 23, 2022

Although the members that are affected by this diff (m_qVersion, m_discreteVarVersions, etc.) are unused in release builds, it is dangerous to conditionally expose them.

The reason why is because of ABI breakages. StateImpl.h is a header that can, in principle, be included by downstream code (I know it's internal/, but that won't stop it from being transitively included by, e.g. OpenSim) there is a chance that different compilation units will compile different downstream code based on what their NDEBUG is set to (might be different from simbody's build).

Example: In Linux, I was getting a segfault on a cache variable read from a not-debug part of StateImpl, probably because my downstream code--compiled in Debug mode--compiled assembly code that computes an incorrect offset into the StateImpl struct, because it inlined a function via OpenSim.

That segfault disappears if I apply this patch, and I can then build opensim-creator in Debug mode against Release-mode binaries in Linux. The utility of this is that I'm using debug mode /w libasan to kick out harder-to-detect faults.

I have read in other PRs, issues, etc. on both simbody and opensim-core that downstream projects must be compiled with the same optimization+debug levels. This should not be the case. It is perfectly normal to use a downstream debug binary with an upstream release library (think about graphics bindings, OS APIs, game engines, etc.).

The only exception is maybe MSVC, which has some kind of iterator debug level macro in its standard library, which causes is to cry quite a bit if you mix up flags. I have only seen this in MSVC--specifically for iterators--and both OSX and Linux are usually ok with mixing debug levels.

This patch makes StateImpl slightly bigger but, assuming empty containers cause no allocations, the overhead should be small compared to the rest of the datastructure. If there is genuinely a performance concern then I would recommend heap-allocating a DebugData struct behind a unique_ptr to put a cap (pointer size) on the overhead.


This change is Reviewable

- It changes the ABI of simbody when compiling with/without the flag,
  which can break builds that use different flags
@adamkewley
Copy link
Contributor Author

@sherm1 , I've had another OpenSim user run into (luckily, compile-time) compilation issues on Linux when compiling debug binaries against Release OpenSim+Simbody binaries because of this bug.

Is there any chance that this could be merged? I know you're busy but it's one of those issues that is super-confusing to any dev that isn't aware of ABI stability etc.

Copy link
Member

@sherm1 sherm1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Sorry for the delay, Adam -- apparently I forgot about this long ago!

Thanks for the fix.

Reviewed 2 of 2 files at r1, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @adamkewley)

@sherm1 sherm1 merged commit 3c3ad5a into simbody:master Mar 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants