top | item 46513372

(no title)

tasn | 1 month ago

The recent bug in the Linux kernel Rust code, based on my understanding, was in unsafe code, and related to interop with C. So I wouldn't really classify it as a Rust bug. In fact, under normal circumstances (no interop), people rarely use unsafe in Rust, and the use is very isolated.

I think the idea of developers developing a "bugs antenna" is good in theory, though in practice the kernel, Redis, and many other projects suffer from these classes of bugs consistently. Additionally, that's why people use linters and code formatters even though developers can develop a sensitivity to coding conventions (in fact, these tools used to be unpopular in C-land). Trusting humans develop sensibility is just not enough.

Specifically, about the concurrency: Redis is (mostly) single-threaded, and I guess that's at least in part because of the difficulty of building safe, fast and highly-concurrent C applications (please correct me if I'm wrong).

Can people write safer C (e.g. by using sds.c and the likes)? For sure! Though we've been writing C for 50+ years at this point, at some point "people can just do X" is no longer a valid argument. As while we could, in fact we don't.

discuss

order

pclmulqdq|1 month ago

I hear "people rarely use unsafe rust" quite a lot, but every time I see a project or library with C-like performance, there's a _lot_ of unsafe code in there. Treating bugs in unsafe code as not being bugs in rust code is kind of silly, also.

antirez|1 month ago

Exactly. You don't need much unsafe if you use Rust to replace a Python project, for instance. If there is lower level code, high performances needs, things change.

pdimitar|1 month ago

For your last sentence, I believe topics are conflated here.

Of course if one writes unsafe Rust and it leads to a CVE then that's on them. Who's denying that?

On the other hand, having to interact with the part of the landscape that's written in C mandates the use of the `unsafe` keyword and not everyone is ideally equipped to be careful.

I view the existence of `unsafe` as pragmatism; Rust never would have taken off without it. And if 5% of all Rust code is potentially unsafe, well, that's still much better than C where you can trivially introduce undefined behavior with many built-in constructs.

Obviously we can't fix everything in one fell swoop.

j-krieger|1 month ago

There is a reason for this. A lot of libraries were written at a time when the Rust compiler either rejected sound and safe code so you have to reach for unsafe, or `core` didn't yet deliver safe abstractions.

antirez|1 month ago

In Rust you can avoid "unsafe" when you use Rust like it was Go or Python. If you write low level code, that is where C is in theory replaceable only by Rust (and not by Go), then you find yourself in need of writing many unsafe sections. And to lower the amount of unsafe sections, you have to build unnatural abstractions, often, in order to group such unsafe sections into common patterns. Is is a tradeoff, not a silver bullet.

burntsushi|1 month ago

Not necessarily at all. Go peruse the `regex` crate source code, including its dependencies.

The biggest `unsafe` sections are probably for SIMD accelerated search. There's no "unnatural abstractions" there. Just a memmem-like interface.

There's some `unsafe` for eliding bounds checks in the main DFA search loops. No unnatural abstractions there either.

There's also some `unsafe` for some synchronization primitives for managing mutable scratch space to use during a search. A C library (e.g., PCRE2) makes the caller handle this. The `regex` crate does it for you. But not for unnatural reasons. To make using regexes simpler. There are lower level APIs that provide the control of C if you need it.

That's pretty much it. All told, this is a teeny tiny fraction of the code in the `regex` crate (and all of its dependencies).

Finally, a demonstration of C-like speed: https://github.com/BurntSushi/rebar?tab=readme-ov-file#summa...

> Is is a tradeoff, not a silver bullet.

Uncontroversial.

tasn|1 month ago

I think this framing is a bit backwards. Many C programs (and many parts of C programs) would benefit from being more like Go or Python as evident by your very own sds.c.

Now, if what you're saying is that with super highly optimized sections of a codebase, or extremely specific circumstances (some kernel drivers) you'd need a bit of unsafe rust: then sure. Though all of a sudden you flipped the script, and the unsafe becomes the exception, not the rule; and you can keep those pieces of code contained. Similarly to how C programmers use inline assembly in some scenarios.

Funny enough, this is similar to something that Rust did the opposite of C, and is much better for it: immutable by default (let mut vs. const in C) and non-nullable by default (and even being able to define something as non-null). Flipping the script so that GOOD is default and BAD is rare was a huge win.

I definitely don't think Rust is a silver bullet, though I'd definitely say it's at least a silver alloy bullet. At least when it comes to the above topics.

josephg|1 month ago

In my experience (several years of writing high performance rust code), there’s only really 2 instances where you need unsafe blocks:

- C interop

- Low level machine code (eg inline assembly)

Most programs don’t need to do either of those things. I think you could directly port redis to entirely safe rust, and it would be just as fast. (Though there will need be unsafe code somewhere to wrap epoll).

And even when you need a bit of unsafe, it’s usually a tiny minority of any given program.

I used to think you needed unsafe for custom container types, but now I write custom container types in purely safe rust on top of Vec. The code is simpler, and easier to debug. And I’m shocked to find performance has mostly improved as a result.

pjdesno|1 month ago

> was in unsafe code, and related to interop with C

1) "interop with C" is part of the fundamental requirements specification for any code running in the Linux kernel. If Rust can't handle that safely (not Rust "safe", but safely), it isn't appropriate for the job.

2) I believe the problem was related to the fact that Rust can't implement a doubly-linked list in safe code. This is a fundamental limitation, and again is an issue when the fundamental requirement for the task is to interface to data structures implemented as doubly-linked lists.

No matter how good a language is, if it doesn't have support for floating point types, it's not a good language for implementing math libraries. For most applications, the inability to safely express doubly-linked lists and difficulty in interfacing with C aren't fundamental problems - just don't use doubly-linked lists or interface with C code. (well, you still have to call system libraries, but these are slow-moving APIs that can be wrapped by Rust experts) For this particular example, however, C interop and doubly-linked lists are fundamental parts of the problem to be solved by the code.

kibwen|1 month ago

> If Rust can't handle that safely (not Rust "safe", but safely), it isn't appropriate for the job.

Rust is no less safe at C interop than using C directly.

j-krieger|1 month ago

For 1) The necessary safety guarantees downgrade to the level available in C all the time.

staticassertion|1 month ago

The issue is unrelated to expressing linked lists, it's related to race conditions in the kernel, which is one of the hardest areas to get right.

This could have happened with no linked lists whatsoever. Kernel locks are notoriously difficult, even for Linus and other extremely experienced kernel devs.

Ygg2|1 month ago

> This is a fundamental limitation

Not really. Yeah you need to reach into unsafe to make a doubly linked list that passes borrow checker.

Guess what. You need unsafe implementation to print to console. Doesn't mean printing out is unsafe in Rust.

That's the whole point of safe abstraction.

nec4b|1 month ago

>> I guess that's at least in part because of the difficulty of building safe, fast and highly-concurrent C applications (please correct me if I'm wrong).

You wrote that question in a browser mostly written in C++ language, running on an OS most likely written in C language.

gf000|1 month ago

Just because the pyramids exist, it means they were easy to build?

OS and browser development are seriously hard and took countless expert man hours.