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

Memory leak in ThreadLocalRegistryImpl::GetThreadLocalsMapLocked() on Windows #692

Closed
klugier opened this issue Jan 23, 2016 · 7 comments
Closed

Comments

@klugier
Copy link

klugier commented Jan 23, 2016

Hello,

I am trying to port gtest to U++ bazar project (www.ultimatepp.org) , but it's memory dectors shows that there are memory leaks on MS Windows. I fount that one of this leaks comes from static ThreadLocalRegistryImpl method "ThreadIdToThreadLocals* GetThreadLocalsMapLocked()" - gtest-port.cpp - line 532. Below is the original implementation:

  // Returns map of thread local instances.
  static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
    mutex_.AssertHeld();
    static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals;
    return map;
  }

As you can see the problem here is that this static variable is never deleted in the gtest code. The solution here is simply, instead of allocating on stack let's allocate this on heap:

  // Returns map of thread local instances.
  static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
    mutex_.AssertHeld();
    static ThreadIdToThreadLocals map;
    return ↦
  }

In this solution destructor of ThreadIdToThreadLocals will be called when all static variable should be cleaned.

Sincerely,
Zbigniew Rębacz

@nachokruss
Copy link

That would make things worse as local variables are destroyed after GetThreadLocalsMapLocked returns.

@dawikur
Copy link
Contributor

dawikur commented Jan 26, 2016

@nachokruss local yes, but static are not.

@nachokruss
Copy link

Aha. You are right didn't see it was static, maybe put in a pull request then?

@klugier
Copy link
Author

klugier commented Jan 26, 2016

Thanks for comments. I will create pull request in near future.

@coreykosak
Copy link

This is not a leak per se (where a leak is defined as "allocated memory
that has become inaccessible from any pointer"), but rather a failure to
destroy all allocated objects at program shutdown.

Put another way, that object is always reachable, so it's not a leak.

So far as I am aware (maybe the gtest owners want to comment more
authoritatively), I don't think we care about carefully destroying every
last object at shutdown.

Is there an argument (other than hygeine / warnings from the leak detector
you are using) why this design choice hurts your project?

On Tue, Jan 26, 2016 at 2:28 PM, Zbigniew Rębacz [email protected]
wrote:

Thanks for discussion guys. I will create pull request in near future.


Reply to this email directly or view it on GitHub
#692 (comment).

@MrSapps
Copy link

MrSapps commented Apr 14, 2016

Its annoying to find real leaks with lots of on purpose leaked objects :)

@gennadiycivil
Copy link
Contributor

Should be addressed by #1142

souptc pushed a commit to microsoft/onnxruntime that referenced this issue Dec 17, 2018
I started out with ~1800 leaks and got it down to zero. Some are in google's test code itself (see google/googletest#692 ) though it looks like they might not be interested in fixing them.

1600 leaks were in not having a virtual OpKernel destructor.
150 leaks were in not calling ::google::protobuf::ShutdownProtobufLibrary
the rest were in our statics

Scott - I reverted some of the gsl changes as the static pointers were never being destroyed. Doesn't the initialization order only apply to global statics, not function ones?
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

No branches or pull requests

6 participants