[1] https://clang.llvm.org/docs/AddressSanitizer.html
[2] https://developer.apple.com/documentation/xcode/diagnosing-m...
It should be part any project from the start, run as much as possible with ASAN when the performance hit can be afforded.
It was actually in the link the parent posted. I just missed it at first.
Still, in some cases you have some tiny uninitialized member for example that is much harder to find. So with this malloc it might even cover those more.
On Linux, running `env MALLOC_PERTURB_=43605 myprogram` will do the same.
Some gibberish is better than others. For instance, on x86 (64-bit, 32-bit, or even 16-bit), filling with the 0xcc byte means that, if executed as code, it will trap (0xcc is the single-byte INT3 "single-step breakpoint" instruction). And for most Unix-style operating systems, which put the kernel in the high half of the address space, the filler bytes should have the high bit set, so that treating them as pointers will trap (the pointer will have its high bit set, pointing to kernel memory, which user space is forbidden from accessing).
The Linux setup where you can choose your own scribbles seems to meet your needs no?
Trying to execute off the heap is going to trap anyways.
As I mentioned, only until that freed block is reused for a new allocation, which means it will no longer be all-zeros; or until the memory allocator decides it's time to unmap that region, which means it will trap (SIGSEGV or similar).
When memory is unmapped, caches of memory mappings of other threads are discarded, via inter-core interrupts. Then they get misses until their cache is restored.
In what might be a multi-thread program, you don't fool with the memory map without very good reasons. Mapping new pages, or marking a page r/o or r/w is OK; anything else, probably not.
ARM architecture does not need to interrupt for TLB shootdown.
Is it really a problem? Failing harder and earlier is a good thing if it means the bug has more chances of being detected and fixed.
"the same way some programs currently accidentally depend on freeing memory not immediately overwriting it."
Maybe a dumb question, but what do you mean by this? Could you give a C/C++ pseudo-example? free(f);
f->close();
in code that does a few malloc, if/else’s, etc. between those calls. Stuff like that gets hard to spot in more complex code, especially in the presence of C++ copy constructors, move constructors, etc, where the compiler helpfully inserts that call to free for you.Bugs in copy constructors also can lead to double frees when the destructors of an object and its copy both call delete on a pointer that they think they exclusively own. Between those two destructor calls, you can easily get a use after free. Example: https://stackoverflow.com/a/64014035
If the allocator doesn’t change the content of freed blocks, such bugs can go unnoticed, making the program “accidentally depend on freeing memory not immediately overwriting it”.
You only mean the former, not both. The only reason for the existence of the giant rats' nest of complexity that is C++ move semantics is eliminating this particular mistake.
char const* inputFilename = std::string("path/to/file").c_str();
call_to_C_API(inputFilename);
Boom. You can typically access `inputFilename` until the next allocation on the stack, but it will almost always go bad quickly. This isn't allocation on the heap, which usually requires another level of indirection, but you get the idea.Isn't it allocating in the stack due to the "small string optimization"? Making string contents longer (or using a C++ standard library which doesn't have a "small string optimization" in the first place) would be enough to have it be allocated in the heap instead.
Changing it to:
call_to_C_API(std::string("path/to/file").c_str());
Makes it valid because the std::string object will live until the semicolon.
For instance, I can imagine a program which accidentally follows a dangling pointer to an already freed structure, and reads another pointer from within that structure, not crashing because it ends up checking this later pointer against NULL... until the stars align and the memory used by the freed structure has been returned to the operating system, or overwritten by a later allocation.