Search code examples
c++address-sanitizer

ASAN is not able to detect memory leak for unused delete after new


Hello stackoverflow community, I am creating a memory leak to use ASAN and detect memory leaks.

$ export MallocNanoZone='0' # to avoid https://stackoverflow.com/q/64126942/9497703 on OS X
$ cat new_delete.cc
class Dummy {
    public:
        Dummy(int x) {
            sz = x;
        }
    private:
        int sz;
};

void func(int i) {
    Dummy* p = new Dummy(i);
    if (i < 50) {
        // If return from here then there is a memory leak on the
        // heap. Dummy is not freed.
        return;
    }
    // Do useful things.
    delete p;
}

int main() {
    func(10);
}
$ clang++ -fsanitize=address -g -O0 new_delete.cc
$ ./a.out

I was expecting ASAN to detect this memory leak. However, it didn't.

Can anyone point out what I am missing here? I am using OS X and following clang version:

$ clang++ --version
Apple clang version 12.0.0 (clang-1200.0.32.28)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Solution

  • This is a known issue - algorithm used in Lsan is probabilistic and does not guarantee that all leaks are detected (see #937 for details). E.g. in your case if we change main to

    int main() {
        int a[100];
        func(10);
    }
    

    clang starts to detect the leak:

    $ clang++ -fsanitize=address new_delete.cc && ./a.out 
    =================================================================
    ==349258==ERROR: LeakSanitizer: detected memory leaks
    
    Direct leak of 4 byte(s) in 1 object(s) allocated from: