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

Support leak detection and race condition analysis #1199

Open
isaachier opened this issue Jul 5, 2018 · 8 comments
Open

Support leak detection and race condition analysis #1199

isaachier opened this issue Jul 5, 2018 · 8 comments
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase.
Milestone

Comments

@isaachier
Copy link
Contributor

isaachier commented Jul 5, 2018

llvm/clang provide many useful sanitizers for debugging low-level code. Here's a few popular ones: AddressSanitizer, LeakSanitizer, MemorySanitizer, ThreadSanitizer. Details about them can be found here: https://github.com/google/sanitizers. They catch a lot of runtime bugs, similar to Valgrind. Anyway, the headers that provide interfaces/hooks for these tools can be found (on my Mac) in /usr/local/Cellar/llvm/6.0.0/lib/clang/6.0.0/include/sanitizer. It would be awesome if Zig supported these tools out of the box, just like clang does (I think Go uses at least ThreadSanitizer too).

@isaachier
Copy link
Contributor Author

isaachier commented Jul 5, 2018

Also, seems LLVM IR already has function attributes relating to these sanitizers:

sanitize_address
This attribute indicates that AddressSanitizer checks (dynamic address safety analysis) are enabled for this function.
sanitize_memory
This attribute indicates that MemorySanitizer checks (dynamic detection of accesses to uninitialized memory) are enabled for this function.
sanitize_thread
This attribute indicates that ThreadSanitizer checks (dynamic thread safety analysis) are enabled for this function.
sanitize_hwaddress
This attribute indicates that HWAddressSanitizer checks (dynamic address safety analysis based on tagged pointers) are enabled for this function.

@andrewrk andrewrk added this to the 0.4.0 milestone Jul 5, 2018
@andrewrk
Copy link
Member

andrewrk commented Jul 5, 2018

This is in line with zig's goals. Essentially, we want debug builds to have as many of these sanitizers enabled at once as we can, as long as we can retain performance within 2 orders of magnitude of release-fast.

You can think of zig's safety checks as sanitizers.

Some of these sanitizers are not compatible with each other, so it is a bit of a puzzle. In some cases it may be worth zig doing its own sanitizer checks and ignoring LLVM's, or sometimes it may be worth using LLVM's sanitizers.

One thing we must not break, however, is zig's ability to cross-compile on any target for any target. Which means that if a sanitizer requires a runtime support library, zig must be able to build it from source for every supported target.

@isaachier
Copy link
Contributor Author

OK that is harder than I thought. I agree the address sanitizer is redundant for Zig given that you are already checking for undefined values in debug mode etc. The checks I'd love to see are leak/double-free detection and race condition detection.

@andrewrk
Copy link
Member

andrewrk commented Jul 5, 2018

For leak/double-free detection, one way we can do that is to have a general-purpose allocator in the standard library which is considered "for debugging" and then either:

  • in debug mode default the standard general-purpose allocator to this one
  • you could manually enable these kind of sanitation by choosing the SanitizerAllocator in your main entry function rather than GeneralPurposeAllocator

For race condition detection, I want to investigate language-level support for that. I think there is a lot we can do.

@isaachier isaachier changed the title Support llvm/clang sanitizers Support leak detection and race condition analysis Jul 6, 2018
@PavelVozenilek
Copy link

Very thorough, even excessive, memory leak detection could be implemented by the user. I did it in a C project: see #480. I enjoyed making it to fit my needs, current or envisioned.

If a functionality is hardcoded into the language/compiler/library ecosystem, it may limit freedom of a developer to make better fitting tools. Will I be able to use my own allocator (with somehow different API) and still use significant parts of Zig's stdlib? C++ decided to force one design on everyone, and it is not a success.

Example of a specific need: test may not leak. Test runner knows about all allocators (they register themselves when created, unregister on destruction), will record their current state at the beginning, and at the end of a test it will check no leak occured. Implemented fast enough to be usable.

@isaachier
Copy link
Contributor Author

C++ didn't really force a design on anyone. You can use your own allocator type, and even maintain state in those allocators if using C++11.

Adding a leak allocator may be the way to go. Essentially, track the chunks of memory allocated to different objects. If any allocations remain when deinit is called, log an error. A good C++ implementation I have seen is here (courtesy of my last employer): https://github.com/bloomberg/bde/blob/ba252cb776f92fae082d5d422aa2852a9be46849/groups/bal/balst/balst_stacktracetestallocator.h. They have a few useful allocators in that library. BDE contains an STL rewrite that allows for standard containers with specific instances of allocators passed in, similar to Zig.

@PavelVozenilek
Copy link

@isaachier: I mean, large part of C++ STL (as of C++98) is married with their allocator design. If you do not want it, you have almost empty hands. Go and develop standard library replacement, like EASTL.

What I fear is the general tendency to design grand systems, where everything fits nicely together, and no part can be removed or changed w/o grave consequences.

@andrewrk
Copy link
Member

Related: #2301

@andrewrk andrewrk modified the milestones: 0.6.0, 0.7.0 Dec 9, 2019
@andrewrk andrewrk modified the milestones: 0.7.0, 0.8.0 Oct 10, 2020
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 Nov 6, 2020
@SpexGuy SpexGuy added the enhancement Solving this issue will likely involve adding new logic or components to the codebase. label Mar 20, 2021
@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 May 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase.
Projects
None yet
Development

No branches or pull requests

4 participants