In eval.c:
2134 else if (XSUBR (fun)->max_args == MANY)
2135 {
2136 /* Pass a vector of evaluated arguments. */
2137 Lisp_Object *vals;
2138 ptrdiff_t argnum = 0;
2139 USE_SAFE_ALLOCA;
2140
2141 SAFE_ALLOCA_LISP (vals, XINT (numargs));
2142
2143 GCPRO3 (args_left, fun, fun);
2144 gcpro3.var = vals;
2145 gcpro3.nvars = 0;
2146
2147 while (!NILP (args_left))
2148 {
2149 vals[argnum++] = eval_sub (Fcar (args_left));
2150 args_left = Fcdr (args_left);
2151 gcpro3.nvars = argnum;
2152 }
2153
2154 set_backtrace_args (specpdl_ptr - 1, vals);
2155 set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs));
2156
2157 val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals);
2158 UNGCPRO;
2159 SAFE_FREE ();
2160 }
At 2141, if numargs is > 2047 (and so allocation size exceeds MAX_ALLOCA on
a 64-bit system), SAFE_ALLOCA_LISP pushes an entry of type SPECPDL_UNWIND to
specpdl stack. At line 2154, set_backtrace_args modifies this entry assuming
SPECPDL_BACKTRACE. Oops.