News for hackers. Stuff that matters.
Re:Updating the Go Memory Model by twotwotwo on Monday July 12, 2021 @12:50PM (#27812277)
> Note that this means that races on multiword data structures can lead to inconsistent values not corresponding to a single write. When the values depend on the consistency of internal (pointer, length) or (pointer, type) pairs, as is the case for interface values, maps, slices, and strings in most Go implementations, such races can in turn lead to arbitrary memory corruption.

That second sentence is one of the painful things about the Go memory model--Go is type and memory safe if you avoid explicitly unsafe things, except for data races on those structures.

I wonder what you can practically do to mitigate that at this point; doesn't seem like you go back and change things to be like Java. Can there be some best-effort detection for races in those specific places that's fast enough to run in prod (like I think they did for maps)? I also recall some Go mailing-list post I can't find suggesting that an SSE 128-bit move, while not guaranteed not to tear, seemed to tear only rarely in their tests on the chips of the time; is that true and is there anything there? I imagine fully preventing the problem with atomic reads/writes of these pairs from the heap is a clear no-go performance-wise, and might involve ABI-changing alignment guarantees.

[Edit: SSE2 behavior is discussed here https://stackoverflow.com/questions/7646018/sse-instructions... which is mentioned in a comment at https://research.swtch.com/gorace which seemed to inspire it. Chance of a race seemed to depend on CPU model at the time, bad on the old Core Duo, better on some server chips another answerer tried. Good on my laptop FWIW!]

Probably hard for anything to happen here because any performance regression is hard to swallow, the race detector is close enough for many, and anything you do won't be a 100% solution anyway. Which is a bummer.

Re:Updating the Go Memory Model by pierrebai on Monday July 12, 2021 @01:29PM (#27812784)
I came here to quote and comments on this paragraph. The poke at C/C++ undefined behaviour, claiming Go has no such thing. Except this sentence is exactly undefined behaviour: after the data race, due to possible corruption, anything could happen.

There is also equivalently smugness about the language in general. It is one thing to say there are no undefined behaviour related to the memory model, but given a compiler optimizer, you need to do hard analysis that there cannot be once optimized, with all operations re-ordering that can happen.

The simplicity of the Go memory model, which is vague on purpose, is taken as making it safe. Is it? It mostly mean it is vague, which provide a convenient cover to hide under.

Edit: toward the end, the author talks about adding documentation about compiler optimizations that would be explicitly forbidden. So some of my earlier comments would be addressed.

Re:Updating the Go Memory Model by lamontcg on Monday July 12, 2021 @02:20PM (#27813354)
> There is also equivalently smugness about the language in general.

This really turns me off about Go. And it seems to attract "tech-splainers" that defend the language choices that are made by talking down to people.

Re:Updating the Go Memory Model by throwaway894345 on Monday July 12, 2021 @03:10PM (#27813827)
I don't know. A lot of the criticism of Go is just wild over-exaggeration. Is "tech-splaining" just setting the record straight? For example, the guy upthread is insinuating that Go is roughly on-par with C++ as they both have nonzero amounts of undefined behavior. Having used both languages extensively, I can say for certain that you will run into a lot more UB in C++ than in Go, and it will be a lot harder to debug when it happens. Similarly, the guy downthread who is making a mountain out of Go's nullable pointers (and all of the other people who complain about Go's type system)--yeah, they are strictly worse than Rust's enums, but the overwhelming majority of all software ever written has been built with languages that have nullable pointers and a good chunk of that is with languages that have fully dynamic type systems (not only is the type system going to allow your null pointer access, but it will allow all manner of type errors!). Is it "smugness" to put criticism into perspective?
Re:Updating the Go Memory Model by lamontcg on Monday July 12, 2021 @04:03PM (#27814417)
If you look in the past history of language features that are being added or might be added (e.g. generics) you can find a whole lot of past explanation of why the language doesn't need those features in the name of simplicity and why the reader just doesn't understand the brilliance of Rob Pike.

Reminds me a lot of the Mac forums where every poor feature in an Apple product is explained with a "let me help you understand why you're thinking about it wrong" kind of answer -- up until Apple fixes the bug / implements the feature to the applause of the same people who were talking down why it would ever need to get fixed.

And just the tone of the article here turns me off in the way it begins with a bunch of quotes and philosophy. I actually agree entirely with “Don't communicate by sharing memory. Share memory by communicating" but I figured that out myself in probably 2003 writing crappy perl scripts that utilized parallelism but I wanted to aggressively avoid all the concurrency pitfalls. Actor models and Erlang later made completely intuitive sense to me. The principle is entirely correct, but its fucking weird that a programming language needs to have a list of "proverbs".

Re:Updating the Go Memory Model by throwaway894345 on Monday July 12, 2021 @04:48PM (#27814929)
> If you look in the past history of language features that are being added or might be added (e.g. generics) you can find a whole lot of past explanation of why the language doesn't need those features in the name of simplicity and why the reader just doesn't understand the brilliance of Rob Pike.

Isn't this just nutpicking[0]? You have that with every language. I can criticize C++ on proggit right now and 3 or 4 people will respond "C++ has every language feature, just use the ones you want/like/etc and ignore the others, your problems are invalid!". Similarly, on an OCaml forum I can find a dozen people who tell me if Jane Street hasn't run into my problem before and solved it, then it's not a real problem and I'm dumb for trying to do it. I can post here or on r/rust (or proggit) and people will tell me that Rust is strictly faster/easier to develop with than any GC language because in the worst case you can always throw `Rc<T>` on everything. I can post on r/python about how hard it is to optimize Python and people will tell me I'm dumb and I can just use multiprocessing, rewrite the slow bits in C/Cython/etc, use numpy/pandas/etc. I can merely register for an account on a Java forum and be berated for my low intelligence. :)

> The principle is entirely correct, but its fucking weird that a programming language needs to have a list of "proverbs".

I don't feel as strongly as you do, but I agree that proverbs and analogies are pretty low quality and invite more confusion than they address. Probably only a rung above analogies and a rung below quotations.

[0]: https://rationalwiki.org/wiki/Nutpicking

Re:Updating the Go Memory Model by lamontcg on Monday July 12, 2021 @05:02PM (#27815092)
> Isn't this just nutpicking[0]?

From that article, I'm specifically addressing "Does this movement _promote_ crazies?"

I'd argue the sloganeering attracts them like moths to a flame.

Re:Updating the Go Memory Model by throwaway894345 on Monday July 12, 2021 @05:21PM (#27815298)
I don't know what is meant by "sloganeering" but if writing a full, nuanced article (e.g., TFA) fits the bill then I'm not sure I agree with your conclusion...

In other words, I agree that "sloganeering" attracts the nuts, but I'm not sure I agree that TFA is sloganeering.

Re:Updating the Go Memory Model by lamontcg on Tuesday July 13, 2021 @01:39PM (#27823787)
proverbs == sloganeering

the focus on "simplicity" also is both a good thing, and a great way to shut down any discussion.

Re:Updating the Go Memory Model by throwaway894345 on Tuesday July 13, 2021 @04:31PM (#27825927)
> proverbs == sloganeering

If the TFA amounted to "don't communicate by sharing data; share data by communicating <mic drop>" then yeah, I would be on your side, but the author went to the trouble of writing a 4K word essay to support his points. That you and others reduce it to mere slogans isn't a valid criticism of TFA IMHO.

To your point, there are actual people in and outside of the Go community who do this kind of lazy argumentation. For example, someone upthread said (and I'm hardly paraphrasing), "Hoare called nullable pointers a billion dollar mistake and Go has nullable pointers so... <mic drop>".

> the focus on "simplicity" also is both a good thing, and a great way to shut down any discussion.

Pretty sure you could levy the same criticism against the Java folks for "configurability" or the C++ folks for "performance/control" and the Haskell folks for "type safety". It still sounds like you're nutpicking rather than observing something unique to the Go community.

Re:Updating the Go Memory Model by Zababa on Monday July 12, 2021 @07:34PM (#27816317)
I don't think generics are a good example, as from what I understand their stance was "We haven't find a good way to put them in Go, but we understand that you might want them. We'll try some things and see which fits with Go the best.". That got warped to "you don't need generics anyways" by some overly zealous people. Maybe a better example would be the type system, with Rob Pike saying something about taxonomy being boring?
Re:Updating the Go Memory Model by AmpsterMan on Tuesday July 13, 2021 @01:42AM (#27817917)
I myself like the "proverbs". It's short, simple ways that get me to understand what frame of mind I should be in when writing or reading a particular language.
Re:Updating the Go Memory Model by Anaminus on Monday July 12, 2021 @07:12PM (#27816184)
Sometimes people don't actually want help, they just want to complain. Other people misinterpret this as a question or a debate, so their explanatory responses are received negatively. You'll find that this also applies to C++, Rust, every programming language, and anything in general.
Re:Updating the Go Memory Model by Jabbles on Monday July 12, 2021 @02:22PM (#27813383)
you need to do hard analysis that there cannot be once optimized, with all operations re-ordering that can happen

The previous post demonstrated that this is extremely difficult, beyond the ability of cutting edge research for mainstream languages.

https://research.swtch.com/plmm

Re:Updating the Go Memory Model by Jweb_Guru on Monday July 12, 2021 @02:53PM (#27813678)
I'm a bit tired of reading motivated blog posts like this that bring up enough related work that you know they know solutions exist to the problems they're bringing up, but for some reason felt it was not necessary to bring up those solutions. This line in particular is plain false:

> None of the languages have found a way to formally disallow paradoxes like out-of-thin-air values, but all informally disallow them.

The post neglects to mention the Promising Semantics paper of 2017 that resolves the out of thin air problem to (as far as I know) everyone's satisfaction, despite pointing out the previous work that brought up the problem. Similar things are true for ARM's memory model, etc.--this is all stuff that's been mostly resolved within the last few years as proof techniques have caught up with compilers and the hardware. Ironically, the thing that's been hardest to formalize by far in a useful way (outside of C++ consume) is--surprise, surprise--sequentially consistent fences!

It also handwaves away as some unimportant point the reason why compilers provide things like relaxed accesses--it's not just (or even primarily) about the hardware, but about enabling useful compiler optimizations. Even if all hardware switched to sequentially consistent semantics, don't expect languages that aim for top performance to abandon weak memory. And personally, I think it's ironic that at a time when even Intel is struggling to maintain coherent caches and TSO, and modern GPU APIs don't provide sequential consistency at all, people are trying to act like hardware vendors will realize "the error of their ways" and go back to seqcst.

Re:Updating the Go Memory Model by rsc on Tuesday July 13, 2021 @12:12AM (#27817563)
I had not looked at the Promising Semantics paper of 2017. Thank you for the reference.

That said, what I have learned from watching this space for a decade is that even formal proofs are no match for the complexity of this general problem. You have to get the definitions right, you have to prove the right statements, and so on. There is still plenty of room for error. And even a correct, verified proof is not really an insight as to why things work.

Experts were telling us in 2009 that OOTA had been resolved to everyone's satisfaction, only to discover that it wasn't, really. Maybe Promising Semantics is the final answer, but maybe not. We need to get to the point where everything is obvious and easy to explain, and we're just not even close to that yet.

Looking at citations of Promising Semantics in Google Scholar I found this Pomsets with Preconditions paper from OOPSLA 2020: https://dl.acm.org/doi/abs/10.1145/3428262. It contains this sentence:

"As confirmed by [Chakraborty and Vafeiadis 2018; Kang et al. 2018], the promising semantics [Kang et al. 2017] and related models [Chakraborty and Vafeiadis 2019; Jagadeesan et al. 2010; Manson et al. 2005] all allow OOTA behaviors of OOTA4."

I take that to mean the jury still seems to be out on excluding all OOTA problems. Maybe the canonical example has been taken care of, but not other variants. And again we don't really understand it.

Re:Updating the Go Memory Model by voidnullnil on Tuesday July 13, 2021 @07:09PM (#27827345)
Disregarding memory models, OOPSLA is not a good source for PL research.
Re:Updating the Go Memory Model by shp0ngle on Tuesday July 13, 2021 @01:26AM (#27817846)
This is very different and it seems a lot of people misunderstand this.

Undefined behavior is not "data structure being corrupted". When data structures are corrupted, program still functions as written.

Undefined behavior is "things fly off the ceiling", no logic applies and programs start behaving essentially randomly because of the optimizations.

Undefined behavior is not broken data. That is still a well defined behavior.

Re:Updating the Go Memory Model by labawi on Thursday July 15, 2021 @02:23PM (#27848202)
Behavior of a program after data (as in value) races can be defined and constrained.

If you have wild pointer writes (aka arbitrary memory corruption) and almost any non-trivial control flow, the results are pretty much undefined. As in, it is pretty much impossible to specify or reason about what a program will do.

The article:

> ... such races can in turn lead to arbitrary memory corruption.

Tearing writes themselves are not undefined behavior, but use them wrong and you're off into undefined territory, with no way back.

> Undefined behavior is .. because of the optimizations.

Optimizations are popular, but it doesn't matter why the behavior is undefined.

Re:Updating the Go Memory Model by killingtime74 on Monday July 12, 2021 @08:47PM (#27816682)
Also C/C++ was gradually developed so it can be understood. Go had the benefit of a lot of hind sight and still ended up like this
Re:Updating the Go Memory Model by tomp on Tuesday July 13, 2021 @06:26AM (#27819356)
It's not "undefined behaviour". It's "implementation-defined behaviour".

Undefined behaviour would be, if the compiler thinks that it always happens, it (the compiler) can do anything, including e.g. transforming the whole program into

    int main() {
        return -1;
    }
In Go's case, the compiler performs no such shenanigans - it just compiles your code as-is, and it's your responsibility to make sure it's correct - but exactly because it's not undefined behaviour, the analysis is much simpler than in C/C++ - there's no funny business going on in the compiler, and therefore all effects of the data race are local (in code) (i.e. no "nasal deamons").
Re:Updating the Go Memory Model by throwaway34241 on Monday July 12, 2021 @04:26PM (#27814659)
> I wonder what you can practically do to mitigate that at this point; doesn't seem like you go back and change things to be like Java.

Wouldn't there be an obvious trade off there, requiring an extra heap allocation and indirection every time a slice is used in a data structure? I've always thought of Go as lower-level than Java (since it has explicit pointers, more control over memory layout, etc), which I think makes it a more useful language overall even if not the best fit for every application (since if you do want Java, it already exists and is mature).

In other words, I think both Java's and Go's decisions make sense here.

Re:Updating the Go Memory Model by twotwotwo on Monday July 12, 2021 @07:44PM (#27816376)
FWIW, I meant race semantics similar to Java's--weird things happen but type/memory safety remains. Not the whole Java runtime model with object headers, etc.

It's obviously, uh, quite an Exercise for the Reader(tm) to figure out the best path to avoid memory unsafety given races in line with other Go priorities (as a starting point, imagine a ton of expensive atomics accessing certain pairs on the heap, downgraded to regular loads/stores if the compiler can prove it's safe). But I was trying to say it seems harder to get there now that certain things are set in stone and regressing perf of anything is going to be bad for some user out there.

Re:Updating the Go Memory Model by throwaway34241 on Monday July 12, 2021 @08:43PM (#27816663)
Sure, I was imagining implementing better race semantics the way Java/C# do, by referencing certain multi-word data by pointer to avoid partial update problems. As it is now slices are 192-bit values (on 64 bit systems) embedded directly in objects that can be shared across threads, I don't know how you would efficiently update that atomically.
Re:Updating the Go Memory Model by twotwotwo on Monday July 12, 2021 @09:06PM (#27816777)
Just in theory: pointer/capacity pair is atomic, then you read len non-atomically and check it's less than cap before using it. Slice header today puts len before cap, but, like, if we're dreaming.

You'd probably hit other walls. I'm def. not trying to say it's straightforward!

Re:Updating the Go Memory Model by uluyol on Monday July 12, 2021 @10:06PM (#27817026)
Is Java really memory safe in the face of races? The case I'm thinking about is this:

Shared state:

ArrayList A with intial buffer B and length L

Thread 1:

Grows A and replaces B with buffer C, length with M

Thread 2:

(Earlier loaded B into a register)

Code says write to A[M-1]. JVM checks M-1 against M but uses B as it was already stored in a register. Now you have a buffer overflow.

Except, people on this thread seem to think this is impossible. How does Java prevent this?

Re:Updating the Go Memory Model by lmm on Monday July 12, 2021 @10:30PM (#27817126)
The buffer itself, being a Java array, is checked. You'll get an exception but you won't get undefined behaviour.
Re:Updating the Go Memory Model by uluyol on Tuesday July 13, 2021 @08:04AM (#27819925)
Of course. That makes sense. Thanks!
Re:Updating the Go Memory Model by to11mtm on Monday July 12, 2021 @10:24PM (#27817107)
Yeah this can be a hard problem to solve.

In most managed languages to 'properly' deal with it you typically need to accept locking on some level (like with ConcurrentDictionary in C# or ConcurrentHashMap in Java).

One semi-elegant (yet internally complex) solution I've seen; in C# there is the language-ext library. All the collection types are structs (value types where things like .Add() return a new struct) however the struct itself just holds an implementation to a class. This works well from a user standpoint but the internals of the code is... interesting to say the least and can still lead to a lot of allocations if you're not careful.

Re:Updating the Go Memory Model by ngrilly on Monday July 12, 2021 @01:28PM (#27812768)
> doesn't seem like you go back and change things to be like Java

Java is like Go in that regard. That's why you have to use ConcurrentHashMap instead of HashMap for instance.

Re:Updating the Go Memory Model by twotwotwo on Monday July 12, 2021 @01:40PM (#27812915)
Java's trick is maintaining memory/type safety in the presence of races. You might crash, and your application might not see the values it expects, but you never get a buffer-overflow-like situation where Java's internal structures might get corrupted in arbitrary ways, for example.
Re:Updating the Go Memory Model by ngrilly on Monday July 12, 2021 @02:05PM (#27813214)
I see your point now. Yes, Java won't segfault, unlike Go on slices/maps/interface values. But even without segfaults, undefined behaviors due to race conditions can still be pretty in Java (causing infinite loops, memory leaks, etc.). Maybe it's better to let the program crash with a segfault.

https://stackoverflow.com/questions/51102644/what-the-worst-...

Re:Updating the Go Memory Model by Diggsey on Monday July 12, 2021 @02:38PM (#27813540)
"Undefined behaviour" has a specific technical meaning. In Go, data races can result in UB. In Java, they can't.

Java may be non-deterministic, or exhibit unintended behaviour in response to a race condition. UB is strictly worse because it could do either of those things... or indeed anything else, segfaulting being the least of your concerns.

Re:Updating the Go Memory Model by ngrilly on Monday July 12, 2021 @03:26PM (#27813987)
This is the "technical meaning" of "undefined behaviour" according to Wikipedia:

> Undefined behavior (UB) is the result of executing a program whose behavior is prescribed to be unpredictable, in the language specification to which the computer code adheres.

Can we predict the behavior of a Java program with a data race?

Re:Updating the Go Memory Model by anderskaseorg on Monday July 12, 2021 @04:51PM (#27814960)
A section of Java code with a data race can’t break anything that the same section of code couldn’t have been rewritten to intentionally break without using a data race. For example: it might throw an exception, loop infinitely, or return valid values that the programmer didn’t expect; but it cannot corrupt the internal state of the JVM, violate type-safety, fiddle with private fields, or access data that isn’t reachable from its own variables. Data races cannot be used to violate a security barrier between mutually untrusting sections of Java code.
Re:Updating the Go Memory Model by ngrilly on Tuesday July 13, 2021 @11:35AM (#27822237)
You're right. That's a big advantage of the JVM. It's memory safe even in presence of data races.

That post from Russ Cox (again) explains quite well why Go is not memory safe in presence of data races, and what should be changed to fix this: https://research.swtch.com/gorace

Re:Updating the Go Memory Model by Diggsey on Tuesday July 13, 2021 @11:25AM (#27822113)
That's less a definition, and more a description of what UB looks like.

Here's a better definition: https://en.cppreference.com/w/cpp/language/ub

Re:Updating the Go Memory Model by UncleMeat on Monday July 12, 2021 @05:33PM (#27815397)
This depends on what "unpredictable" means. Do I know precisely what this java program will compute? No. But I do know some things that it won't do. Its behavior is not completely unbounded.
Re:Updating the Go Memory Model by Dylan16807 on Monday July 12, 2021 @10:48PM (#27817213)
That's a really bad standalone definition. It would apply to randomly generating numbers, or most attempts at allocating memory and then sorting by address.
Re:Updating the Go Memory Model by twotwotwo on Tuesday July 13, 2021 @01:30PM (#27823684)
Others said this different ways, but I think the scenarios where you don't get an immediate segfault at the bad read/write are the trickiest ones--hard to debug, at least. One flavor is, say, writing past the end of a slice b/c you read the pointer from one slice and len/capacity from another. If it segfaults, it might be later when the clobbered object is next used.

A few years back someone at Dropbox mentioned tricky prod-only races were a real problem for them sometimes, for instance: https://about.sourcegraph.com/go/go-reliability-and-durabili...

That's where I start dreaming about best-effort detection of races in production binaries or even just reducing the chances of torn reads. Years back there might have been other options, like explicit private vs. shared heaps with more controls on the shared heap, but there seems to be a more restricted set of choices now.

Re:Updating the Go Memory Model by ngrilly on Tuesday July 13, 2021 @03:21PM (#27825074)
I agree that most of the time the segfault will happen later during program execution, which makes debugging very tricky. From that point of view, Java preserving memory safety even in presence of data races is a big win. I guess that's also what makes Rust so appealing for programs needing memory safety with concurrency and no GC.
Re:Updating the Go Memory Model by gpderetta on Monday July 12, 2021 @02:31PM (#27813467)
No it is not better. Java will preserve the integrity of the runtime. Still memory safety issues in go due to races are probably very hard to exploit so it might not make a huge difference in practice.
Re:Updating the Go Memory Model by ngrilly on Monday July 12, 2021 @03:31PM (#27814037)
Yes, the JVM will keep executing the program, but I'm still not convinced this is strictly better than segfaulting if a thread is stuck in an infinite loop using CPU for nothing, and another is leaking memory.
Re:Updating the Go Memory Model by jjnoakes on Monday July 12, 2021 @08:08PM (#27816485)
The problem is, UB is not guaranteed to segfault. A guaranteed segfault when a bug is hit would be great - but randomly getting one of (segfault, silent memory corruption, invalid instructions, ...) is not great, and most people would consider that to be much different than what Java gives you.
Re:Updating the Go Memory Model by gpderetta on Monday July 12, 2021 @03:37PM (#27814112)
It is better than invoking random code because the runtime mistakes some data for a vtable pointer.
Re:Updating the Go Memory Model by ngrilly on Monday July 12, 2021 @03:59PM (#27814374)
I agree that a data race on an interface value in Go, is worse than an infinite loop or a memory leak, because it can lead to calling the wrong method on a value, which is hard to debug.
Re:Updating the Go Memory Model by yc12340 on Monday July 12, 2021 @11:47PM (#27817459)
...and easy to exploit
Re:Updating the Go Memory Model by ngrilly on Tuesday July 13, 2021 @11:42AM (#27822343)
Not easy, but definitely possible:

https://blog.stalkr.net/2015/04/golang-data-races-to-break-m...

> We have to admit that exploiting this requires a fairly specific situation in which there is a data race we could trigger and some structs with function pointers around.

Re:Updating the Go Memory Model by gpderetta on Wednesday July 14, 2021 @05:27AM (#27831176)
Nice.

I would note that Java is designed to run untrusted code, so fat pointers would be unacceptable as the attacker could easily craft the code required to trigger the race. Go does not claim to provide sandboxing of untrusted programs.

Re:Updating the Go Memory Model by ibraheemdev on Monday July 12, 2021 @01:32PM (#27812811)
Java will throw a ConcurrentModificationException. Go can cause undefined behavior.
Re:Updating the Go Memory Model by ngrilly on Monday July 12, 2021 @02:08PM (#27813237)
This is not guaranteed at all:

> Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

Source: https://docs.oracle.com/javase/8/docs/api/java/util/Vector.h...

This is conceptually similar to the race detector in Go, which is also a debugging tool, but without strict guarantees.

Re:Updating the Go Memory Model by papercrane on Monday July 12, 2021 @01:58PM (#27813138)
Java might throw a ConcurrentModificationException. The docs are quite clear that it's not guaranteed and best-effort only.
Re:Updating the Go Memory Model by TheDong on Monday July 12, 2021 @02:53PM (#27813667)
> Go is type and memory safe if you avoid explicitly unsafe things, except for data races on those structures

Note that this isn't actually a real exception. maps are implemented in the go stdlib using "unsafe", in addition to compiler magic for the generics part.

I believe that it holds that if you don't use "unsafe" then your program is memory and type safe, it just happens that the go stdlib and runtime use "unsafe", so you can't safely use them either.

I get that this is a distinction without a difference.

Re:Updating the Go Memory Model by Dylan16807 on Monday July 12, 2021 @10:54PM (#27817237)
> it just happens that the go stdlib and runtime use "unsafe", so you can't safely use them either.

It's still the job of the code author to make it so you can safely use that code, despite internal use of unsafe.

Re:Updating the Go Memory Model by throwaway894345 on Monday July 12, 2021 @03:13PM (#27813866)
Data races aren't limited to maps, so I'm not sure it's even a distinction at all :)
Re:Updating the Go Memory Model by TheDong on Monday July 12, 2021 @11:05PM (#27817287)
I think data-races that can cause undefined behavior are limited to maps and slices and other structures that internally use unsafe.

data-races that can't cause undefined behavior are a different class, closer to what java has, and iiuc that's what you get without unsafe.

I don't think the distinction matters, but I think it exists.

Re:Updating the Go Memory Model by voidnullnil on Tuesday July 13, 2021 @07:15PM (#27827388)
The slice is simply unsynchronized, so a user of the slice may pull out one array but a length that was for a different array.

https://blog.stalkr.net/2015/04/golang-data-races-to-break-m...

Re:Updating the Go Memory Model by throwaway894345 on Tuesday July 13, 2021 @12:42PM (#27823121)
They use `unsafe.Pointer`s under the hood, but I'm pretty sure that implementation detail is unrelated to the race condition (the issue with the race condition is that writes of these types aren't atomic so a concurrent thread that is reading the value could observe it in a partially-updated state (e.g., the pointer field has been updated but not the length field).
Re:Updating the Go Memory Model by gpderetta on Tuesday July 13, 2021 @12:33AM (#27817656)
As far as I understand all interface pointers in go are fat pointers to (vtable, object) and as such can't be updated atomically [1]. Hence any data race on assignment to an interface pointer can lead to UB.

[1] unless there is an additional indirection, I don't really know much about go.