-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
locale0.cpp
: Protect memory integrity of _Fac_node
#4916
Conversation
I think your private heap is incorrectly implemented and hence doesn't meet the required behavior in the Standard. So such use causes undefined behavior, and thus MSVC STL doesn't need to defend against it. |
While I agree with this as an argument against the presented reason for the change, I'm willing to consider that we should be using the same form of allocation in both debug and release builds. Variations between debug and release can hide problems. This is why I've tagged the PR as "enhancement" and not "bug". I haven't approved yet since I'm not completely convinced, but I think it at least merits discussion. |
I agree it's an enhancement, not a bug, and I do recognize the fundamental design issue of our application code. That being said, I wouldn't say our implementation is "incorrect" - it seems inevitable when you decide to globally replace |
Unpopular opinion: I argue that the current design of |
This is the absolute scariest part of the STL, and it's a miracle that it works as-is, much less when people are replacing The proposed change looks reasonable to me but I also need to think about it (and get past my sheer blinding terror of any changes to the facet machinery; I've been dealing with breakage in this area since 2007). |
I'll approve this. There's Only One STLTM so there are no mix-and-match concerns, and avoiding release/debug differences is a benefit. I'm not especially persuaded by the application scenario (our behavior has been like this for a long time - why is it a problem now?), but having only one form of STL behavior is strictly simpler.
Lines 31 to 33 in 8af2cc4
|
Thanks for the discussion and approval. Great to see agreement on merging this PR, despite for a different reason than my original motivation.
Why it used to work is a mystery to me. By setting up a debugger, I clearly see FWIW our C++ project is integrated into a C# project and we have managed C++ code that makes things more complicated. We are migrating from .Net framework to .Net core which might somehow change something magic. |
I haven't come up with a reason not to accept this change. It improves debug/release consistency a bit and causes no harm. |
locale0.cpp
: Protect memory integrity of _Fac_node
I'm mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed. |
Thanks for simplifying this ancient horror, and congratulations on your first microsoft/STL commit! 😻 🎉 🚀 Because I like to live dangerously, this change is expected to ship in VS 2022 17.12 Preview 3. |
locale0.cpp has a global static linked list:
STL/stl/src/locale0.cpp
Line 52 in 8af2cc4
whose memory is released when another global variable,
STL/stl/src/locale0.cpp
Line 64 in 8af2cc4
, is destructed:
STL/stl/src/locale0.cpp
Lines 54 to 62 in 8af2cc4
This is fine, except when
new
anddelete
are replaced globally by application code. In our application code (a fairly old codebase that is hard to refactor), we replacenew
anddelete
operators globally and use our private custom heap to manage the memory. The problem is_Fac_node
linked list's memory is allocated on our private heap, but when the destructor of_Fac_tidy_reg_t
is invoked, our private heap has already been destroyed, causing read access violation. This crash doesn't happen in DEBUG build, where_Fac_node
has its own implementation ofnew
anddelete
implementation.This PR proposes that
_Fac_node
overridesnew
anddelete
in non-DEBUG mode as well, not only for consistency with DEBUG mode, but also for integrity and control of its memory usage.