Live data from Hacker News

There is no memory safety without thread safety

ralfj.de

61–70 of 517 posts

Re: There is no memory safety without thread safety

#61

I agree with the author's claim that you need thread safety for memory safety. But I don't agree with: > I will argue that this distinction isn’t all that useful, and that the actual property we want our programs to have is absence of Undefined Behavior. There is plenty of undefined behavior that can't lead to violating memory safety. For example, in many languages, argument evaluation order is undefined. If you have…

The evaluation order is _unspecified_, not undefined behaviour.

Re: There is no memory safety without thread safety

#62
Every time this conversation comes up, I'm reminded of my team at Dropbox, where it was a rite of passage for new engineers to introduce a segfault in our Go server by not synchronizing writes to a data structure.

Swift has (had?) the same issue and I had to write a program to illustrate that Swift is (was?) perfectly happy to segfault under shared access to data structures.

Go has never been memory-safe (in the Rust and Java sense) and it's wild to me that it got branded as such.

Re: There is no memory safety without thread safety

#63

This is false as a generality. A memory safe, managed language doesn't become unsafe just because you have a race condition in a program. Like, say, reading and writing several related shared variables without a mutex. Say that the language ensures that the reads and writes themselves of these word-sized variables are safe without any lock, and that memory operations and reclamation of memory are thread safe: there a…

race condition != data race. Specifically, in go, a race condition can cause application level bugs but won't affect, directly, the runtime consistency; on the other hand a data race on a slice can cause torn writes and segfaults in the best case, and fandango on core in the worst case.

Re: There is no memory safety without thread safety

#64
post #4

This is a canard. What's happening here, as happens so often in other situations, is that a term of art was created to describe something complicated; in this case, "memory safety", to describe the property of programming languages that don't admit to memory corruption vulnerabilities, such as stack and heap overflows, use-after-frees, and type confusions. Later, people uninvolved with the popularization of the term…

> If you want to claim that a language is memory-unsafe, POC || GTFO.

There's a POC right in the post, demonstrating type confusion due to a torn read of a fat pointer. I think it could have just as easily been an out-of-bounds write via a torn read of a slice. I don't see how you can seriously call this memory safe, even by a conservative definition.

Did you mean POC against a real program? Is that your bar?

Re: There is no memory safety without thread safety

#65

Earlier quoted context omitted.

If the variables are word-sized, sure. But what if they are larger? Now a race condition between one thread writing and another thread reading or writing a variable is a memory safety issue.

> Now a race condition between one thread writing and another thread reading or writing a variable is a memory safety issue. No it isn't, because the torn write cannot have arbitrary effects that potentially break the program. It only becomes such if you rely on such a variable to establish an invariant about memory that's broken if a torn write occurs (such as by encoding a ptr+len in it), which is just silly. Don't…

> which is just silly. Don't do that!

tell that to the Go runtime, which relies on slices always being valid and not being able to create invalid ones.

Re: There is no memory safety without thread safety

#66

Earlier quoted context omitted.

That's "unspecified" not "undefined". "Undefined behavior" literally means "anything goes", so any program that invokes it is broken by definition.

That is not true, that is a very specific definition of UB which C developers (among others) favor. That doesn't mean that another language can't say "this is undefined behavior" without all the baggage that accompanies the term in C.

The author is using the term in the way that everyone else understands it. They are not aware of your unusual definition.

Re: There is no memory safety without thread safety

#67

Earlier quoted context omitted.

What precisely are you accusing your interlocutor of not understanding?

Why people with vastly more skill and experience programming and writing programming languages made the decisions they did.

Skill? Go? With the amount of mistakes piling up over the years comparable to PHP at this point? Really??

Re: There is no memory safety without thread safety

#68
post #30

Earlier quoted context omitted.

I think the true answer is that the moment you have to do tricky concurrency in Go, it becomes less desirable. I think that Go is still better at tricky concurrency than C, though there are some downsides too (I think it's a bit easier to sneak in a torn read issue in Go due to the presence of fat pointers and slice headers everywhere.) Go is really good at easy concurrency tasks, like things that have almost no shar…

> And frankly, a lot of software I write is just boring, and Go does fine for a lot of that. I try Rust periodically for things, and romantically it feels like it's the closest language to "the future", but I think the future might still have a place for languages like Go. It's not so much about being "boring" or not; Rust does just fine at writing boring code once you get familiar with the boilerplate patterns (Real…

Rust can yield a higher quality solution, but we can't make a perfect solution, we can only approach perfection. If we want to go further, we could introduce formally-proven code, too. Personally I'm interested in the intersection of proof assistants and Rust, like creusot-rs, and have been investigating it.

But as much as I love LARPing about correctness (believe me I do,) it's just simply the case that we won't right perfect software and it's totally OK. It's totally OK that our software will have artificial limitations, like with Go, only accepting filenames that are valid UTF-8, or taking some unnecessary performance/latency hits, or perhaps even crashing in some weird ass edge case. There are very few domains in which correctness issues can't be tolerated.

I don't deal with domains that are truly mission critical, where people could die if the code is incorrect. At worst, people could lose some money if my code is incorrect. I still would prefer not to cause that to happen, but those people are generally OK with taking that risk if it means getting features faster.

That's why Go has a future really. It's because for most software, some correctness issues are not the end of the world, and so you can rely on not fully sound approaches to finding bugs, like automated testing, race detection, and so on.

Rust can also make some types of software more productive to write, but it is unlikely to beat Go in terms of productivity when it comes to a lot of the stuff SaaS shops deal with. And boy, the software industry sure is swamped in fucking SaaS.

Re: There is no memory safety without thread safety

#69
post #61

I agree with the author's claim that you need thread safety for memory safety. But I don't agree with: > I will argue that this distinction isn’t all that useful, and that the actual property we want our programs to have is absence of Undefined Behavior. There is plenty of undefined behavior that can't lead to violating memory safety. For example, in many languages, argument evaluation order is undefined. If you have…

The evaluation order is _unspecified_, not undefined behaviour.

Interestingly, at least in C++, this was changed in the recent past. It used to be that evaluation of arguments was not sequenced at all and if any evaluation touched the same variable, and at least one was a write, it was UB.

It was changed as part of the C++11 memory model and now, as you said, there is a sequenced-before order, it is just unspecified which one it is.

I don't know much about C, but I believe it was similarly changed in C11.

Re: There is no memory safety without thread safety

#70

Earlier quoted context omitted.

That is not true, that is a very specific definition of UB which C developers (among others) favor. That doesn't mean that another language can't say "this is undefined behavior" without all the baggage that accompanies the term in C.

It's literally how the term "UB" is defined, and understood by experts. Why would anyone want to say "undefined" when they really mean "unspecified"? That's just confusing.

No, it's how one very specific community of experts understands it. It is not some kind of universal law of definition that it must mean that always and everywhere. As far as what is confusing, that is a matter of perspective. I think it is confusing (to put it mildly) that the C community has chosen to use "undefined behavior" to mean "it must never happen, and anything goes if it does". That is extremely counterintuitive, and only makes sense to those who live and breathe that world. So if the standard is to be "avoiding confusion", then we better change the definition used by the C community ASAP.
Post reply on HN