I just hate to use such heuristics.
It looks like the only "code in the stack"-case (apart from signal handling,
but this is a kernel issue and can be solved if necessary without changing
anything to executables) is trampolines.
Trampolines are rare because it's an implementation technique that's tricky,
a little slow and as far as I know only used by gcc (and useless for most
languages) and then most programs compiled with gcc don't make use of those
trampolines (those coded in C rarely use that gcc-extension, those coded in
ObjC are considered rare depite evidence to the contrary).
Why not decide that gcc is broken as long as it uses trampolines without adding
explicit code to first make the stack executable ?
Stefan