Live data from Hacker News

Ntimed – NTPD replacement

github.com

91–100 of 109 posts

Re: Ntimed – NTPD replacement

#91

Earlier quoted context omitted.

> They can't write good C so no one can! This is an accurate parody of my opinion. I'm unable to say "good C" with a straight face. > I seriously think the C-hater crowd on HN is just disappointed that they can't reason well about pointers. Let's be (hopefully) pessimistic and assume I'm a bottom 10th percentile programmer, and assume (I believe optimistically) that every programmer half an iota better than me is phy…

I take slight issue with talking too cavalierly about ranking programmers [what are we, the HR department at a big company? ;-)], but let's reverse it and say the top 10th percentile of people working in C write very few overflows and pointer bugs (but never zero, since we're all human). Should you therefore mistrust by default the software written by those folks, due to being burned by output from the lower 10th wor…

> I take slight issue with talking too cavalierly about ranking programmers

Reasonable. Programming skill is not a 1 dimensional trait... and it's a bit bloody minded, even if it were. I threw myself in the fire with the hypotheticals because it made me uncomfortable, even as a hypothetical for the sake of argument, to be doing such a reduction.

> Should you therefore mistrust by default the software written by those folks, due to being burned by output from the lower 10th working in the same language?

Sure, absolutely. This manifests as a willingness to review their commits for mistakes, and to support their efforts in trying to reduce the chances of making certain types of mistakes, and an insistence they do the same for me.

And once I've gotten a better handle on their skill, assuming they're good, we'll both invariably regret it when I start to get complacent with my reviews and they check something in with a problem we've now both missed. It wouldn't surprise me if the best programmers I've worked with sneak more bugs past me than the worst as a direct result of this...

> And all this despite the fact that we have some mitigations these days, such as address randomization, fewer pages being executable, privilege separation, safer coding styles and practices being pretty well known in some circles, etc.?

Yes, absolutely. Why even indulge in any of these mitigations if you trust yourself and your fellow programmers with unsafe pointers? Each of these is vitally important specifically because we can't. And unfortunately, these mitigations are imperfect solutions. A horrifying amount of software disables them outright - and even when enabled, exploits still show up in the wild - they just get more convoluted and end up with lower success rates.

Better language choice is yet another potential mitigation. For me that usually means C#. This too is imperfect: I'm still more than able to write an unchecked buffer overflow with an unsafe block, or a marshaling API call, etc. ad infinitum - but it's an improvement.

> And where would that lower 90th be if it weren't for the fact that these days people are primarily being taught in memory safe languages?

Spending more time learning about and fighting memory bugs instead of shipping features, a sad waste of productivity. (I don't think that's the answer you were hinting at, but I'm not sure what is. An aside: My field still worships and is primarily taught memory unsafe languages.)

Re: Ntimed – NTPD replacement

#92

Earlier quoted context omitted.

I take slight issue with talking too cavalierly about ranking programmers [what are we, the HR department at a big company? ;-)], but let's reverse it and say the top 10th percentile of people working in C write very few overflows and pointer bugs (but never zero, since we're all human). Should you therefore mistrust by default the software written by those folks, due to being burned by output from the lower 10th wor…

> I take slight issue with talking too cavalierly about ranking programmers Reasonable. Programming skill is not a 1 dimensional trait... and it's a bit bloody minded, even if it were. I threw myself in the fire with the hypotheticals because it made me uncomfortable, even as a hypothetical for the sake of argument, to be doing such a reduction. > Should you therefore mistrust by default the software written by those…

I look forward to your review of my code.

Re: Ntimed – NTPD replacement

#93
post #92

Earlier quoted context omitted.

> I take slight issue with talking too cavalierly about ranking programmers Reasonable. Programming skill is not a 1 dimensional trait... and it's a bit bloody minded, even if it were. I threw myself in the fire with the hypotheticals because it made me uncomfortable, even as a hypothetical for the sake of argument, to be doing such a reduction. > Should you therefore mistrust by default the software written by those…

I look forward to your review of my code.

Got a review link or pull request for me? ;)

Re: Ntimed – NTPD replacement

#94
post #90

Earlier quoted context omitted.

Rust seems interesting, though when I read about it I often think "sounds good, but why not just use C or C++?" These are, after all, already working well for a lot of people, and working just about everywhere. And you don't have issues that come with an experimental language: like on day x GC is a good idea, and on day x + 1 reference counted pointers are the way to go. The benefits range from overstated [bounds che…

Memory safety is a huge problem: every large C++ has vulnerabilities caused by memory safety problems. E.g. web-browsers get pwned because of memory unsafety. Apparently, all (or close to all) critical security bugs in Firefox were problems that Rust compilers will catch. I believe pcwalton went through Mozilla's bugzilla to check this. In any case, bounds checking is a tiny side street in how Rust ensures memory saf…

> ownership and lifetimes are the important novel things

The first is very clearly a borrowed C++ feature (from RAII and smart pointers). I'm unfamiliar with the 2nd but it sounds like just making the compiler yell at you more when you break scope rules (like C++ will happily let you do with dangling pointers - I will give you that dangling pointers are bad).

> Rust doesn't solve race conditions: it solves data races, which are also problematic (they cause memory unsafety). It is impossible/very hard to avoid arbitrary race conditions, but data races are the only ones that can cause memory unsafety directly.

This sounds like gibberish to me. When I said "race conditions" please read it as "data races". Many of which will not "cause memory unsafety directly". Many of which low-level code such as a kernel will need to not be abstracted from. (Imagine writing a page fault handler in a language that tries to hide data races from you... Doesn't sound like a great idea.)

Re: Ntimed – NTPD replacement

#95
post #90

Earlier quoted context omitted.

Memory safety is a huge problem: every large C++ has vulnerabilities caused by memory safety problems. E.g. web-browsers get pwned because of memory unsafety. Apparently, all (or close to all) critical security bugs in Firefox were problems that Rust compilers will catch. I believe pcwalton went through Mozilla's bugzilla to check this. In any case, bounds checking is a tiny side street in how Rust ensures memory saf…

> ownership and lifetimes are the important novel things The first is very clearly a borrowed C++ feature (from RAII and smart pointers). I'm unfamiliar with the 2nd but it sounds like just making the compiler yell at you more when you break scope rules (like C++ will happily let you do with dangling pointers - I will give you that dangling pointers are bad). > Rust doesn't solve race conditions: it solves data races…

Rust doesn't hide data races. It prevents them.

Even the Linux kernel has very, very few intentional data races. Most of them rely on undefined behavior and Linus has complained before about kernel code breaking when GCC actually tries to exploit that behavior. In those rare cases, it is perfectly reasonable to use unsafe code, along with copious comments explaining why it's safe.

You may want to read this article: https://software.intel.com/en-us/blogs/2013/01/06/benign-dat...

Re: Ntimed – NTPD replacement

#96

Earlier quoted context omitted.

> ownership and lifetimes are the important novel things The first is very clearly a borrowed C++ feature (from RAII and smart pointers). I'm unfamiliar with the 2nd but it sounds like just making the compiler yell at you more when you break scope rules (like C++ will happily let you do with dangling pointers - I will give you that dangling pointers are bad). > Rust doesn't solve race conditions: it solves data races…

Rust doesn't hide data races. It prevents them. Even the Linux kernel has very, very few intentional data races. Most of them rely on undefined behavior and Linus has complained before about kernel code breaking when GCC actually tries to exploit that behavior. In those rare cases, it is perfectly reasonable to use unsafe code, along with copious comments explaining why it's safe. You may want to read this article: h…

I think you misunderstand me. Data races happen a lot in kernel development, yes Linux too, and you need to handle them and keep behavior sane. Take my example of a page fault handler. You need a strategy to account for the cases where another proc faults on the same page being processed. Or if a page is being unmapped and accessed simultaneously, you may let the access through or you may deliver a signal depending on timing. Handling these is a real task and if you are in lala land pretending data races don't happen, good luck.

This, in my opinion, suggests that what I read about Rust makes it sound unsuitable for certain domains where concurrent writes and data races are an inherent fact of the universe, a reality that the language seems to deny and be working against.

(Didn't even mention lock free algorithms, for example I was reading one day about [I think it was] the dentry cache using lock free algorithms... You can bet there is part of that code that yes, expects data races to happen and handles them.)

Re: Ntimed – NTPD replacement

#97

Earlier quoted context omitted.

Rust doesn't hide data races. It prevents them. Even the Linux kernel has very, very few intentional data races. Most of them rely on undefined behavior and Linus has complained before about kernel code breaking when GCC actually tries to exploit that behavior. In those rare cases, it is perfectly reasonable to use unsafe code, along with copious comments explaining why it's safe. You may want to read this article: h…

I think you misunderstand me. Data races happen a lot in kernel development, yes Linux too, and you need to handle them and keep behavior sane. Take my example of a page fault handler. You need a strategy to account for the cases where another proc faults on the same page being processed. Or if a page is being unmapped and accessed simultaneously, you may let the access through or you may deliver a signal depending o…

Those aren't data races. Page faults are actually synchronized (they block) and the switch to kernel mode is a synchronization point. They are examples of races, but they're not examples of data races.

Just to be completely clear, since we didn't define what we were talking about: a data race exists when there are two or more unsynchronized accesses to the same memory location, at least one of which is a write. What happens when that occurs is undefined behavior in C, whether or not you are writing a kernel. On some hardware the result is totally unusable (the write is corrupted). Additionally, the compiler and (on some architectures) the processor are free to reorder operations such that other threads will see your writes in the wrong order, or not at all.

This is all hardware level, the kernel has to deal with these problems too. The "relaxed" ordering in the C++11 memory model is essentially the lowest guarantee you can do anything useful with (other than have something like a racy counter, where you literally don't care at all what the value is, which is basically the only place the kernel has intentional data races at all). For some architectures and operations it resolves to a noop (relaxed stores and loads on x86, for example, never require additional synchronization beyond what the compiler provides).

The Linux kernel takes advantage of these semantics for lock-free or mostly-lock-free algorithms like RCU. There's a lot of code in those implementations specifically to ensure the correct barriers and orderings are in place so that there can't be data races. There's no reason they couldn't be implemented in Rust, and it would probably be easier since they could rely on LLVM's implementation of fences and so on rather than reimplementing it for each architecture. And if LLVM didn't have what they needed, they could just implement it in inline assembly (which is what kernel developers already do anyway).

Re: Ntimed – NTPD replacement

#98

Earlier quoted context omitted.

I think you misunderstand me. Data races happen a lot in kernel development, yes Linux too, and you need to handle them and keep behavior sane. Take my example of a page fault handler. You need a strategy to account for the cases where another proc faults on the same page being processed. Or if a page is being unmapped and accessed simultaneously, you may let the access through or you may deliver a signal depending o…

Those aren't data races. Page faults are actually synchronized (they block) and the switch to kernel mode is a synchronization point. They are examples of races, but they're not examples of data races. Just to be completely clear, since we didn't define what we were talking about: a data race exists when there are two or more unsynchronized accesses to the same memory location, at least one of which is a write. What…

My parenthetical remark which started this tangent is that I see people suggesting rust because "it solves race conditions" and when I looked into that claim it looked basically like the compiler enforcing no data sharing. The scheme is unworkable for lots of domains.

If you define data races to not include race conditions that your code is handling (by placement of atomics, fences, locking etc.) then maybe your points make some sense but it is exactly the code handling these that I am saying does not fit with what I have seen rust advocates claim. You have to reason about these things at some level, and what I hear people advocate on hn is to sidestep it all by preventing sharing, which may be a fine idea but doesn't work for everything.

Lastly, in my mind, if your lock free algorithm works by letting the races happen but using the result of an atomic op and/or fences to ensure consistent behavior, I would still call that a (benign) race. That you needed atomics, fences, or compiler hints to get what you want seems orthogonal.

Re: Ntimed – NTPD replacement

#99

Earlier quoted context omitted.

Those aren't data races. Page faults are actually synchronized (they block) and the switch to kernel mode is a synchronization point. They are examples of races, but they're not examples of data races. Just to be completely clear, since we didn't define what we were talking about: a data race exists when there are two or more unsynchronized accesses to the same memory location, at least one of which is a write. What…

My parenthetical remark which started this tangent is that I see people suggesting rust because "it solves race conditions" and when I looked into that claim it looked basically like the compiler enforcing no data sharing. The scheme is unworkable for lots of domains. If you define data races to not include race conditions that your code is handling (by placement of atomics, fences, locking etc.) then maybe your poin…

Rust definitely allows data sharing. It just doesn't allow data races.

> If you define data races to not include race conditions that your code is handling (by placement of atomics, fences, locking etc.) then maybe your points make some sense but it is exactly the code handling these that I am saying does not fit with what I have seen rust advocates claim.

Its actual guarantees for atomics are not very strong and let you handle all of those things in safe code. What's interesting is that it can guarantee correct behavior for types that have more interesting semantics than "a bytestring," like mutexes or smart pointers. The implementations of those things are still unsafe, but you can generally provide a safe API to them, which you can't do in most other languages. This is because Rust has the notion of thread safety built into the language and enforced by the type system. For example, Rust's `shared_ptr` equivalent, `Arc` is defined to be thread safe to share and send to other threads if and only if `T` is also thread safe to share and send to other threads. That doesn't mean you can't build up a safe type from the lower level atomics, or Rust isn't suited for this domain. It means you can write safe APIs in Rust that you can't in C++.

> You have to reason about these things at some level, and what I hear people advocate on hn is to sidestep it all by preventing sharing, which may be a fine idea but doesn't work for everything.

Rust just forces you to do just enough synchronization to not have undefined behavior. It's not a dogmatic language and doesn't believe there is one right way to do concurrency. Channels were just removed from the prelude for precisely that reason--they're not particularly favored over other concurrency mechanisms.

> Lastly, in my mind, if your lock free algorithm works by letting the races happen but using the result of an atomic op and/or fences to ensure consistent behavior, I would still call that a (benign) race. That you needed atomics, fences, or compiler hints to get what you want seems orthogonal.

Data races are well-defined, and what you're describing aren't data races, benign or otherwise. You basically never want data races, just like you basically never to dereference a dangling pointer. Rust prevents things you basically never want, it doesn't prevent writing useful things like lock-free data structures.

Re: Ntimed – NTPD replacement

#100

Earlier quoted context omitted.

My parenthetical remark which started this tangent is that I see people suggesting rust because "it solves race conditions" and when I looked into that claim it looked basically like the compiler enforcing no data sharing. The scheme is unworkable for lots of domains. If you define data races to not include race conditions that your code is handling (by placement of atomics, fences, locking etc.) then maybe your poin…

Rust definitely allows data sharing. It just doesn't allow data races. > If you define data races to not include race conditions that your code is handling (by placement of atomics, fences, locking etc.) then maybe your points make some sense but it is exactly the code handling these that I am saying does not fit with what I have seen rust advocates claim. Its actual guarantees for atomics are not very strong and let…

> Data races are well-defined, and what you're describing aren't data races, benign or otherwise. You basically never want data races, just like you basically never to dereference a dangling pointer

Lock free algorithms, or even a lock implementation, does not jive with this. You let the race happen, and you safely detect when you lost or won the race, and then you do stuff accordingly. To use your pointer analogy, it's OK to have a stale pointer in RAM or in a register at a moment in time. It's a violation of the invariants to dereference it.

As for the rest, perhaps I have been misinformed or led to some outdated info on rust when I saw things about no sharing. I will be sure to take a look.

Post reply on HN