Live data from Hacker News

C stdlib isn't threadsafe and even safe Rust didn't save us

edgedb.com

301–310 of 370 posts

Re: C stdlib isn't threadsafe and even safe Rust didn't save us

#301
post #96

Earlier quoted context omitted.

But that won't actually fix the underlying problem, namely that getenv and setenv (or unsetenv, probably) cannot safely be called from different threads. It seems like the only reliable way to fix this is to change these functions so that they exclusively acquire a mutex.

I have a different perspective: the underlying problem is calling setenv(). As far as I'm concerned, the environment is a read-only input parameter set on process creation like argv. It's not a mechanism for exchanging information within a process, as used here with SSL_CERT_FILE. And remember that the exec* family of calls has a version with an envp argument, which is what should be used if a child process is to be…

You can’t convince me that there is EVER a reason to call setenv() after program init as part of a regular program, outside needing to hack around something specific.

Environmental variables are not a replacement for your config. It’s not a place to store your variables.

Even if the env var API is fully concurrent, it is not convention to write code that expects an env var to change. There isn’t even a mechanism for it. You’d have to write something to poll for changes and that should feel wrong.

Re: C stdlib isn't threadsafe and even safe Rust didn't save us

#302

Earlier quoted context omitted.

Errr, not really. "If you detached a thread in your application using a non-Cocoa API, such as the POSIX or Multiprocessing Services APIs, this method could still return NO." Also, I've never heard of this behavior despite years developing for macOS (admittedly tangentially). I don't see how that could work given that threads can come and go during the life of the application.

Yes, really: https://developer.apple.com/library/archive/documentation/Co... . This also outlines what you have to do if you use POSIX threads.

Interesting. Definitely a 3rd approach that threads the needle between what win32 and X Window chose. Thanks for the link.

[ EDIT: not quite sure how to think about this ... if I create NSThreads to act as worker threads that do not make cocoa calls, I still have to deal with new overhead in any cocoa call stacks. That's not ideal, but again, it's a "middle-way" approach, and like every other approach has its own pros and cons. ]

Re: C stdlib isn't threadsafe and even safe Rust didn't save us

#303
post #96

Earlier quoted context omitted.

I have a different perspective: the underlying problem is calling setenv(). As far as I'm concerned, the environment is a read-only input parameter set on process creation like argv. It's not a mechanism for exchanging information within a process, as used here with SSL_CERT_FILE. And remember that the exec* family of calls has a version with an envp argument, which is what should be used if a child process is to be…

You can’t convince me that there is EVER a reason to call setenv() after program init as part of a regular program, outside needing to hack around something specific. Environmental variables are not a replacement for your config. It’s not a place to store your variables. Even if the env var API is fully concurrent, it is not convention to write code that expects an env var to change. There isn’t even a mechanism for…

> You can’t convince me that there is EVER a reason to call setenv() after program init as part of a regular program, outside needing to hack around something specific.

The most common use I see for this is people setting an env in the current process before forking off a separate process; presumably because they don't realize that you can pass a new environment to new processes.

I wonder what bugs you'd find if you injected a library to override setenv() with a crash or error message into various programs. Might be a way to track down these kind of random irreproducable bugs.

Re: C stdlib isn't threadsafe and even safe Rust didn't save us

#304

Earlier quoted context omitted.

Indeed, environment variables should be used to configure child processes, not to configure the current process, for non-shell programs, IMHO. Note that Java, and the JVM, doesn't allow changing environment variables. It was the right choice, even if painful at times.

I think there's a narrow window, at least in some programming languages, when environment variables can be set at the start of a process. But since it's global shared state, it needs to be write (0,1) and read many. No libraries should set them. No frameworks should set them, only application authors and it should be dead obvious to the entire team what the last responsible moment is to write an environment variable.…

> I think there's a narrow window, at least in some programming languages, when environment variables can be set at the start of a process.

I mean, based on this issue I would say the only safe time is "at the start of the program, before any new threads may have been created".

But again, as others have said, there's no good reason I'm aware of to set environment variables in your own process, and when you spawn a new process you can give it its own environment with any changes you want.

Re: C stdlib isn't threadsafe and even safe Rust didn't save us

#305
post #265
post #171

Earlier quoted context omitted.

But it would force Rust programs to add their own synchronization mechanism around them. As long as no two threads can call getenv/setenv at the same time then it’s fine.

The problem isn't something that Rust can solve. The Rust stdlib is already using synchronization on the versions of these functions that are exposed from the Rust stdlib. That's why those functions were allowed to be marked as safe in the first place. The problem is that people are calling C code from Rust (which already requires an unsafe annotation), and then that C code is doing silly thread-unsafe shenanigans fo…

Ah, that’s a detail that I either forgot or did not know. Thank you.

It certainly would be nice if the C library had fewer built–in footguns. And if we could write programs in other languages without ever depending on it (which wouldn’t but much use when you’re relying on a C library anyway, but it still would be nice).

Re: C stdlib isn't threadsafe and even safe Rust didn't save us

#306

Earlier quoted context omitted.

I am going to do this once, but not again. Please pay attention to it. You are not just wrong, but failing to demonstrate an understanding of the actual topic being discussed. I can't say whether you actually have it or not, but your responses do not demonstrate this. I have dealt with plenty of people on this site who say things that are factually incorrect, many of whom have argued with me when I do so. You are not…

Is it possible you're replying to LLM generated posts?

Would it matter?

Re: C stdlib isn't threadsafe and even safe Rust didn't save us

#307
post #5

The major takeaway from this is that Rust will be making environment setters unsafe in the next edition. With luck, this will filter down into crates that trigger these crashes ( https://github.com/alexcrichton/openssl-probe/issues/30 filed upstream in the meantime).

> Nowadays the best solution to this issue is "stop using this crate" with libraries like rustls.

Nice to see that the author of the library has a sensible take. Unfortunately the ecosystem does not: https://github.com/seanmonstar/reqwest/blob/master/Cargo.tom...

Re: C stdlib isn't threadsafe and even safe Rust didn't save us

#308
post #12

Mutable global state is evil. Friends don’t let friends use mutable global state. I hate envvars. It’s “the Linux way”. I avoid them like the plague. A++ strong recommend. libc is terrible. The world needs to move on.

> Mutable global state is evil. Friends don’t let friends use mutable global state. Throw away your CPU and RAM then.

There are certainly levels of the abstraction pyramid where mutable global state is unavoidable; however, it shouldn't be too difficult to get to a point where we have enough abstraction so that we don't need to worry about mutable global state for what we do.

And even if those abstractions can't be 100% effective, we'd go a long way to achieving the desirable results of getting rid of it, if we just develop the mindset of avoiding it if at all possible, excepting for very rare instances where it's needed as a last resort.

Re: C stdlib isn't threadsafe and even safe Rust didn't save us

#309

Mutable global state is evil. Friends don’t let friends use mutable global state. I hate envvars. It’s “the Linux way”. I avoid them like the plague. A++ strong recommend. libc is terrible. The world needs to move on.

Don’t use a mouse or a monitor then.

One of the reasons X is being fazed out in favor of Wayland is because X is far more global than it needs to be -- and this is one of the reasons it has security risk that can't be completely removed without API-breaking effects.

Re: C stdlib isn't threadsafe and even safe Rust didn't save us

#310

Earlier quoted context omitted.

Which programming languages? When using C++ I wanted programs to have a function that was called before main() and set up things that got sealed afterwards, like parsing command-line-arguments, the environment variables, loading runtime libraries, and maybe look at the local directory, but I'm not sure if it'll be a useful and meaningful distinction unless you restructure way too many things. I remember that on the F…

Everyone thinks they are can be the first to do something, and that there is surely nothing that will happen before them. Unfortunately everyone save for one is mistaken. Sometimes that chosen one is not even consistent.

This is one of the problems with Singletons. Especially if they end up interacting or being composed.

In Java you’d have the static initializers run before the main method starts. And in some languages that spreads to the imports which is usually where you get into these chicken and egg problems.

One of the solutions here is make the entry point small, and make 100% of bootstrapping explicit.

Which is to say: move everything into the main method.

I’ve seen that work. On the last project it got a little big, and I went in to straighten out some bits and reduce it. But at the end anyone could read for themselves the initialization sequence, without needing any esoteric knowledge.

Post reply on HN