5 ms·
They CAN accommodate all users, just have compile time options you can enter in your make file/on the command line/etc to say what level of bounds checking/etc
by runevault 9y ago
They CAN accommodate all users, just have compile time options you can enter in your make file/on the command line/etc to say what level of bounds checking/etc you want compiled into your code. Hell that way even within a given project you can choose "this library I'm nervous about so I'll eat the hit on bounds checking".
- pjmlp 9y agoThey do it, but the performance culture among C devs doesn't appreciate enabling them. https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Object-Size-Checking.html#Object-Size-Checking https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Object-Size-Che... https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Pointer-Bounds-Checker-builtins.html#Pointer-Bounds-Checker-builtins https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Pointer-Bounds-... I bet not much UNIX software compiled with gcc enables them. Android is probably the only OS that does make use of them. https://android-developers.googleblog.com/2017/04/fortify-in-android.html https://android-developers.googleblog.com/2017/04/fortify-in...
- wahern 9y agoThe performance culture isn't just C. Far from it. Rust was susceptible to Stack Clash because they ripped out their existing stack probing to gain a few percent increase in performance. The article for this thread literally says, "For many use cases ASan is the better choice because it has much less overhead." IME Valgrind does a _much_ better job of detecting memory issues, partly because ASan only detects issues directly triggered in the code that you compile, whereas Valgrind can detect memory issues directly triggered by external code, but indirectly caused by your code.
- eridius 9y ago> Rust was susceptible to Stack Clash because they ripped out their existing stack probing to gain a few percent increase in performance. Citation please? I thought Rust used guard pages, and that stack probing was something that it was moving towards, not something that was being ripped out.
- comex 9y agoRust used guard pages, but was still vulnerable to attacks based on jumping over the guard page, which is the same issue that Stack Clash exploited in C programs. The ideal fix for that is stack probing, which Rust is indeed moving towards. However, in the past, Rust had a different fix: it would add a bit to all function prologues that explicitly checked for running out of stack space - based on LLVM split stack support, and a remnant of when (even further in the past) Rust actually used split stacks. The explicit check also protected against jumping over the guard page, but was much more expensive than stack probing, and also caused issues with embedded use cases. The plan was to replace it with stack probing, but things dragged on and it was removed before the replacement was ready.
- pjmlp 9y ago> The performance culture isn't just C. Far from it Sure, but it is where it is more visible, specially micro-optimizing code as it is being written, without validating if it really matters to the application's use case with a profiler. The school of systems programming languages from Algol side, was that correctness was much more relevant than pure performance, Algol dialects for systems programming already had Rust like unsafe blocks in the mid-60's. In Burroughs B5500 the administrator could enable which applications with unsafe modules were allowed at all to be executed, 10 years before C was invented.
- wahern 9y agoI've never met a C programmer or C compiler author who felt correctness should take a backseat to performance. And as I demonstrated, the Rust designers are hardly immune to poor decision making on this score. Someone else corrected me regarding the stack probes--Rust didn't have probes but actually checked the size of the stack. It's also worth pointing out that often times decisions are premised on maintenance burdens. Performance was one excuse for removing the stack checking in Rust; the other was the maintenance burden of maintaining a feature outside of LLVM. That goes directly to the heart of the undefinedness issue in C. Doing the "obviously correct" thing wrt to choosing between possible undefined- or implementation-defined behaviors isn't as easy as we think. Good compilers are built on abstractions and code reuse, like any other piece of well-written software. Doing the correct thing in some obvious cases can result in having to make non-obvious tradeoffs elsewhere, possibly having to choose between adding (or maintaining) complexity, or removing a powerful feature, such as deterministic stack overflow prevention. The history of C (indeed, Unix and the whole "worse is better" school of design) is about favoring less complexity in the tooling while shifting more of the burden onto the user. That's a judgment not about runtime performance, but a very unintuitive judgment about the performance and efficiency of programmer time; that you quickly reach a point of diminishing returns, much sooner than most people believe, putting complexity into, and relying on intrinsic features of, the tooling; that it's often better to make it easier to implement and integrate specialized tools, and easier to reuse existing tools as part of a more focused solution. From that perspective the design of C makes a ton more sense, even if reasonable people can still disagree about the results. The notion that C--the language design, the ecosystem--is principally about performance is something mostly held by inexperienced programmers. It's a strawman of critics. There were plenty of other languages from the 1970s that were capable of generating faster code than C. Certainly performance was and continues to be of significant concern, but C is hardly unique in that sense. If the debate about how to balance performance with other issues stands-out, I'd argue that's primarily because of C's ubiquitous position and how it and the computing industry (including hardware industry) has co-evolved. When something seems so "obvious" (security vs performance), yet everybody continues to seemingly repeat the same dumb mistakes, often times what we're missing is that our premises are flawed. Maybe C didn't become ubiquitous because of it's performance, but more so because it was easy to port and easy to build upon. After several years Rust still has a single implementation. Even Go has two production-quality implementations. That's not a criticism of Rust, just an observation that the "security vs performance" axis is hardly the only relevant dimension for judgment and explanation.
- runevault 9y agoThat's totally fair. Flip side arguing "we shouldn't do this because people who only care about immediate performance don't want them" feels like it is ignoring some percent of people who may not feel that way, or even the possibility of using it as a way to bring more people to systems level programming but are not up to making the leap Rust currently requires (which will hopefully become less of an issue as they work on this year's roadmap, but I would certainly argue still exists right now and we won't know how successful their efforts REALLY are until they are all in place).
- pjmlp 9y agoWhen IBM researched RISC in the mid-70s, on the IBM 801 minicomputer, they decided to use a subset of PL/I as their mostly safe system programming language. They implemented a botstraped optimizing compiler for it, making use of an intermediate language with multiple optimization passes. http://rsim.cs.illinois.edu/arch/qual_papers/compilers/auslander82.pdf http://rsim.cs.illinois.edu/arch/qual_papers/compilers/ausla... It was like having LLVM in the 70's and is only one example of the research on optimizing compilers since FORTRAN was created.