Remix.run Logo
kazinator 5 days ago

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 are no low-level pointers (or else only as an escape hatch that the program isn't using).

The rest is your bug; the variable values coming out of sync with each other, not maintaining the invariant among their values.

It could be the case that a thread-unsafe program breaks a managed run-time, but not an unvarnished truth.

A managed run-time could be built on the assumption that the program will not create two or more threads such that those threads will invoke concurrent operations on the same objects. E.g. a managed run time that needs a global interpreter lock, but which is missing.

munificent 5 days ago | parent | next [-]

> A memory safe, managed language doesn't become unsafe just because you have a race condition in a program.

The author's point is that Go is not a memory safe language according to that distinction.

There are values that are a single "atomic" write in the language semantics (interface references, slices) that are implemented with multiple non-atomic writes in the compiler/runtime. The result is that you can observe a torn write and break the language's semantics.

ralfj 4 days ago | parent | prev | next [-]

> The rest is your bug; the variable values coming out of sync with each other, not maintaining the invariant among their values.

If the language and its runtime let me break their invariant, then that's their bug, not mine. This is the fundamental promise of type-safe languages: you can't accidentally break the language abstraction.

> It could be the case that a thread-unsafe program breaks a managed run-time, but not an unvarnished truth.

I demonstrated that the Go runtime is such a case, and I think that should be considered a memory safety violation. Not sure which part of that you disagree with...

gpderetta 5 days ago | parent | prev | next [-]

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.

dodobirdlord 5 days ago | parent | prev | next [-]

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.

zozbot234 5 days ago | parent | next [-]

> 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 do that!

gpderetta 5 days ago | parent [-]

> 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.

kazinator 5 days ago | parent | prev [-]

Don't have such things, if you know what's good for you, or else don't have threads.

qcnguy 5 days ago | parent | prev | next [-]

The author knows that. His point is that Go doesn't work that way because it uses greater-than-word-sized values that can suffer torn writes leading to segfaults in some cases.

pharrington 5 days ago | parent | prev [-]

Your fantasy language doesn't have a race condition.