Re: Integrating "safe" languages into OpenBSD? (2017)
marc.info
marc.info
There isn't really much of a statement or judgment on Rust. At most there's an interesting point on it's value proposition:
> However there is a rampant fiction that if you supply a new safer method everyone will use it. For gods sake, the simplest of concepts like the stack protector took nearly 10 years for adoption, let people should switch languages? DELUSION.
This is mostly true. Developers in particular don't generally care about security, so selling Rust as a "secure" language is not going to be enough. I've said this since 1.0. But it's not entirely true for products, which often drive development - Chrome's pairing of performance and security led to tons of marketing wins.
Given that tools like "cat" etc are:
a) Not generally security sensitive
b) Target developers
I don't see anyone choosing the "rust cat" over the builtin. This is why people build tools like "bat", that aren't just memory safe copies, but they're memory safe tools that add features and target slightly different cases.
Not much else to get from this post, I think.
The whole C ecosystem is a joke with respect to builds—all dependencies are implicit; you’re just expected to have the exact dependencies installed on your system at the exact versions and in the exact locations on the filesystem that the build tooling is willing to look. Autotools and CMake are absolutely terrible; they make Python’s build ecosystem look sane and well-designed.
So no, “security” isn’t the most compelling use case (for me, anyway), it’s moving past these dumpster fire build systems as quickly as possible so mere mortals can build their own software. Specifically, hasten the day where my entire application dependency tree doesn’t bottom out in some Autotools, CMake, shell script, project.
This is an area where the BSDs are pretty good. There may not be a dependency system here exactly, but because XBSD base builds XBSD base, everything you need is in one checkout. Generally with just (BSD) Make driving the build.
Programs outside of base are genrerally built with Portfiles which specify dependencies such that (BSD) Make can satisfy them. But somebody has to write the Portfile, and it's often not the authors of the program.
I used to feel sheepish defending npm and the whole node package ecosystem against its critics, but once I started trying to run deep learning applications or WebRTC media servers I quickly realized that some of the critics are probably coming from a much worse package management system that they’ve merely grown familiar with.
Want to have two pieces of software on one computer that rely on... idk, two different versions of libwebsockets? Yeah, you’ll need either docker/overlayfs, or some filesystem or pkgconfig hack that I’m sure a comment reply will helpfully mention if you want two have to versions of a library installed for two different executables.
If your programs depend on different MAJOR versions of libwebsockets and libwebsockets' build system doesn't easily allow that to happen then complain to the developer of libwebsockets about it. If the developer of libwebsockets is not interested in solving this problem then complain to the developers of the programs which depend on libwebsockets that they should find a better library which doesn't suck. If they don't listen, rewrite the tools you depend on to not suck.
If, on the other hand, the programs depend on different minor versions of libwebsockets and libwebsockets broke API in such a way that just using the highest common version doesn't work then complain to the developer of libwebsockets that they should stop doing terrible things like breaking API and then complain to the developers of those applications that they shouldn't let this kind of breakage slide and should move to a different library.
If you think this is unrealistic then I think your push towards insane let's-pull-all-the-dependencies-into-one-binary/package build systems is unrealistic.
You want a sane build system? The change starts when you stop tolerating idiots who cause things not to work.
We don't tolerate engineers who build crappy bridges which break and kill people. You shouldn't be tolerating programmers who build crappy libraries which break API or don't allow two major-versions to be easily simultaneously installed and linked against.
On my old MacBook Pro I have dozens of node projects that I’ve downloaded over the years just to mess around. If I ever want to clean up, I can delete a project’s folder, and know that everything it installed is now gone (because it would be in its node_modules folder).
On my linux desktop if I want to mess around with a cool project that’s written in C/C++ I immediately pull out Docker and start trying to build up an image, since I don’t want to pollute my global library folders with libraries that I might be downloading just to try out this one thing. I can then delete the docker image if I want to clean up. This works, but it feels like a workaround to the main problem of libraries being global.
A hybrid solution where the package manager is aware of all installed versions, can symlink to a globally installed copy and can update all symlinks would probably work.
Unfortunately, there is very little interest in fixing the problem on both sides (distro PMs and language PMs) since they both believe their own approach is right and don't care about the other group's problems.
If you don't like where the project installs its binaries or libraries, you can configure that before `make` or `make install`. You can install it to your home directory, have a separate directory tree for experiments, or whatever you want, and clean it up whenever it is convenient. You can also install things in usr/local and just ignore them. The system is actually well designed if you learn how to use it.
If you need a dependency, use your package manager to install it and you can trivially delete it later... and if you try five different frontends for the same library, you only install one copy of it.
Docker is a workaround for a lack of Unix awareness and sysadmin experience.
On my system I have built lots of random projects to "mess around" and to achieve the same effect of cleaning them up I can just make a list of all the packages I explicitly installed to make them work (including packages which I already had) in a simple flat file. I can then feed that file into my package manager to delete only packages which aren't used by anything else.
Now, I can hear you say: "this isn't practical, these projects depends on 400 dependencies". The question I would then ask is why has it become commonplace for a "dependency" to sometimes equate to 20 lines of code. For these "dependencies" sure I think maybe some kind of local storage is appropriate, but I think that this is already solved in languages like C using git submodules. I don't personally like this approach myself, I would rather people just flesh out a standard library or other common libraries than to produce a 20 line snippet that everyone includes in their project through submodules. But the fact of the matter is, this is still an option.
The other thing I should point out is that your docker image is surely going to take up an order of magnitude more space than just installing a few libraries and keeping them around. This in turn means that you could have just kept an order of magnitude more projects in the same amount of space. And finally, the approach of putting everything in one directory is a big hit in terms of disk space. I don't know much about node or JS but I have to assume that the language is still primarily text based. Keeping around hundreds of dependencies written in text (even with minification but does that happen with node?) is going to take up a lot more space than a few shared objects. So in an ecosystem where everyone has decided that disk space isn't so important, what is the point of easy cleanup?
Given the wording you use by "pollute" I assume you literally mean having those files there in the first place. But I don't understand what the problem would be with that. Especially when most projects use dependencies you're most likely already going to have installed. As long as you don't work against your package manager, nothing should ever break as a result of having too many packages installed.
You've pointed this out yourself, but this works just fine in any sensible OS. You just have two or more versioned instances of libwebsockets in your /usr/lib directory, and a symlink (or multiple symlinks with different partial-semvers) that points to some appropriate default. I think even Windows is doing something like this nowadays, as part of the whole WinSxS mess.
It's usually just a symlink from libwhatever.latest.version.number to libwhatever.so, on the theory that you probably want the latest version of the library (with all its improvements and bugfixes).
There's sometimes an intermediate symlink to the newest major versions too (libwhatever.latest.so, libwhatever.2.so), to avoid breaking changes.
Building a new system is not going to help. Xkcd 927 about standards applies
My main problem is that when it comes to C/C++ dependencies, the package ecosystem defaults to installing globally and has no standard way to specify dependencies aside from having instructions to “sudo apt install these 20 libs”.
Just setup the correct flag / env variable. That's not named a "hack", that's named knowing how to use a computer.
If you do not know how to compile and link an hello world in C. Then indeed, you should probably stay with an hello world in NPM/JS and its 1500~ packages dependencies.
Except that people have run into the exact same issue with stuff like rustc and cargo. Bootstrapping an entirely new platform is just hard, no way around it.
What? Why? Unix is a self hosting environment. You can't even boot the OS you're building on without coreutils or the equivalent.
rustc is a Rust project. Cargo is a build system for Rust projects.
> this makes it way harder than it should be to keep rustc support up-to-date in any distro
I am not aware of distro maintainers complaining about this, or at least, not any time in the last few years. Do you have some context to share? We want distros to have a good experience.
Well, they are the "core" utilities after all. This becomes less of an issue the further out in the ecosystem you get.
> at the exact versions and in the exact locations on the filesystem that the build tooling is willing to look.
This isn't strictly true.. you just need _compatible_ versions to be available, and most build tools and even the compiler itself will check several commonly used locations for code.
There are a few corner cases, but by and large, this isn't as big a problem as it might be for other languages that make writing incompatible interfaces orders of magnitude easier than with C.
> Specifically, hasten the day where my entire application dependency tree doesn’t bottom out in some Autotools, CMake, shell script, project.
Each those solve the same problem at different levels. Perhaps this is because there is no _one true_ way to replace them, and the advantage is that each project uses the tool most suited to their case.
Perhaps the built-in tools with these "modern" languages are a good general tool for the majority of developers, perhaps they aren't. If they aren't, then now you have the same problem all over again in a new ecosystem.
the tools are all there - just they're not popular and aren't widely used
I wrote a bit of an old intro to the workflow: https://geokon-gh.github.io/hunterintro.html
This is an example of a project that's well setup using this pattern: https://github.com/elucideye/drishti
And having things work dynamically ... well that's what package maintainers due. It seems inherently very fragile. Developers only build test and develop against whatever dependency versions they have locally. you can't test against every version under the sun
If anyone knows of a distribution that aims to use only software with sane build systems, let me know, I would be very curious.
It's not for "no reason", in general you will not be able to get away from having a complicated build system at the lowest level. Otherwise you would need to be prepared to give up on nice things like cross-compiling and supporting more than one compiler, CPU architecture, etc.
The problem is most distros / deployed systems are managed and bootstrapped imperatively, which there is nothing pushing back against complicating the bootstrapping. Thus, entropy wins and it gets more complex.
As someone who as actually started about reproducing BSD bootstraps declaritively (https://github.com/NixOS/nixpkgs/pull/82131/files) they are way more entangled than they need to be, so Theo de Raadt has no ground to stand on.
Its claims to fame are support for multiple languages, reproducible builds, and system-wide package caching.
What build systems like cargo seem to think is awesome is probably the most backwards idea of build systems I've ever seen. Static linking and automatic downloading of dependencies. Even the ability to directly pull from a github repo. No wonder almost nothing written in rust ever gets packaged.
Dependencies are hard, following a spec like semver seems to have confused people. Developers are lazy and don't want to think about settling down their API. Solution? Just give up and encourage bad behaviour. Thanks guys. Great solution. I think I'll stick with the previous one.
Big oof. Python packaging has a lot of problems, and defaulting to a single shared location when installing, that might conflict with your default package manager, is very high on the "What the fuck are you even doing" list of issues. You also very easily get into version hell. Unless you start using virtualenv, at which point you're basically doing the same thing cargo is.
> automatic downloading of dependencies
How is that a problem? Cargo has a lockfile to ensure the dependency downloaded is the exact same, various flags to prevent cargo from updating the lockfile (--frozen and --locked), and even the ability to vendor dependencies with cargo vendor[0]. It defaults to the most convenient things for developers because packages will be worked on many more times than they are packaged.
> Even the ability to directly pull from a github repo.
So does python/pip. And most package managers I've worked with. Crates.io will refuse packages that have github dependencies though, so this only comes up when packaging something that isn't really ready to be packaged.
As for linking, there are several rust-specific problems to dynamic linking:
1. Rust currently has no stable ABI (apart from the C ABI). This means updating rustc (and maybe even updating llvm) may cause the ABI to change, and libraries to become incompatible. There is currently no plan to fix this on Rust's part, and in fact some opposition, since it would prevent some optimizations from happening (such as niche-filling optimizations).
2. Generic functions and impls would not be part of this, as monomorphised variants would have to end up in the final binary. I believe C++ has the same problem with templates. A lot of Rust APIs are generic. This could theoretically be fixed (at least partially) through automatic promotion to dynamic dispatch, or other similar schemes.
[0]: https://doc.rust-lang.org/cargo/commands/cargo-vendor.html
Sure, but I think that what systems like cargo provide is worse across the board.
> defaulting to a single shared location when installing, that might conflict with your default package manager, is very high on the "What the fuck are you even doing" list of issues.
This is easily solved if pip was to have a way of listing all dependencies which it's about to install. Then I could mangle the names to fit my package manager's style and automatically install them with my package manager. But I will give it to you, this omission is one of the few things which pip could improve on.
> You also very easily get into version hell.
This is not a pip problem. Stop using things which result in dependency hell. Semver solved this problem a long time ago. If developers insist on not stabilising their APIs and breaking them all the time those developers libraries' shouldn't be used.
> Cargo has a lockfile to ensure the dependency downloaded is the exact same,
Great, now I can make my software depend on an out of date and vulnerable version of a library. Why do you think encouraging bad behaviour is a good thing? Yes, getting versions right is hard, but it's better than the alternative of static linking and having to update 100 pieces of software when you find a critical vulnerability in <popular network library>. This gets even worse when not only does every developer have to change this lockfile to update their code but now because they used lockfiles and as a result the upstream library developers felt it was safe to break API 100 times between when that library was locked and when it was patched. Now a simple update of <popular network library> which would involve pushing an ABI compatible patched version via distribution channels requires 100 developers to all push updates to their software which may or may not include having to re-write portions of their software.
> It defaults to the most convenient things for developers because packages will be worked on many more times than they are packaged.
Only because you allow and encourage it to happen. Which I hope I've made my point clear is NOT a good thing.
> So does python/pip. And most package managers I've worked with. Crates.io will refuse packages that have github dependencies though, so this only comes up when packaging something that isn't really ready to be packaged.
So it's good to see that this issue has been appropriately addressed. I wasn't aware that this was a restriction of crates.io. That being said, it doesn't stop everyone and their grandmother from just not using crates.io for certain things and not having their stuff on crates.io.
I wasn't aware this was possible with python but I also never see python packages using it.
> Rust currently has no stable ABI (apart from the C ABI).
Which isn't a good thing.
> 2. Generic functions and impls would not be part of this, as monomorphised variants would have to end up in the final binary. I believe C++ has the same problem with templates. A lot of Rust APIs are generic. This could theoretically be fixed (at least partially) through automatic promotion to dynamic dispatch, or other similar schemes.
I think Ada has a solution for this. Not 100% sure but it can't be impossible to solve if only rust developers made it their goal to make libraries work somehow.
rustc is also built with cargo, and it is packaged on most distros. A lot of distros are including packages of other tools too.
Now if python had a way to do this and package managers refused to interopate (as I believe would happen) we would have a different discussion.
Such ecosystems come with incredible costs. For instance,
rust cannot even compile itself on i386 at present time
because it exhausts the address space.
Consider me a skeptic -- I think these compiler ecosystems
face a grim bloaty future.
I would think that OpenBSD developers/users would care about security, since that's pretty much the value-proposition of OpenBSD.I know OpenBSD supports some more esoteric hardware that LLVM probably will not target, however.
Microcontrollers are the exception, but then they don't run a full blown OpenBSD stack anyways.
I guess. It's really a judgment of Rust (specifically the compiler toolchain) for this one use case.
> I would think that OpenBSD developers/users would care about security,
Maybe. Again, I think "cat" and other system tools are really low on the list of priorities for anyone securing a system. Not to say that they don't represent attack surface, by any means, but there are just a lot of things to do before rewriting the utility entirely.
Generally "cat" is not exposed to the internet, and if you're running a service and you said "I'm concerned about local attackers using cat" it's probably a lot easier to just put the service into some sort of environment (container, sandbox, user, whatever) that doesn't give access to cat.
Totally agree on this point. In fact, I think it’s brash for the rust armada to think that the borrow checker alone is going to help replace 20+ years of maintenance on these kinds of tools, which often crufty, and gnarled by the sands and whims of generations that preceded us.
Yes, you can lock things down with jails/containers, but it’s a valid target. Defense in depth, and all that jazz.
You do realize that OpenBSD is, by far, the most secure general purpose operating system specifically due to decades of thankless work by people like Theo de Raadt, right?
I don’t think healthy skepticism of Rust is strong enough evidence to conclude that they don’t care about security.
OpenBSD's website says things like "Only two remote holes in the default install, in a heck of a long time!", but remote holes in the default install is such a small surface on any OS (besides e.g. Windows XP). When was the last time you saw a remote hole in the default install of, say, Ubuntu desktop? macOS? The Amazon Linux AMI?
The interesting vulnerabilities are in server software that isn't running by default, local privilege escalation, etc.
Also, weren't there like four security bugs in December, at least one of which was remotely exploitable?
didn’t linux move a packet routing vm into the kernel in the last ten years? I’d say chances are high there are multiple exploitable holes just based on time and surface area alone.
Literally right now, with snaps. If you only mean unintentional remote holes, and not deliberate backdoors, then we have very different ideas of what "most secure general purpose operating system" means.
Also, BSD doesn't generally actively refuse to fix security holes when thousands of people compain about them.
Also, if I understand your unstated argument correctly, even if we don't admit a difference between unintentional remote holes and "deliberate backdoors," there's still a huge and meaningful difference between remote holes that can be exploited by a tiny number of people and remote holes that can be exploited by anyone.
Are you forgetting the time they sent local filesystem searches to some spyware company? And that's just things that were a: deliberate, and b: public enough that I remember them off the top of my head despite not having used Ubuntu in years? (I forget which specific problem made me drop it, or I'd probably have a third example.)
OSX is a toxic, vendor-supplied-malware infested cesspit that I've never used and don't pay much attention to, and I've never even heard of Amazon Linux, so I wouldn't expect to have examples for those.
> the "OpenBSD cares more about security than everyone else" narrative
Actually, my claim was that Ubuntu (and maybe a significant fraction of "everyone else", but that wasn't really my point) is actively opposed to security.
> even if we don't admit a difference between unintentional remote holes and "deliberate backdoors,"
There is a difference; there's a huge difference; deliberate backdoors are much, much worse. This kind of shit is something I would expect of Microsoft (Windows) or Google (Chrome).
That was not a remote hole.
> OSX is a toxic, vendor-supplied-malware infested cesspit that I've never used
Sure, but is any of the vendor-supplied malware in that cesspit a remote hole?
I'm happy to have broad, open-ended arguments about who sucks more in new and innovative ways, but let's finish the argument we're already having first. Is OpenBSD meaningfully more secure than other operating systems on the axis they are choosing to advertise, namely "remote holes in the default install," than other OSes?
In particular, whatever you believe about deliberate backdoors, toxic cesspits, being actively opposed to security, etc., none of that is something the choice of programming language is in any way relevant to. If Theo's argument were "We don't need Rust because we are the only operating system that isn't actively opposed to security, so everyone else has lost the game already," we'd be having a very different conversation. But it's not and we aren't.
Yes, I think it is fair to say that I am very familiar with all of this information. I work in information security, and was quite into Linux kernel security for a while. I disagree with your assertion about it being the most secure general purpose OS but I'm not gonna go there :)
> I don’t think healthy skepticism of Rust is strong enough evidence to conclude that they don’t care about security.
Cool, that was not my conclusion either. I'm saying that Rust's value proposition in general includes memory safety and I think that it's not compelling for most developers, especially with regards to rewrites of low-value attack surface.
Could you please go there? I'm very curious what the contenders for "most secure general purpose OS" might be.
I think maybe as a "with 0 configuration to the OS/ services" OpenBSD could be a top contender. With "I have practical security challenges to solve and I'm willing to change things in this system" I might choose Linux. If I'm handing a laptop out to an employee or friend, maybe a Chromebook, or even Windows! It's a pretty nuanced discussion that I couldn't do justice to without really caring and feeling that everyone involved in the conversation is equally invested/ coming in with the right attitude, which is impossible on an internet forum.
Bad developers don't, but many developers do. The Rust project itself has hundreds of contributors, to the point that it feels that it has more contributors than LLVM itself (I work on both, and this is an unbacked feeling I get from the velocity of the contributions).
Point being, if developers wouldn't care about Rust, they wouldn't be developing it.
I believe Rust's success has less to do with memory safety, which I think most developers (anyone coming from a GC'd language) consider table stakes, and much more to do with great documentation and incredibly powerful primitives and ecosystem such as the type system, cargo, crates.io, etc.
In general, Rust allows you to write software that doesn't break silently. That's a quite good value proposition for large scale software, where other languages often require programers to be super careful with refactorings, while in Rust you can really refactor all the things.
The reason people are afraid to do large refactorings in say C++ is often "security-related": fear of introducing segfaults, memory errors, undefined behavior, threading errors, etc. but one can also see these fears as "productivity-related" (hours and hours of debugging), or through many other lenses (shipping bugs to users, having a segfault in the middle of a demo that costs you a client, introducing a segfault one day before the release of your game, etc.).
In general, every programmer wants to have a certain degree of security that their software "works" for some definition of "works". For some this security might be actual network security, but for others it might mean that they don't want their data-science app that has been running for a week burning thousands of dollars to crash due to a segfault while writing the results.
If they are external resources, there is little it can do.
While an improvement, it isn't a full solution, specially in the domain of distributed computing.
For distributed computing, you typically use message passing of some form via network sockets, that's "safe" by design. You can also use RDMA, and there usually your process needs to opt into that, create an RDMA readable/writable region, and you are back to the mercy of your network stack up to which kind of protection you can enforce there.
From Rust point-of-view, if you make the wrong assumptions about shared memory or RDMA regions, your program has a bug. The fix is simple, use appropriate atomic (or atomic volatile) to read/write from those regions. Even if another process is writing while you are reading, as long as the operations are the right ones (e.g. <128-bit atomic reads/writes), you can avoid memory unsafety and data races.
This won't protect you from deadlocks or race conditions, etc. but that's not something that any programming language does. Rust has deadlock protection within a process, but that's not required for safety, so it is an extra feature on top.
It’s not always security, but that’s always a plus (though I have no idea if bat is any more secure than cat). I can make the same statement about exa and many of the other tools that are getting better in the Rust suite of CLI tools.
A fiction indeed. This is how developers actually behave. If you build a better mousetrap, lots of developers will all too quickly give you n reasons why it's terrible, and why you won't be able to pry their (punch cards/assembler/compiler/favorite-language/favorite-tool) out of their cold, dead hands.
This has been true, literally since the modern era of computer programming began in the middle of the last century, and it shows no signs of abating.
"Please use the original title, unless it is misleading or linkbait; don't editorialize."
HN has enough sensational Rust discussions with fresh articles and didn't need to supplement those with a 3-year-old one. Oh well, win some lose some.
First he doesn't know about ripgrep, which is far better than GNU or BSD grep.
Second,none of the known grep's can find unicode strings. Redhat carried along the uni patches for a while, but when people complained about performance on the new utf8 locales, they dropped it. coreutils is still missing unicode support, so we don't find equivalent strings with different bytes. No normalization, no fold casing. Rust based coreutils could solve that, because they have the proper libs which are better than in C land and could survive the perf critics.
Third, rust is not secure. Just more secure than C. Memory safety, thread safety and type safety are lies. People buy it, but Theo should know.
ripgrep isn't POSIX compliant. Never was and never will be. So I don't think it's really applicable here. ripgrep is maybe an existence proof that a competing tool can be written, but it is certainly not a suitable POSIX compliant grep replacement. Building a fully POSIX compliant grep tool with good performance like GNU grep is pretty difficult. It could be done. It would probably take me a couple months (and only by leveraging my existing work). I just don't have any incentive to do it, personally.
> Second,none of the known grep's can find unicode strings.
That's definitely not true. GNU grep can do this just fine:
$ echo 'Δ' | LC_ALL=en_US.UTF-8 grep '\w'
Δ
$ echo 'Δ' | LC_ALL=en_US.UTF-8 grep 'δ' -i
Δ
GNU grep does pay more of a performance penalty for Unicode support than ripgrep does. It's easy to see this with a somewhat pathological case by comparing `rg '\w{42}'` with `LC_ALL=en_US.UTF-8 grep -E '\w{42}'`. (Not all cases are pathological, but ripgrep and GNU grep are both very good about literal optimizations, so it's easiest to demonstrate with a pathological case.) I'm not sure if one can attribute this to better library support in the Rust ecosystem though. It's really about how the regex machinery itself is built.Unicode search needs do be optimized to normalize characters, and similar problems exist for case folding, grep -i
These problems are also security relevant btw. Many unicode strings are now identifiers, like names or file paths. that the stdlib still provides no functions to search and compare strings is a much bigger beef. grep is just a symptom of a much bigger problem
A grep tool that did normalization would be extremely slow. You'd probably be better served by a specialized tool. Or even better, it should be possible to write a fairly simple wrapper that puts everything into your desired normal form before searching.
- I am using grep(1) on unicode stuff in Spanish on XTerm just fine, even in ed(1). This is not a GNU craputils base, but the OpenBSD one. Heck, I type Spanish only characters with ed(1) in order to write my phlog. I can use nvi(1) from ports, but ed(1), fold(1) and ispell(1) are more than enough and I can forget about switching modes.
- That's a great example of Cargo Cult.
- On Unix and descendants, plan9 gave us UTF8, and fore sure it's grep supports more UTF8 stuff than your non-existant Rust based OS.
> Developers in particular don't generally care about security
Thanks, now I have to clean a mouthful of coffee off my screen!
Again, quoting Theo directly...
> However there is a rampant fiction that if you supply a new safer method everyone will use it. For gods sake, the simplest of concepts like the stack protector took nearly 10 years for adoption, let people should switch languages? DELUSION.
Anyways, I think you've clearly misunderstood my point.
If people wanted memory safety so much, they could have done that years ago with Java
Static linking might be good for folks distributing a single server binary over a fleet of machines (pretty much like Go's primary use case), or a company that only cares about a single massive binary containing the OS itself (the browser), but it stops "being cool" very quickly on a typical *nix system if you plan to have hundreds of rust tools lying around.
Size _matters_ once you have a few thousands binaries on your system (mine has short of 6k), think about the memory requirements of caching vs cold-starting each, and running those and how patching for bug or vulnerabilities will pan out. There's a reason dynamic linkage was introduced and it's _still_ worth it today.
And rebuilding isn't cheap in storage requirements either: a typical cargo package will require a few hundred megabytes of storage, likely for _each_ rebuild.
Two days ago I rebuilt the seemingly innocuous weechat-discord: the build tree takes about 850mb on disk, with a resulting binary of 30mb. By comparison, the latest emacs binary from git rebuilds in a 1/10 of the time with all the features enabled, the build tree weights 150mb (most of which are lisp sources+elc) with a results in a binary of 9mb, not stripped.
Under the very specific constraints that Rust is operating in, static linking is currently the best option.
That said, I wouldn't mind seeing some kind of ABI guarantees that make dynamic linking possible. https://gankra.github.io/blah/swift-abi/ is a great, accessible read on some of the challenges of making a stable ABI, so I certainly don't expect it SOON.
I do wonder if there is some scheme that could be adopted in a performant way for making the ABI stable as of the Rust Edition, even if it were only for core and std, statically linking everything else?
Static linking makes your deployability worries go away. That's not to say that isn't at least possible with dynamic linking, but the complexity and gymnastics will sink you. Everyone gets bit by it eventually.
Isn't that furthering my point?
If all of your engineers die in a fiery plane crash en-route to the company offsite, or your datacenter is wiped out in a flood, at least you have your statically linked binary that can run on commodity servers somewhere.
You have the peace of mind of knowing that your code as built should be able to run somewhere else in its current state without modification. You don't have to worry about the package availability of something that may have been around when you shipped your servers but may not be when you go to ship them again, or something that only coincidentally worked because your systems were installed via a certain upgrade path that's no longer reproducible.
It's a simple matter of business risk and minimizing surprises.
Not everyone values deployability as much as you (or employers, I suspect) do. On my personal computer I care about getting security patches and disk usage.
Over 65% of startups have less than 6 months of cash reserves right now and 74% have been laying off staff. It turns out the majority of people are poor long-term planners.
I personally don't care about how you manage your personal workstation, but you're not who most of us are building for. Most of us aren't building tools to support you. We're writing a big ecosystem for everyone to collaborate.
In a professional setting, problems with how people manage their computers aren't acceptable. Any decently-sized company will get rid of such a problem quickly. In smaller companies I've seen people get fired over poor management of their workstation's environment.
Also: static linking is not deployability if the source code is not shipped to the target - you don't have _my_ version of a library which is patched to support my hardware.
Dynamic linking is a better use of user resources, which is sort of ergonomics.
To say one metric should be king without context is missing the point.
A good linker will shave off the parts of a library you're not using, and the parts which are left over are usually not very big. The problem isn't with static linking, it's that some "developers" think that bundling an entire Chromium build with their app is a good idea.
Rust has a problem with big binaries (so does Go), but that's Rust's problem, not static linking's problem.
Dynamic linking only works if you can guarantee ABI stability and folks haven’t had to deal with ABI changes since C++13 to the point where if the C++ folks can’t change the ABI by C++23 we will forget it was ever a problem because we’ll make the cost of change too hard. And the current C++ ABI currently makes some parts of C++ executables sub-optimal unless you hunt down your own standard-library alternatives.
Additionally, with dynamic linking, both code authors and code users now need to agree on versions to support under assumptions that newer features in newer libraries aren’t worth adopting quickly. To that end, some OSes do update dynamic libraries more quickly, but doing so theoretically requires a lot more recompilation and potentially you’re downloading the same binaries more than once. At that point, dynamic linking is worth less than a binary-optimized compression algorithm, no? Especially for distributing changes to said executables.
Which isn’t to say, for OS distros, that dynamic linking is bad, far from it, it tends to be the only valid solution for programming against OS core components, but that in our haste to update dynamic libraries independently of code compiled for them, we tend to forget ABI compatibility and the costs to maintain API compatibility across a wide variety of dependency versions for packagers and developers (or alternatively, the lack of updates to new library features for end users).
Windows APIs never changing is the reason Windows stagnates more than macOS, where Apple is less afraid to say your older app simply won’t run any longer. Linux suffers less from this, but as pointed out in the email, part of that is because POSIX implementations are relatively stable over decades, whether or not significant improvements are still possible for more modern UX or security, for example.
The details of dynamic linking on OS platforms can be found in this recent series of posts: https://news.ycombinator.com/item?id=23059072 (in terms of stability guarantees besides libc dynamic linking)
You can have dynamic linking with ABI stability with stuff like COM and UWP.
It is also the only viable way to do plugins in scenarios where IPC is too costly.
Does Chromium offer any other type of linking? I mean, is the problem in the developer including it when another option is possible or the fact that no other option is possible?
But before that time the chromium bloat is 100% independent from the static linking bloat.
For what it's worth, rustc does support dynamic linking, both for system dependencies and crates. You can compile a crate with the type `dylib` to produce a dynamic rust library, that can then be linked against when producing a final binary by passing ` -C prefer-dynamic`.
I don't think it's possible to make this work with cargo currently, but there are a couple open issues about it (albeit without much activity).
And of course, rust not having a stable ABI means the exact same rust compiler (and LLVM version, I suppose) would need to be used when compiling the dynamic libraries and final binary.
There has been work done on using sscache for cross crate build artifact caching to reduce the footprint when building many binaries.
I wish they went as far as Go with their ability to produce fully static binaries and allow for cross compilation. Go's ability to have one CI pipeline running on Linux that then produces binaries that run on every conceivable version of Linux, Mac and Windows is a huge productivity boost.
For most of my use cases, they don't go far enough with static linking!
Also Rust is still evolving. They still have to add major new features to the compiler instead of being able to implement features like raw dylibs which would remove the need to include .lib files.
The libc is only part of the greater issue of community tolerance of C components in the stack, like openssl or host OS TLS implementations, while Go mainly seems to just use the tls implementation of the language creators. There is rustls but it's not regarded as good enough and the defaults are using native-tls or openssl. And even rustls uses C components as it builds on ring which has C components of its own...
https://www.scientificamerican.com/article/1959-cargo-cults-...
Not everyone knows this term, surely.
And I didn't know the Rust package manager is called "Cargo".
Unless it wants to leave some scenarios open for the systems programming languages that offer tooling for them.
Due to subtle binary incompatibilities in shared libraries, a CD pipeline I maintain costs twice as much money to run in order to target MacOS and Debian systems. It's not "worth it" to me.
Static linking is a cornerstone of what I'd call "deterministic deployment." The cost savings of deterministic deployment are so immense that after reading your comment and reacting to it, I'm tempted to estimate how much money dynamic linking will cost my business this year and how much money we'd save by reworking our build tree to compile our dependencies from source and maintain static libs on the targets we care about.
>And rebuilding isn't cheap in storage requirements either: a typical cargo package will require a few hundred megabytes of storage, likely for _each_ rebuild.
shrug I don't care about build storage requirements until we start talking tens to low hundreds of GB and disk I/O becomes the time bottleneck or caching costs real money in CI.
I'm going to tell you that static linking is the only way to go.
The idea that needs to die is the personal workstation. It's just another deploy target. Ideally whatever is doing builds is reproducible and throwaway. Leaving those artifacts around on disk introduces its own host of problems.
Disk is cheap and you shouldn't have tons of binaries on your systems for no good reason.
(Aside from this though, I'm in full agreement with Theo.)
Arguable, but I'll grant you this. But RAM ain't cheap.
Each of your virtualized/containerized systems are going to have their own distinct instances of the shared libraries, so you're getting a fraction of the benefits of dynamic linking if you're doing your infrastructure properly today anyway. Stop keeping pets.
How many of these big binaries are you running on your servers at once?
Certainly not mine, my memory deduplication is doing just fine.
I'm currently building Firefox, it takes ages. It is marvel such complexity still manageable on customer hardware. Emacs is from another age.
[1] https://blogs.windows.com/windowsdeveloper/2020/04/30/rust-w...
Stable ABIs are hard, and we have a lot of other work that's a higher priority for our users. There is no ideological opposition to dynamic linking, only practical blockers.
_Rust and OpenBSD are not a good fit._
OpenBSD keeps to certain aspects about how to do thinks which just don't work well with rust. This doesn't mean they are better or worse. They are just different.
For example outside of rustc-dev hardly anyone compiles rust them self. As such not many work on making rust compile itself on exotic systems (and yes in 2020 i386 is a exotic system, even through it was the standard in the past). I mean improving cross compilation is for now much more important (as far as I can tell).
But OpenBSD requires the ability to self compile and support hardware for a very long time so rust (for now) doesn't fit.
Another example is that many rewrites of classical small tools provide little value to anyone _if_ they are 100% compatible. As such they tend _to not be compatible_ in favor of better interfaces/output etc. (E.g. ripgrep!!)
Lastly OpenBSD is stuck in a world where thinks move very slow. But this is also why many people use it. One the other hand rust is from a world where thinks move much faster, sure with small steps and backward compatibility but a small step every 6 weeks is still a lot over a fiew years. So they just don't fit well together.
I also believe that in the future they might fit well together at some point. But not for now and probably not in the next 3 or so years.
This is in fact incorrect--there is a project aiming to build all of the coreutils in Rust (https://github.com/uutils/coreutils).
More to the point: while I do concur in the conclusion that Rust shouldn't be a part of the OpenBSD base system, the gatekeeping implied here (it's not a serious language because it's not used to build an operating system) is really toxic. Especially considering that the gate in question has already been thoroughly breached by the language in question (some universities have switched to using Rust in their OS courses, for example).
I would still agree with his statement at least as far as BSD is concerned. Outside of Redox I haven't seen any serious projects to implement POSIX compatibility. The Rust coreutils project is a good start but from their readme it looks like they are more aiming to achieve GNU compatibility on Microsoft Windows while being MIT licensed — I don't think anyone is seriously using it to build a BSD (or even a GNU) distro. If I'm wrong about that I'd love to hear it though. Rust is a good choice to write these things in but let's be realistic about the time frame required to rewrite everything.
Plus I just downloaded those Rust coreutils and tried to build it and now I'm waiting for 400 (!!!) Rust dependencies to download and compile. Is this really appropriate for a core system component to have this many dependencies? Or is there something I'm missing here? I admit I am not familiar with best practices in Rust. As the project stabilizes I assume they will want to start eliminating the dependencies or vendoring them upstream? At what point do we decide to put these into a separate library like libbsd or gnulib?
There may be some platform-specific dependencies, but at least when building on Windows, I saw 67 dependencies downloaded.
One thing that may be skewing the count is that internally coreutils is packaged with one crate per command. There are about 100 commands, so you'll have seen at least that many separate crates building. They're listed here: https://github.com/uutils/coreutils/blob/6e8c901204934029c88...
My impression is that ecosystems where tracking dependencies is hard tend to discourage them, while ecosystems where tracking dependencies is easy encourage them. The coreutils crate depends on separate md5, sha1, sha2, and sha3 crates, if managing external dependencies was hard I imagine those would be bundled together. But it is easy, so it makes sense to organise the crates so that each just provides one specific piece of functionality. Think single responsibility principle applied to packaging.
Thinks like `cargo tree | wc -l` or the number of dependencies cargo builds are not appropriate as they count _internal_ dependencies (from the same repo).
Given that it's split into many "sub-crates" in the same workspace this will make the numbers unnatural high.
Or with other words _most_ of the 417 "dependencies" for building the "unix" feature set are internal ones in the same repository. I.e. the project is just split up into many small parts.
Additionally many deps are reused between many internal deps.
Removing duplicate dependencies, dev-dependencies (e.g. testing tools) and build dependencies less then 100 deps are left.
Looking through them many are rust versions a C/C++ libs which are "available per default", like e.g. unix_socket, libc and similar.
Then some are thinks which come from rust deps being split up more, e.g. there are md5, sha1, sha2, sha3 as separate crate.
There are also a bunch of "internal" deps of deps e.g. backtrace-sys.
Anyway still a lot of deps but most are quite reasonable and could be "taken care of" in some way or another if they want to ship a distro based on this.
POSIX compliance is a headache which is not only hard to get right but also strongly limits your interfaces and internal tooling.
Many scripts still will run with non full compliance, but that doesn't help if you try to build for OpenBSD.
Also I'm not sure how they ended up with 400 deps for coreutils. I would have expected much less. But yes this means at least until better code signing and so on is the default this isn't at all appropriate for the base of any OS.
I just which the author would have written it a bit less mean in it's wording. (Probably was just annoyed, but sill).
> To actually achieve POSIX-compliance is not an easy task and requires lots of testing.
Why are the existing tests not enough for a new implementation?
Absolutely not. The entire OpenBSD base system can be built without an internet connection.
His reply is not great, but IMO posting to some venerable old project's ML saying, in the abstract and without actually having made any effort to analyze the issue in depth "Under what conditions would you consider replacing one of the current C implementations with an implementation written in another, "safer" language?" comes off as rather rude and not very productive IMO. I can understand him shutting it down immediately instead of wasting his time arguing with programming 101 students who cargo cult Rust without understanding the reality of maintaining something as complex as OpenBSD.
* It takes a long time for a rewrite to be fully compatible and a good implementation. This project says it uses the busybox tests and that seems like a good start. Is it good enough though? Busybox itself is quite good for certain embedded niches but it would be absurd to replace a good chunk of OpenBSD userland with that, the usability would suffer a lot.
* OpenBSD needs to compile itself, in reasonable time, and at the time of the writing rust was slower than C at this and could not self host on 32bit x86 due to address space limitations. Has it been fixed?
Not to mention that Busybox (last I checked) uses a license unsuitable for inclusion in OpenBSD (which is trying to reduce the amount of GPL-licensed software in the base install).
He's not gatekeeping in that way by saying that Rust isn't used to create OS utilities (which as an aside is what he actually says. He doesn't say anything about building an OS) and therefore isn't a serious language and therefore shouldn't be included in OpenBSD*. He's saying it's not used for making OS utilities and therefore has no specific use in OpenBSD that requires it to be in the toolchain. Very different points with the latter being pretty reasonable, imo.
Also, I am a bit confused about the gatekeeping implied here (it's not a serious language because it's not used to build an operating system) is really toxic.? Which line in the e-mail stated that?
> As a general trend the only things being written in these new languages are new web-facing applications, quite often proprietory or customized to narrow roles. Not Unix parts.
Which I read in the tone of "go play with your toy language somewhere else, and let the real programmers program with real languages. Additionally, there's the allusions to the fact that the ls/grep-replacements in Haskell aren't POSIX-compliant, which I again read in the tone of "they can't be taken as serious replacement efforts."
There was a little bit of editorializing there but if 'base builds base' is table stakes then start working on that coreutils project first.
It's Theo de Raadt, toxic rhetoric is sort of his brand.
But... he has a real point here. It's not about grep or cat or whatever really, those are just the use cases for which OpenBSD would care.
It's that as Rust is reaching the second decade of its history, and despite some outrageous wins in press, evangelism, and general developer mindshare... Rust just hasn't made much progress in replacing exactly the software that it claims to be intended to replace!
Where are the pervasively used compression libraries in Rust? Video and audio codecs? Network stacks? Database engines? System management utilities? PKI and encryption stacks? All that stuff is still in C. After ten years of Rust success!
It's not like no one is using Rust. It's not like it doesn't have success stories (even in the categories above). But they're comparatively rare, still. There's nothing in Rust that rises to the category of "stuff everyone just uses because it's what everyone uses" (c.f. zlib, libjpeg, readline...) yet.
And if there isn't after the first decade, what needs to change to make it happen in the second. I mean, is it maybe fair to say that the window is closing for rust to take over a significant fraction the systems programming world?
IMHO, that's basically not possible, so it isn't a fair ask. If the Rust community produced a drop-in replacement that is every bit as good as readline in literally every way... still nobody would switch, because why would they? What's the benefit? You spend all this effort just to trade evenly across. If the Rust community produces something better, nobody's going to use whatever those extra features are outside of Rust itself.
This is the category of software that will be last.
The question for Rust, and equally, every other ambitious language, isn't really "What percentage of existing code will be rewritten in this new language?" (And by "rewritten", I don't just mean "reimplemented but only your community uses it, but in the sense you mean... it actually replaces the original.) If your answer is any number significantly over zero, that itself represents entrance into the absolute top tier of languages... this is very rare. The question for Rust et al is "What percentage of future code will be written in your language?" On that front, Rust is still on a pretty decent trajectory.
Sort of. It's only been five years since it was actually stable enough for production use. (with a few exceptions of folks who were really invested)
But take a look on Firefox:
* Video and audio codecs - MP4 metadata parser, Audio backend
* Database engines - key-value storage backed by LMDB
* Network stacks - A QUIC implentation, SDP parsing in WebRTC
* PKI and encryption stacks - TLS certificate store
* And more https://wiki.mozilla.org/Oxidation
Just five years since first stable release.
It's not ten or 20 years, the first release of Rust was in 2015. Pre-1.0 Rust was a wildly different language, with green threads, segmented stacks, regular and wild breakage, not really a C replacement! Please understand this point.
But anyway here are some projects:
https://github.com/ctz/rustls a TLS library that uses https://github.com/briansmith/webpki a pki library
https://github.com/burntsushi/rust-snappy a compression library
https://github.com/tikv/tikv a database engine
https://github.com/hyperium/tonic a gRPC library
https://github.com/tock/tock an embedded OS
https://lib.rs/command-line-utilities lots of CLI utilities which include system management
You ask for "pervasively used" but this is not under control of Rust itself. It's not feasible to replace decades old setups in five years.
The most widely deployed Rust stuff is in Firefox and some Gnome libraries AFAIK.
> I mean, is it maybe fair to say that the window is closing for rust to take over a significant fraction the systems programming world?
I don't see why this should be the case.
I read 2013, Theo de Raadt's email is from 2017, over 4 years later. I think we can fault him for being overconfident and not checking his facts.
They'd be infinitely easier to persuade to try something like this than a BSD. For OpenBSD it's probably always going to be a non-starter because of all the hardware they'd have to leave behind.
It also does not address the concerns of higher build times compared the contemporary C counterparts, which also support far more platforms than Rust.
The use of cargo for example suggests that at least a few uu utilities makes network connections at build time to fetch dependencies!
For example something as simple as chown:
https://github.com/uutils/coreutils/blob/master/src/uu/chown...
The words 'gatekeeping' and 'toxic' are toxic.
They just don't get exposure in FOSS land.
Rust explicitly aims to be a systems language. It explicitly challenges C and C++ on their own turf. Implying that it's not suitable for serious systems work is insulting.
> Note that the email conversation was from a few years ago.
Remember that the project he said didn't exist was 4 years older than his email. And if I understand other comments correctly, that project was well known among Rust practitioners.
He made strong claims outside his area of expertise. An easy mistake to make, but one that has consequences when you're this famous. Such mistakes are totally fine in private, but in public… they're a little toxic.
When you re-write a tool, _why not improve it_? (Especially if the chance that the 100% backwards compatible rewrite will not be accepted anyway).
For a bunch of tools exactly this happens, a new tool which provides the (roughly) functionality but a new (IMHO often better) interface, slightly different options or syntax (for got reasons). Etc.
An example for this is ripgrep (rg), which already became a widely used replacement for grep. It's just not a drop in replacement. (It couldn't do what it does if it would be).
Any new tools that have high resource needs, don't support all the more exotic/esoteric platforms that it supports, are all nonstarters if your goal is a very small core system that compiles quickly on all supported platforms.
Instead he personally attacks people.
commit d4e96b33e343733992fad55ac840c9649cd72ede
Author: Jordi Boggiano <j.boggiano@seld.be>
Date: Fri Aug 2 09:22:57 2013 -0700
Initial commit
Although I hope that Redox[2] takes off more so than rust makes it into existing systems. I dream of one day ordering a System76 with Redox already installed.Yeah, I agree: if the sole value proposition were 'security' it would be a really slow roll. cargo is the killer app IMO. Anyone who's walked a big dependency tree - download, build, oh oops this requires libfoo - download, build, oh oops that requires libbar...
But I think lots of coders land on rust because they want or need something faster or more portable than Python or JS and rust is 'easier' than C.
If that's supposed to be a poster child of how well rust tools work, I fully understand Theo's vitriol.
In 2020 I personally use ag 99% of the time, and when I do use grep is because its options are burned in my brain and it saves me 30 seconds by not looking up the equivalent for ag.
But ag isn’t a drop in replacement for grep, and when you have tooling that’s depends on that, replacing it simply isn’t a viable option.
This should have been at the top of the email because this is the main issue (along with the i386 one). As other people have noted in this thread some people have already re-written basic utilities in Rust (and other languages).
Unless someone manage to make the Rust compiler much much faster then it is currently it won't get accepted into OpenBSD anytime soon.
Is this true anymore or just a history note?
Last I checked Rust needed more than 4GB of RAM to compile itself.
This is Theo de Raadt on integrating Rust utilities in OpenBSD.
We need to make memory safe languages accessible and with that, the tools and other frameworks for a new language isn't an easy path.
Which gets to an aspect in many walks of life - if you are doing something from scratch - you can use the latest knowledge and enforce that, but knowledge moves on and bringing up the rest of the system inline with a what is needed to use that new language/knowledge is not an overnight task, it's a slow process - and even if you provide something better, you can not guarantee it will be embraced at a needed pace to keep the momentum going.
Much like anything in life, you have better trains than you did when they was invented, but legacy infrastructure precludes an instant/overnight switch, due to impact upon what is used currently.
So case of, requirements for something better like rust support, is a bit of a catch-22 as you need it there to get the people to use it so tools get written, but to get it there you kinda need the tools so that people use it to write the tools. Hence the first step is always the biggest.
Which makes you wonder how intertwined aspects of the OS and programs are, even with standards like POSIX, there is clearly a bigger larger standard needed.
This along with the dependances and you can see why docker and other application level virtualization has much going for it.
Wow, that one was really cruel.
- Embedded systems and "Internet of Things" (IoT) devices
Many operating systems and toolchains continue to support i386: https://itsfoss.com/32-bit-os-list/
Just because you do not use it does not mean other people do not.
Rust and OpenBSD share a lot of technical values though so maybe this isn't surprising. Rust values safety and correctness. OpenBSD values safety and correctness. Rust values 'Just Works' with all the nice things cargo does and the whole 'fearless refactoring / concurrency' thing. OpenBSD values 'Just Works' with sane defaults and the 'batteries included' base system.
In a new system you may not need cat though, but if you're a unix system with a heavy shell and textual basis, you do need lightweight versions of these things - light to build, light to run, and well integrated into the environment.
What's the path out for unix systems? I have no idea, but at least as of today I have not seen a modern safe language that is ready to replace unix use cases. Maybe zig? It's hello world is at least under 10kb.
My problem is the ecosystem. The packaging and build system clearly isn’t designed to accommodate classic desktop applications. The FFI is really painful, and even Firefox has tons of wrapper code to just integrate with the libraries it needs to have a GUI.
In that respect I agree with Theo in that Rust developers are focusing on far too narrow of a use case, mostly web facing applications or data processing. Cargo being so similar to npm kind of confirms this. Rust isn’t intended for me.
The only reason he might still be right is if they don't aim to be POSIX-compliant. The page doesn't explicitly call out compliance as a goal, but given that it has some busybox tests, it's probably compliant or very close.
It's seldom a very interesting or constructive discussion. If you think Rust has something to bring to some project then you should at least take the time to write a decent proof of concept or something similar, not ask the current maintainers to rewrite their codebase in Rust/Go/Haskell/Prolog because of some purely theoretical benefits. You don't go to construction workers in the street and tell them that they should consider using different types of hammers.
To improve security, Rust should probably aim to replace libjpeg and other stuff which deals with malicious data a lot.
>As a general trend the only things being written in these new languages are new web-facing applications, quite often proprietory or customized to narrow roles. Not Unix parts.
This doesn't really match what I saw of the Rust ecosystem and, even if it did, being able to write proprietary web-facing apps doesn't preclude one from writing "Unix parts". It's as if I said that C++ couldn't be used to write Unix utilities because it's used to write proprietary videogames. It's not a very good argument IMO.
Once there are a large number of core utilities implemented in Rust that show some significant practical benefit over the C versions, the situation may be different.
It is also very difficult to come up with a definition of "memory leak" that doesn't include programmer intention, and so it's not clear that you can come up with static analysis to preclude it.
Rust is a stepping stone. It is a proof of concept that shows a lot of problems can be solved at compile time without adding huge bloat at runtime.
Yes, Rust has problems. Some of them are just because the language is new and you feel not yet fully built.
The compile times are more more insidious side effect of Rust's properties. I think, realistically, it will take some time but the problems will be resolved either in future Rust or in another language based on it. And it will be very worth the wait.
High level languages are fun and important, but it is not possible that all system code is going to be built in high level languages. As we run stuff that is more and more demanding of CPU we need a good low level language that will also tick some important checks of reliability.
And what can I say - after about 3 hours and max memory usage of about 31% (or a little less than 1.8GB) the compile finished without errors.
So could you please point me to the source of your claim? Did I just uncover some magic loophole that allowed me to achieve this feat while using less than 2GB of RAM? What did I do wrong/right?
Your builds don't need more memory, they need more address space. You can convince me otherwise by enabling PAE and still running into the issue. Until then I stand by my point.
For my money ripgrep knocks the socks off of grep. I can't recall if it's perfectly posix compliant but it's blazing fast and has a much nicer output.
> Do you care about POSIX compatibility? If so, then you can't use ripgrep because it never was, isn't and never will be POSIX compatible.
So at least that bit is there.
What I think would be a good candidate for first base-system rust component, in case you are considering taking on a task like this, is a milter for OpenSMTPD.
It doesn’t seem like there’s much to be gained here. Network facing software is where the big wins are.
edit: rough crowd today. Check out Send, Sync, rayon and ripgrep.
> I wasn't implying. I was stating a fact.
It doesn't affect his point, per se, but this is a confusing way to engage the topic.
This seems worth fixing. I think this is his main point.
There is also the bigger question if and why the core utilities should be re-written in Rust. Given that safety is the main value proposition of rust it may be makes sense, but it’s a much bigger discussion.
Maybe you can create something more widespread in Rust and not being a single part of a browser.
The large majority of modern compilers and languages are either bootstraped or written in a mix of the language itself and C++.
Perhaps it did, but they started 25 years ago.
(Much like the bit, "staying closed-source set back clones by weeks or months... years ago".)
https://github.com/redox-os/extrautils/blob/master/src/bin/g...
Not to mention Theo's statement is so much weaker than actually successful implementations the existence of these two completely blows through the goal:
> There has been no attempt to move the smallest parts of the ecosystem, to provide replacements for base POSIX utilities.
(And yes, Theo, like many hackers, is prone to exaggeration.)
Huh? Some days all I see on HN fron page is "X written in Rust" projects, where X is some long existing tool (now with colorized output by default!)
The guy does a lot of work maintaining OpenBSD but it looks like people only upvote his pointless flaming. This is practically TMZ for Nerds stuff.
I think I'll block Theo de Raadt for myself on HN.
I don't want to be harsh, but who the hell is compiling anything on i386 now? Real question, is anyone even making fresh i386 hardware that might be used by consumers, or deployed in datacentres?
I do, however, think it is odd that OpenBSD would value compiler size over security, given the philosophical values of the OpenBSD project. I would expect that sort of opinion (and agree with it) in the NetBSD project, but I would think that OpenBSD would be willing to put up with big compiler binaries and slow compile times in exchange for even small improvements in memory safety. Strongly and statically typed languages in the ML tradition (like Rust, SML, OCaml, Haskell) all have big bloaty compilers, but that is for a specific reason: the type system that prevents you from compiling invalidly-typed programs is in essence a test suite. And for rust, a language with a type system that covers memory safety bugs, that test suite is massive.
OpenBSD is pretty famous for the comprehensiveness of its test suite, perhaps only superseded in depth by applications that lack its breadth (such as SQLite). I've never run the full OpenBSD test suite in a development cycle, but I've heard stories about running it that perhaps parallel the frustration newbies have with getting rust programs to compile.
What would an OpenBSD test suite look like if it could conclusively prove the absence of all memory safety bugs? Would Theo De Raadt be willing to put up with a test suite that ran for two hours longer and required more memory than could be allocated on i386 systems if it could do so? I think he would...because that is something in line with the OpenBSD philosophical values. So why is it that it needs to compile code so efficiently, if you're gonna turn around and run tests for 3 days to make sure nothing breaks?
> So we cannot replace any base utility, unless the toolchain to build it is in the base. Adding such a toolchain would take make build time from 40 minutes to hours. I don't see how that would happen.
So, to summarize: "We're not going to include the capability to write core utils in Rust, and also, no one is bothering to do it."
Its rather startling to me how tail-wagging-the-dog, or maybe chicken-and-egg, this situation is. Did anyone stop to consider that the reason why some of these utilities aren't being rewritten is because the unix old guard doesn't want to support it in the toolchain? If this guy is the wall that you'll eventually have to crash your car into, I'm not going to get behind the wheel in the first place. Why waste my time?
Look; the compile limitations are real. I'm not saying that it should be supported. But, attitudes like the one are not productive. What is it about operating system devs and these aggressive, mean, anti-social, self-important personalities? A response worded like this should not be tolerated by the community. It would have been just as easy and clear to say "We don't have toolchain support for Rust, and we're really not interested in supporting it due to its compile time and architecture support issues. <One sentence explaining compile time issues>. <One sentence explaining architecture support issues>. We can revisit this discussion in the future if/when these improve."
None of this is censorship.
When a smart but curmudgeonly component owner just doesn't want to accept some outsider's change, there's no end to the technical objections that component owner can raise against the outsider's change --- but these objections are just a smokescreen, and addressing them is futile, because the real problem is that the component owner has done a thing certain way for a long time and some attempt by an outsider to shake things up triggers all the owner's ancient territorial defense instincts. The actual merit of the outsider's proposal doesn't matter: the problem is social, not technical.
In a situation like this, when the intrepid outsider does manage to exhaust the maintainer's objections, the maintainer will switch to just spewing unfalsifiable FUD, to inventing further ridiculous objections, or just simply ignoring the outsider's change entirely. There's no technical fix for a curmudgeonly maintainer who really doesn't want to entertain new ideas.
In the corporate world, to resolve this problem, you usually have to go up the management chain and explain to leadership that certain people are making important work impossible. (You should try every possible alternative means of persuasion first, of course.) In the FOSS world, you just have to fork as a last resort.
If you want to reach that level then you need to commit for real, and solve those issues that Theo rightfully marks. Even though this was written in 2017 it is just as applicable today: either you replacement is as good on all fronts as the thing it replaces and has some additional benefits replacement of something battle tested makes no sense.
Typical Machiavellian talker who overestimates his own abilities, derails a working project and moves on to the next company after two years to continue the damage there.
There probably are legitimate technical issues with integrating Rust. That's fine; it happens. Maybe Rust will be better in the future (this was written in 2017, so maybe it already is). Or, maybe Rust will never be a good candidate for BSD. Any of these outcomes are possible.
I take issue with his tone, which is strongly reminiscent of Linus' management of Linux. He's welcome to be mean, but I would think long and hard about joining a community with a leader with such a disposition (I don't know Theo's history, so I can't say whether this is a pattern).
Being kind when running a project, especially of the scope of an operating system/kernel, is very difficult. Not everyone has the disposition to do it. You'll get Rust-fiends and Go-phers and all sorts of people who haven't contributed a single line come in and make wild suggestions that don't make sense, every day. You'll get HackerNews armchair commentators like me who think their opinion matters. In the face of this, its understandable to respond with scorn. But; enviable leaders instead form measured responses. You never make it personal. You never shut the door on suggestions.
Open Source, especially at BSD's scale, is not a one man army. Thousands of people have helped with that project, and its creator no longer has the blank check to be a dictator.
An excerpt from Bezos' 2010 Princeton commencement address [1]:
> I decided to do the math for my grandmother. I estimated the number of cigarettes per days, estimated the number of puffs per cigarette and so on. When I was satisfied that I’d come up with a reasonable number, I poked my head into the front of the car, tapped my grandmother on the shoulder and proudly proclaimed, “At two minutes per puff, you’ve taken nine years off your life!”
> I have a vivid memory of what happened next and it was not what I expected. I expected to be applauded for my cleverness and arithmetic skills. “Jeff, you’re so smart. You had to have made some tricky estimates, figure out the number of minutes in a year and do some division.” That’s not what happened. Instead, my grandmother burst into tears. I sat in the backseat and did not know what to do. While my grandmother sat crying, my grandfather, who had been driving in silence, pulled over onto the shoulder of the highway. He got out of the car and came around and opened my door and waited for me to follow. Was I in trouble? My grandfather was a highly intelligent, quiet man. He had never said a harsh word to me, and maybe this was to be the first time? Or maybe he would ask that I get back in the car and apologize to my grandmother. I had no experience in this realm with my grandparents and no way to gauge what the consequences might be. We stopped beside the trailer. My grandfather looked at me and after a bit of silence, he gently and calmly said, “Jeff, one day you’ll understand that it’s harder to be kind than clever.”
[1] https://www.theladders.com/career-advice/jeff-bezos-to-princ...