Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Only Indirect leaks and no Direct ones

After reading through this StackOverflow question: What is the difference between a direct and indirect leak? I was left with the impression that if I fix all Direct Leaks (multiple fix-test passes since an indirect leak may become a direct one after fixing the previous direct leaks) eventually I would end up with 0 leaks.

I'm currently using the Leak Sanitizer (LSAN) and after fixing all Direct Leaks (and some indirect leaks were gone as a result) I'm now left with a bunch of Indirect leaks. Why are there no direct ones? When could this happen? How do I diagnose and fix the remaining leaks?

like image 349
onqtam Avatar asked Aug 13 '19 12:08

onqtam


People also ask

What is an indirect leak?

An indirect leak is a heap object that is reachable by a pointer to its start address, but with all such pointers originating in leaked objects. Leaks can be thought of as trees, with the top-level object the direct leaks and all child objects indirect leaks.

What is indirectly lost in Valgrind?

"indirectly lost" means your program is leaking memory in a pointer-based structure. (E.g. if the root node of a binary tree is "definitely lost", all the children will be "indirectly lost".) If you fix the "definitely lost" leaks, the "indirectly lost" leaks should go away.

What is definitely lost in Valgrind?

Valgrind categorizes leaks using these terms: definitely lost: heap-allocated memory that was never freed to which the program no longer has a pointer. Valgrind knows that you once had the pointer, but have since lost track of it. This memory is definitely orphaned.

How does valgrind detect memory corruption?

Finding Memory Leaks With Valgrind When you run your code, you'll need to specify the tool you want to use; simply running valgrind will give you the current list. We'll focus mainly on the memcheck tool for this tutorial as running valgrind with the memcheck tool will allow us to check correct memory usage.


1 Answers

They might be the circular references. As indirect leak is reachable from other leaked blocks, with cyclic dependency e.g. 2 objects have references to each other, and both of them might be unreachable from the roots.

E.g. in Observer pattern, it's easy to keep circular reference if forget to do a deregistration at the end of usage (Lapsed listener problem).

In general it's better to avoid cyclic references. If think in terms of ownership, owner must have references to objects it owns, but not vise versa, circular dependencies are not possible in this case. It's achievable if pass dependencies via constructor, and not allow to assign dependencies via setters. Also e.g. Rust with borrowing the references makes circular dependencies impossible.

like image 171
Renat Avatar answered Sep 26 '22 01:09

Renat