// class Controller { // public: // void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); } // void WorkComplete(const Result& result) { ... } // private: // // Member variables should appear before the WeakPtrFactory, to ensure // // that any WeakPtrs to Controller are invalidated before its members // // variable's destructors are executed, rendering them invalid. // WeakPtrFactory<Controller> weak_factory_; // };
- Comb through the code to detect / enforce this rule?
- Update the comment, since it's doesn't matter? (and/or/xor)
- Have a pre-submit check to ensure new code follow this?
- See if any crash arise because of the rule being broken?
- Add compile-time (pointer arithmetic?) check in WeakPtr to ensure that it appears last, or near the end?
--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
This occasionally happens because people know too much about lifetimes and hence know WeakPtr's will not be around at destruction time. So while it's technically not valid, there are instances where it's safe.- Update the comment, since it's doesn't matter? (and/or/xor)It _does_ matter, so removing it is not a good idea.- Have a pre-submit check to ensure new code follow this?AFAIK, we're trying to not get overboard on presubmit checks. I wouldn't personally object, but you might want to listen to the presubmit gods. Or OWNERS ;)- See if any crash arise because of the rule being broken?If I understand WeakPtr correctly, adding a DCHECK(!HasWeakPtrs()) in the factory's dtor might work for that.
Can we try to get the WrakPtrFactory destructor deadbeef the object that it frees, and make potential use-after-free bugs more visible?
--
Samuel Huang
WeakPtrFactory doesn't free anything - it just invalidates any WeakPtrs it was used to create.To detect the use-after-dtor (again, note this is NOT use-after-free!) of members, you'd need to check all members for correctness every time they're accessed [via the WeakPtr].On 3 October 2013 16:01, Samuel Huang <hua...@google.com> wrote:
Can we try to get the WrakPtrFactory destructor deadbeef the object that it frees, and make potential use-after-free bugs more visible?
Keep in mind that WeakPtrFactorys can refer to things other than the objects that contain them. :)
Yuck. I'd have to see some specific examples to be sure, but that sounds like something we shouldn't encourage (and maybe even should disallow).
On Thu, Oct 3, 2013 at 10:18 AM, Wez <w...@chromium.org> wrote:
Keep in mind that WeakPtrFactorys can refer to things other than the objects that contain them. :)Yuck. I'd have to see some specific examples to be sure, but that sounds like something we shouldn't encourage (and maybe even should disallow). WeakPtrFactory loses all its usefulness if you don't guarantee that it gets destructed before its referee (or at least all other members of its referee).
It's definitely possible to do that right, but we apparently (myself included) already mess up the easier WeakPtrFactory-as-member pattern already. I feel like if we can narrow it down to its 1 most common use case, and then guarantee (with a Clang checker) that we always get that pattern right, then we should do that.A clang checker that accounts for only the factory-as-member case should be super easy. Dealing with other uses _statically_ might be hard or impossible.
On 3 October 2013 17:25, David Michael <dmic...@chromium.org> wrote:
On Thu, Oct 3, 2013 at 10:18 AM, Wez <w...@chromium.org> wrote:
Keep in mind that WeakPtrFactorys can refer to things other than the objects that contain them. :)Yuck. I'd have to see some specific examples to be sure, but that sounds like something we shouldn't encourage (and maybe even should disallow). WeakPtrFactory loses all its usefulness if you don't guarantee that it gets destructed before its referee (or at least all other members of its referee).It's actually a pretty useful construct, where you have:- Object A that owns Object B.- B has no reason to SupportsWeakPtr.- A wants to pass Callbacks to other components that Bind() to methods on B.- A wants to have those Callbacks become no-ops if they are executed after B has been deleted.A then contains a WeakPtrFactory<Class B> that points to B, and Bind()s WeakPtrs from that in Callbacks it passes to other components, thereby avoiding polluting Class B with knowledge of [Supports]WeakPtr.It's definitely possible to do that right, but we apparently (myself included) already mess up the easier WeakPtrFactory-as-member pattern already. I feel like if we can narrow it down to its 1 most common use case, and then guarantee (with a Clang checker) that we always get that pattern right, then we should do that.A clang checker that accounts for only the factory-as-member case should be super easy. Dealing with other uses _statically_ might be hard or impossible.We can cope with the factory-as-member easily, yes. We should also be able to sanity-check the scoped_ptr<ClassB> + WeakPtrFactory<ClassB> case above reasonably easily.
Related to this, adding a check that classes deriving from SupportsWeakPtr always call Invalidate() in the derived class dtor should be easy, and would trap that potential source of use-after-dtor on members. :)
I've been moving some of these WeakPtrFactory instances and, alarmingly, it seems that GCC, at least, has no problems whatsoever with code like:class Foo {public:Foo() : weak_ptr_(weak_ptr_factory_.GetWeakPtr()),weak_ptr_factory_(this) {}private:...};Without the compiler providing the basic sanity-check that |weak_ptr_factory_| is initialized before the caller tries to create a WeakPtr from it, these patches appear to introduce more scope for bugs than they fix. :(