5 ms·
Interesting article, but I feel like the conclusion using `STACK_SIZE` doesn't make any sense. If you are willing to publish that in a public header, you will
by ioquatix 7y ago
Interesting article, but I feel like the conclusion using `STACK_SIZE` doesn't make any sense.
If you are willing to publish that in a public header, you will break any code if your stack struct changes size. Like, I get the point of using `alloca(stack_size())`... but I don't see why `alloca(STACK_SIZE)` is any better than `struct stack my_stack;`.
- saagarjha 7y agoHow so? Wouldn’t you just recompile with the new stack size?
- GlitchMr 7y agoThat's assuming you would recompile the user. Using a constant instead of a function breaks ABI if the size of a struct changes.
- DougBTX 7y agoThe idea with an ABI (an Application Binary Interface rather than an API) is that there is no need to re-compile, existing binaries still work since the binary interface stays the same.
- jcelerier 7y agoIs that still relevant though (or rather, is the cost / benefit ratio of ABI stability still worth it ?). My laptop from last year is able to bootstrap and build a full yocto system from gcc to the kernel to glibc to X11 to Qt5 in ~15 hours.
- gridlockd 7y agoThat's cute, but how long does it take to push that updated system out to your customers?
- jcelerier 7y ago> That's cute, but how long does it take to push that updated system out to your customers I have never seen a proprietary software that does not ship all its shared libraries along anyways - so, about the same time I would say ? eg. look at all the linux games that just come with the entire ubuntu 12.04 or 14.04 userspace.
- OskarS 7y agoOf course it's still relevant. As long as dynamic loading is relevant, stable ABIs are relevant. If someone finds a security bug in OpenSSL (Heartbleed, for instance), you only need a single update to the OpenSSL libs to fix every program that dynamically link it. But that only works if you have a stable ABI: otherwise, every single program would have to be recompiled to fix the bug.
- jcelerier 7y ago> But that only works if you have a stable ABI: otherwise, every single program would have to be recompiled to fix the bug. yes, and what I am saying is that in 2019, the cost of recompiling $everything is quite low.
- ihalip 7y agoThat's a very big cost for the end users, who'd have to download the equivalent of an official ISO release for each minor update to some base component. According to apt, thousands of packages depend on openssl.
- pjmlp 7y agoNot everyone has a top level computer, not everyone is an expert on rebuilding distributions from scratch, not everything is available as source code to build from, not every OS is a GNU/Linux clone.
- jcelerier 7y ago> Not everyone has a top level computer, not everyone is an expert on rebuilding distributions from scratch you aren't but your distro maintainer should be > not everything is available as source code to build from, and most software not available as source code actually do ship their dependencies because it would be madness to suppose that there will never be any ABI or API break at any point in the future > not every OS is a GNU/Linux clone GNU/Linux is actually the exception here - the two big others just ship and replace the whole OS on every major update (and I've heard that this was the case for minor windows update too nowadays, not sure how much this is true)
- OskarS 7y agoIt's true, there's no way of getting around it. There are four requirements here: 1. Stable ABI 2. A library that can change the size of its opaque struct 3. Stack allocation of the opaque struct 4. Statically sized stack frames (i.e. no VLAs or alloca) Pick (any) three of them. You can't have all four.
- kazinator 7y agoThe value passed to alloca, in this case, will be a reasonably small, bounded integer that can reasonably be expected not to be controllable by a remote attacker when the application is running. (Or so it has to be painstakingly ensured.) An alternative would be to use padded structs: when the struct is newly introduced, make it substantially larger than necessary. Then all the clients are reserving the room already. A transparent (or not) union between the real struct type and some array can be used, or padding members. Additional requirements may be that the unused stuff must be initialized to zero by everyone, or else some version field has to be initialized or whatever. Versioned symbols are another solution. Binary clients that are allocating the smaller, older structure are routed to compatibility functions, at least for those functions where it matters. This approach is seen inside glibc for instance. An approach found in numerous places in Microsoft's WIN32 is to store the structure's size, as known at compile time to the given client, into a dedicated size field. The API then knows it is called by older compiled clients when the size they are passing is smaller than the current sizeof (that_struct).