5 ms·
> Return pointer to stack object (more common than you might think!) Maybe when you're still learning how to program. A combination of valgrind/sanitizers wil
by kbwt 9y ago
> Return pointer to stack object (more common than you might think!)
Maybe when you're still learning how to program.
A combination of valgrind/sanitizers will catch all of these mistakes. The same class of mistakes can also be made in "memory-safe" languages, just replace pointer with index and memory with array.
- danieldk 9y agoValgrind will only catch such indexing errors when you read/write out of bounds when running Valgrind. There is a huge difference between out-of-bounds indexing leading to undefined behavior or an exception/panic.
- klodolph 9y agoValgrind won't catch certain indexing errors even if you exercise them. Valgrind only checks that the address is valid, not that the address was derived from a pointer to the object you are accessing. int main() { int x[16]; int y[16]; int z[16]; x[0] = 0; y[0] = 0; z[0] = 0; y[18] = 3; // Valgrind thinks this is OK. return 0; }
- jcelerier 9y agohttps://i.imgur.com/fgufyE1.png https://i.imgur.com/fgufyE1.png
- klodolph 9y agoI think you may have missed the part of the conversation where we were talking about Valgrind, specifically, and not talking about the address sanitizer.
- 2trill2spill 9y agoBut clang complains, it's not about just one tool. test.c:8:9: warning: array index 18 is past the end of the array (which contains 16 elements) [-Warray-bounds] y[18] = 3; // Valgrind thinks this is OK. ^ ~~
- klodolph 9y agoThe snippet is a demonstration of the limitations of Valgrind, specifically. It would be trivial to change the code so it has the same behavior but doesn't trigger the Clang warning.
- jcranmer 9y agoPointers to stack objects escaping the function (not necessarily returning) is actually surprisingly easy to do. Sure, the example "Foo f; return &f;" is the sort of situation that isn't going to happen if you're at all experienced, but it's not hard to build cases. I recently had to debug a crash which turned out to be a stack object unexpectedly escaping. Effectively, the flow is this: void foo(Foo *v) { Operand blah; /* Turns out that there's a use-list on some operands, and this adds &blah to that list in that case. */ copy_operand(&blah, &v->operands[1]); free_foo(v); } > A combination of valgrind/sanitizers will catch all of these mistakes. They will catch only those mistakes that occur when you run them in tests. Plenty of memory safety CVEs still show up in programs that do aggressive fuzzing under valgrind/sanitizer testing. Or, as one aphorism has it, "testing cannot prove the absence of bugs, only their presence."
- klodolph 9y ago> Maybe when you're still learning how to program. I used to think so, too. From John Carmack (https://twitter.com/ID_AA_Carmack/status/587077680652230656 https://twitter.com/ID_AA_Carmack/status/587077680652230656) > Found two pointer-to-out-of-scope-stack bugs today. I like tight native code, but C/C++ still makes me worry a lot. And then there's this dubious claim, > A combination of valgrind/sanitizers will catch all of these mistakes. Nope! 1) You have to execute the right code paths before Valgrind or any of the sanitizers will catch your use of a pointer to stack. In relatively simple cases, you might not catch the error even if you have 100% code coverage. 2) Not all platforms have Valgrind or sanitizers working on them, in fact, most don't. > The same class of mistakes can also be made in "memory-safe" languages, just replace pointer with index and memory with array. Sure, you could write an x86 interpreter in Java, and I'm sure that somebody has already done this. But these errors have much more severe consequences in C.
- Jweb_Guru 9y agoDon't use string_view then. Seriously, if people actually programmed C and C++ the way people claim they do, it wouldn't be any more efficient than Java most of the time.