Remix.run Logo
menaerus 2 hours ago

I don't understand this example: you're taking an address of local-scope stack object, storing it into a global list, and then use this address elsewhere in the code, possibly at different time-point, to manipulate with the object? I am obviously missing something because this cannot work unless this object lives on the stack of main().

jcalvinowens 2 hours ago | parent | next [-]

The best example I know of off the top of my head is wait_event() in Linux.

So long as the thread is guaranteed not to exit while blocked, you know its stack, and therefore the object allocated on it, must continue to exist. So, as long as there is no way to wake the thread except by kicking that object, the memory backing it is guaranteed to continue to exist until that object is kicked. You do have to somehow serialize the global data structure lookup (e.g. lock/dequeue/unlock/kick), if multiple threads can find and kick the object concurrently that's unsafe (the thread might exit between the first and subsequent kicks).

Generally that's true, even in pthread userspace: while there are some obvious artificial counterexamples one can construct, real world code very rarely does things like that.

menaerus 2 hours ago | parent [-]

Ok, I see, thanks for the example. Is this technique used to avoid the potential runtime performance cost because one would otherwise need to keep that object elsewhere/heap and not on a stack? Or is the problem definition something else?

jcalvinowens an hour ago | parent [-]

It's just mechanically simpler that way. If the wakee thread dynamically allocated the object, it would have to free it after being woken: may as well let the compiler do that automatically for us.

jandrese 2 hours ago | parent | prev [-]

Yep, it's a straight up error in C to return the address of a local variable from a function outside of main. Valgrind will flag this as use of an uninitialized value.

The problem is that as long as it's something where the calling function checks it immediately after the function exits and never looks again (something like an error code or choosing a code path based on the result) they often get away with it, especially in single threaded code.

I'm running into this at this very moment as I'm trying to make my application run cleanly, but some of the libraries are chock full of this pattern. One big offender is the Unix port of Microsoft's ODBC library, at least the Postgre integration piece.

I also blame the Unix standard library for almost having this pattern but not quite. Functions that return some kind of internal state that the programmer is told not to touch. Later they had to add a bunch of _r variants that were thread safe. The standard library functions don't actually have this flaw due to how they define their variables, but from the outside it looks like they do. It makes beginning programmers think that is how the functions should work and write their code in a similar manner.

jcalvinowens 2 hours ago | parent [-]

> Yep, it's a straight up error in C to return the address of a local variable from a function

Sure, that's true, but nobody is suggesting returning the address of a local variable anywhere in this thread.

I'm describing putting a pointer to a local variable in a global data structure, which is safe so long as the function doing it is somehow guaranteed not to return until the pointer is removed from the global data structure.