On Sat, Jul 27, 2013 at 08:27:07PM +0200, Ondřej Bílka wrote: > On Sat, Jul 27, 2013 at 12:12:57PM -0400, Rich Felker wrote: > > On Sat, Jul 27, 2013 at 05:44:05PM +0200, Ondřej Bílka wrote: > > > On Thu, Jul 25, 2013 at 12:50:53PM -0400, Rich Felker wrote: > > > > On Thu, Jul 25, 2013 at 08:55:38AM +0200, Ondřej Bílka wrote: > > > > You can't add call-saved registers without breaking the ABI, because > > > > they need to be saved in the jmp_buf, which does not have space for > > > > them. > > > > > > > Well you can. Use versioning, structure will not change and layout for > > > old setjmp/longjmp is unchanged. For new setjmp we set jump address to > > > jmp_buf address to distinguish it from first case. Then for each thread > > > we keep a stack with extra space needed to save additional registers. > > > When setjmp/longjmp is called we prune frames from exited functions. > > > > This required unbounded storage which does not exist. From a practical > > standpoint you would either have to reserve a huge amount of storage > > (e.g. double the allocated thread stack size and use half of it as > > reserved space for jmp_buf) or make the calling program crash when the > > Standard trick mmap and double.
?? > > small, reasonable amount of reserved space is exhausted. The latter is > > highly unacceptable since the main purpose (IMO:) of jmp_buf is to > > work around bad library code that can't handle resource exhaustion by > > replacing its 'xmalloc' type functions with ones that longjmp to a > > thread-local jmp_buf set by the caller (e.g. this is the only way to > > use glib robustly). > > > Well what I wrote is to work around pathologic cases. > With versioning and changing size of structure I could do trick with > distinguishing by pointing to itself and it would mostly work. > > It would break when function that uses setjmp obtains jmp_buf by > parameter from other unit. This is a fairly reasonable usage, e.g. when the jmp_buf is part of some context structure passed around, and different call levels want to replace it to 'handle exceptions'. Personally, I think the right solution is to use a jmp_buf* in the context rather than a jmp_buf, so different call levels can swap around which one it points to (and so the ultimate caller can re-use the same jmp_buf in multiple contexts), but I can't force everybody to do The Right Thing. If code is valid, conforming C (and sometimes even when it's not) then it needs to be supported by the implementation. > To avoid it we need allocate some extra space. Most programs would have > number of jmp_buf instances limited so not deallocating extra would not > cause problem. To violate that limit you need to have variation to these: Well the number of jmp_buf instances you could use in a reasonable sense is limited by the stack size/number of call frames, which is why I thought a "safe" amount of space would be equal to the size of the stack. However as you've said, one could allocate many more... > > By the way, I do have another horrible idea for how you could do it. > > Next idea would be hack gcc to mark all variables volatile in functions > with setjmp. That does not help. setjmp may not be backing up the caller's variables, but rather register values belonging to (the caller of)^N the caller for arbitrarily large values of N. Rich