I think we agree: an implementation that uses a stack to make normal calls fast, needs to move/copy the stack to the heap, when the stack runs out (or when a continuation is captured).
I don't know whether Chez still uses the same strategy, but a major part of Dybvig's thesis (very readable) was dedicated to explain the details of a possible implementation strategy.
If you want to have code work everywhere and thus code defensively, yes. Of course you're not coding defensively when coding for Racket, either. But I guess I may have misunderstood you--Racket simply gives you a guarantee; as do some (other) Scheme implementations, so you get the same benefit with some/many other Scheme implementations as well--but even those "differ from Scheme (the standard)", by giving such a guarantee outside of the standard. It's not "Racket vs. Scheme implementations", it's "the (Racket|Scheme) implementations vs. Scheme (the standard)". Apologies then for my inappropriate rant about false claims.
> It is difficult to use the machine stack and have a fast call/cc. But I think Chez Scheme proves it's possible.
Chez doesn't seem to be using the machine stack either. I've tested with this code and "ulimit -s 1000" on Linux and it runs fine:
Note that it can still be using a stack built from "machine" or C style arrays as building blocks--that's what I meant with "Some Scheme implementations allocate stack frames more efficiently than cons cells". Gambit falls into this category as well. But you can't have a single uninterrupted C style array as the stack (with no copying during GC like Chicken does) and implement call/cc efficiently. So I'd still say that implementing Scheme including call/cc efficiently means moving away from the stack controlled by ulimit -s, and once that is done it's easy/natural for an implementation to also offer unbounded stacks like Racket does.