On Thursday, July 27, 2023 9:57:51 AM MDT IchorDev via Digitalmars-d-learn wrote: > I've been getting a lot of segfaults from using associative > arrays recently. The faults happen seemingly at random, and from > pretty mundane stuff like `if(auto x = y in z)` that run very > often: > ``` > Segmentation fault. > #0 0x0000555555670f4a in rt.aaA.Impl.findSlotLookup(ulong, scope > const(void*), scope const(TypeInfo)) inout () > #1 0x0000555555661662 in _aaInX () > ``` > > I suspect that this is because they've all been placed inside > `__ghared` structs. Are DRuntime's AAs simply incompatible with > `__gshared`? Do they need to be marked as `shared` to prevent > these shenanigans?
Strictly speaking, __gshared is really only intended for stuff like C globals (which can't be shared due to name-mangling issues). Using it on anything else can at least potentially cause problems due to the fact that the compiler will assume that the variable is thread-local. So, I would strongly advise against using __gshared in a case like this. In practice, you can often get away with it, because the compiler doesn't do much in the way of optimizing stuff based on objects being thread-local right now, but it's definitely risking problems with the type system if you used __gshared when you're not trying to do something like bind to a C global. What should normally be happening is that you use shared, and then when you've protected the object so that you know that it can only be accessed on the current thread by the section of code that you're in (e.g. by locking a mutex), you temporarily cast away shared to operate on the object via a thread-local reference. Then, before exiting that section of code and removing the protections that are preventing other threads from accessing the object (e.g. by unlocking the mutex), you make sure that you've gotten rid of all of the thread-local references to the object so that only the shared reference exists. That way, you don't accidentally mutate the object while it's not protected from access by other threads. Now, as to what's happening in your code that's causing segfaults, the most likely culprit would be that you're accessing the AA without actually having done anything to prevent other threads from accessing it at the same time (or your protections were inadequate). And because the object is being treated as thread-local by the compiler, it would be easy to have accidentally let a reference to it leak somewhere that wasn't being protected by whatever mutex you're using, whereas if the AA were shared, the only sections of code where you would have to worry about thread-local references escaping would be in the sections of code where you've cast away shared after locking the relevant mutex. So, similar to what happens with @safe and @trusted, using shared allows you to limit the code that you have to examine to find the problem. - Jonathan M Davis