Live data from Hacker News

Translating All C to Rust (TRACTOR)

darpa.mil

331–340 of 403 posts

Re: Translating All C to Rust (TRACTOR)

#331

Earlier quoted context omitted.

It'd require using unsafe code somewhere in the stack. Not necessarily by the mentee. It's possible that the AVX code wasn't properly hidden behind a safe abstraction in a library.

That still means the unsafe code is at fault.

OK, so here's my heartfelt plea: remove the 'unsafe' keyword from Rust?

Sure, not being able to do basic things like IO might be a bit of a limitation at first, but, that's all worth it, I guess?

Again: I'm pointing out to you that your absolutist stance on 'unsafe' and 'UB' is doing more harm than good.

You continue to choose to ignore this, which is your right. But as a "community leader" you could and should to better. As could I, I guess, by simply ignoring you, but, the mental health issues I see you cause in real-life make that sort-of hard...

Re: Translating All C to Rust (TRACTOR)

#332

Earlier quoted context omitted.

You can do tons of stuff with purely safe Rust. The main things that you can't do are FFI, making self-referential structures, and dereferencing raw pointers. And unsafe isn't a problem. It's a point of potential danger to be heavily audited, tested, and understood. Having the entire language unsafe by default is an obviously worse situation. This is throwing the baby out with the bathwater, like rallying against sea…

> I don't understand why people criticizing Rust tend so heavily to let perfect be the enemy of good. if you've convinced yourself that you're special and all problems with c are solved by trying harder, clearly everyone else is just lazy. with that line of logic, there's nothing to fix with c. rust is not just redundant, but also aggravating, since its popularity causes the cognitive dissonance to start creeping in.…

> all problems with c are solved by trying harder, clearly everyone else is just lazy.

If you're even remotely familiar with professional C development then you should know this is unironically true. Tooling does exist to offer memory-safe features in C, they're just far more complicated than using a safe language from the offset. Nobody wants to use Valgrind when your linter can do the same job without leaving your editor.

Most of today's high-performance C code is compiled using the same IR that LLVM generates when compiling C. Unless you're a GCC pundit it doesn't make sense to reject the direction the industry is headed in.

> maybe i can make mistakes? should we improve tooling somewhat?

After a while, being allowed to make mistakes starts to pile up: https://www.zdnet.com/article/microsoft-70-percent-of-all-se...

Re: Translating All C to Rust (TRACTOR)

#333
post #324
post #306

Earlier quoted context omitted.

Memory corruption is undefined behavior and means the compiler is free to do anything it wants. Anything it wants... and that includes doing something entirely safe and reasonable. If you write out of bounds, the compiler is allowed to shut the program down in a controlled manner. It's allowed to transparently resize the array for you. Etc. Hence a rust translation can do these things.

You "anything it wants" folks really annoy me a little. If the compiler can, compile-time, detect that code is prone to memory corruption, it can warn the developer. If it can't detect it at compile time, will and shall it add some sort of magic signal handler heuristic to determine whether a segfault occurred due to a runtime-provable specific instance of memory corruption and hence format your harddrive, while for…

I think you misunderstand my point.

Consider the following program:

    #include 
    int main(void) {
        int a[10];
        a[20] = 100;
        printf("%d\n", a[20]);
    }
because accessing a[20] is undefined behavior, it is legal to translate the program to the following rust code (which crashes with out of bounds error message during runtime).

    #![allow(unconditional_panic)]
    fn main() {
        let mut a: [i32; 10] = [0; 10];
        a[20] = 100;
        println!("{}", a[20]);
    }
It gives a different result than gcc. But one that is both valid one and useful. And that's why machine-translating to rust could have benefits in practice. Contrary to simon_void's assertion, you can translate a corruptible program to a non-corruptible one.

(In this particular case the error is simple enough that the compiler catches it and we have to tell it to go ahead anyway, but in more complicated cases it wont be. So please don't get hung up on this point)

Re: Translating All C to Rust (TRACTOR)

#334

Earlier quoted context omitted.

> I don't see any evidence that that's the attitude being taken by TRACTOR — I sure hope it isn't. I don’t see any way it can do otherwise. As a simple example, what would one translate this C statement to: int i; … i = abs(i); ? I would expect TRACTOR to generate (assuming 64-bit integers): let i: i64; … i = abs(i); However, that can panic in debug mode and return a negative number in release mode ( https://doc.rust…

It's possible to preserve the semantics of the original program using unsafe Rust. [1] unsafe { let mut i: std::os::raw::c_int = std::mem::MaybeUninit::uninit().assume_init(); // ... i = libc::abs(i); } That's grotesque, but it is idiomatic Rust insofar as it lays bare many of the assumptions in the C code and gives the programmer the opportunity to fix them. It is what I would personally want TRACTOR to generate if…

The first line is already UB. `assume_init` requires the contents to be initialized, hence the name.

Re: Translating All C to Rust (TRACTOR)

#335

Earlier quoted context omitted.

It's possible to preserve the semantics of the original program using unsafe Rust. [1] unsafe { let mut i: std::os::raw::c_int = std::mem::MaybeUninit::uninit().assume_init(); // ... i = libc::abs(i); } That's grotesque, but it is idiomatic Rust insofar as it lays bare many of the assumptions in the C code and gives the programmer the opportunity to fix them. It is what I would personally want TRACTOR to generate if…

The first line is already UB. `assume_init` requires the contents to be initialized, hence the name.

Mmm, I went back and read the docs for MaybeUnit more carefully and that's a good point.

It may be better to just leave the assignment off the declaration. If the variable is read before it's initialized to something, we'll get a Rust compilation error, forcing programmer intervention. Detecting actual bugs that would result in memory errors and forcing them to be resolved is very much in the spirit of Rust. TRACTOR may aspire to gift C programs with memory safety for free, but it won't always be possible.

Of course if TRACTOR can determine through static analysis that the unitialized read can't cause problems, it might emit different code.

Re: Translating All C to Rust (TRACTOR)

#336

Earlier quoted context omitted.

> No chance. CBMC is amazing, but have you actually tried formally verifying a "real" program? Yes. Every day. It's actually quite easy to do. Write shadow methods covering the resources and function contracts of called functions, then verify the function. Repeat all of the way up and down the stack. It adds about 30% overhead over just TDD development.

Last time I tried CBMC, it ended up running out of memory for relatively small programs, do you encounter any resource usage issues with it? I'm learning Frama-C and I find it more predictable, although the non-determinism of solvers shocked me when I first tried to prove non-trivial programs. I guess ideally I would like something even more explicit than Frama-C.

What do you mean by "non determinism of solvers"? AFAIK, unless your proof finishes really close to the timeout, it is pretty uncommon that a failed PO suddenly succeeds and vice-versa if the code/the annotation are not modified.

Re: Translating All C to Rust (TRACTOR)

#337

That sounds ... hard. Especially as idiomatic Rust as written by skilled programmers looks nothing like C, and most interesting code is written in C++ anyway. Isn't it equivalent to statically determining the lifetimes of all allocations in the C program, including those that are implemented using custom allocators or which cross into proprietary libraries? There's been a lot of research into this sort of thing over…

Man, I want to upvote this but… > most interesting code is written in C++ anyway. Really?! The Linux kernel is a _pretty enormous_ counterexample, as are many of the userland tools of most desktop Linux distros. I am also a key developer of an entirely-written-in-C tool which I'd venture that [a large fraction of desktop Linux users in corporate environments use on a regular basis]( https://gitlab.com/openconnect/ope…

The refusal to use C++ in Linux isn't entirely rational. Nobody else makes that decision. Other kernels are a mix of C and C++ (macOS/iOS, Windows, even hobby operating systems like SerenityOS).

Then you get into stuff that's not kernels and the user-spaces are again mostly all C++. The few exceptions that exist are coming out of the 90s UNIX culture, stuff like Apache or nginx. Beyond that it's all C++ or managed languages.

Re: Translating All C to Rust (TRACTOR)

#338

Earlier quoted context omitted.

> desire to fix existing systems with no additional engineering I, too, enjoy sci-fi. > Just because something is not being used universally doesn't mean that it has failed. You are only correct in the dictionary sense of these words. Fact is that a lot of the programmers are vain creatures prone to ego, and they make their chosen technical stack part of their core identity. This prevents them from being flexible, th…

> I, too, enjoy sci-fi I was characterizing these hardware changes as being fantasy, so I'm glad you agree. > So I'd say if the said CBMC, and likely other tools in the same area, has more or less failed if it could not convince a critical mass of C/C++ devs to use it So, in the same vein, Rust has failed because it has only been around for a similar amount of time and people still use C/C++? > The victims of Heartbl…

> So, in the same vein, Rust has failed because it has only been around for a similar amount of time and people still use C/C++?

Yes, it kind of failed there indeed. And I even hinted at why: Rust is far from perfect and its async implementation is a cobbled together mess. Golang's model reads much better, though I hate their foot-guns quite a lot (like writing to a closed channel leads to a panic; who thought that was a good idea?).

> I fail to see how a CVE that occurred due to poor engineering practices has anything to do with the adoption of good engineering practices and tooling. Yes, Heartbleed is why we need this tooling.

You can't see it? But... the good practices do lead to less of these CVEs as you yourself seem to realize? I don't get this part of your comment.

> You are simultaneously arguing that if we could just adopt Rust, our problems would be solved, but since another technology has not yet been adopted, it has failed.

You have answered it yourself: a lot of people see manual wrangling of `void**` as a badge of honor and their ego takes over (and the fear of being displaced, of course). I claim that Rust is not being more widely adopted due to programmer ego and fear of being obsolete. The fear of the end of nice salaries because they belong to a diminishing cohort of old-school cowboys.

Who would not fear that? Who would want that to end?

> Do you not see the logical inconsistency in your position?

No, and I don't get your argument. The reasons for C/C++ devs not improving the memory safety of their code, and the reasons for them not adopting Rust are very different. Not only is the analogy bad, it is plain inapplicable.

---

But it also does not help that HN reacts like a virgin schoolgirl pinched on the arse when Rust is mentioned. I've coded it for a few years, I loved it, I hated the bad parts and called them out, but even to this day I very quickly and easily get branded as a Rust fanboy even if my comment history shows balanced criticisms towards it. People don't care. People are emotional and are quick to put you in a camp that's easy to hate.

That is the part that I truly hate. No objective debate.

Too expensive to move to Rust? GOOD! That's an amazing argument, we can talk that for weeks and get very interesting insights in both directions.

People unwilling to get re-trained? Also a good argument, with big potential for interesting insights!

But most of everything else is at the level of a heated table debate after the 11th beer. Pretty meh and very uninteresting. No idea why I keep engaging, I think I am just bitter that people who REALLY should know better are reacting on emotion and not on merit. But that's on me. We all have our intolerances to the reality we inhabit. This is one of mine.

Re: Translating All C to Rust (TRACTOR)

#339

Earlier quoted context omitted.

That still means the unsafe code is at fault.

OK, so here's my heartfelt plea: remove the 'unsafe' keyword from Rust? Sure, not being able to do basic things like IO might be a bit of a limitation at first, but, that's all worth it, I guess? Again: I'm pointing out to you that your absolutist stance on 'unsafe' and 'UB' is doing more harm than good. You continue to choose to ignore this, which is your right. But as a "community leader" you could and should to be…

I don't know if he's choosing to ignore it, or if it's simply hard to figure out exactly what you're saying. Your comments are unfocused in a way that makes it hard to engage with any specific point.

The points are:

* Unsafe Rust is required to uphold specific guarantees to not cause undefined behavior. This can be tricky, but it's not impossible, it just involves a lot of care and some tooling like Miri for those specific situations. The situation is the same as pretty much the entirety of the C and C++ languages, plus Rust reference safety.

* Safe Rust is designed to not cause any UB on its own. It can only "bleed" UB from incorrect unsafe code. Without any incorrect unsafe code, this is easy to work with and involves much less work and care.

* Therefore, keeping your unsafe blocks small and in dedicated crates where they can be individually tested increases the quality and reliability of the codebase.

Surely you can see that it's an improvement over the previous status quo. I don't know what absolutist stance you're talking about. Most Rust fans I know, including myself, accept that Rust is an imperfect language, representing an improvement over C and C++. It's not just hypothetical either. Rust has brought demonstrated improvement in reliability for us, and for some of the biggest companies in the world who now lean on it to reduce their rate of defects.

Re: Translating All C to Rust (TRACTOR)

#340

Earlier quoted context omitted.

That still means the unsafe code is at fault.

Yes, but if a developer can't trust the abstractions then isolating unsafe code behind them is of no value.

Given the story at hand, it sounds like the center incorrectly assumed the compiler would prevent UB even in unsafe blocks. They wouldn't be saying "But the compiler said it was okay" if it wasn't unsafe code they had written.

I think the story is just somebody who didn't actually learn unsafe Rust properly (and I'm struggling to give it the benefit of the doubt, as it sounds quite exaggerated; I couldn't imagine a novice Rust dev literally crying because they thought unsafe blocks couldn't cause UB. If you were that emotionally attached to the language, I'd expect you to have learned what unsafe means).

Post reply on HN