Add support for detecting register-stack overrun on IA64.

Per recent investigation, the register stack can grow faster than the
regular stack depending on compiler and choice of options.  To avoid
crashes we must check both stacks in check_stack_depth().

Back-patch to all supported versions.
This commit is contained in:
Tom Lane 2010-11-06 22:59:31 -04:00
parent 9f22a3f091
commit 17b38fae86
1 changed files with 59 additions and 0 deletions

View File

@ -97,6 +97,12 @@ static int max_stack_depth_bytes = 2048 * 1024;
/* Do not make static so PL/Java can modifiy it */
char *stack_base_ptr = NULL;
/*
* On IA64 we also have to remember the register stack base.
*/
#if defined(__ia64__) || defined(__ia64)
char *register_stack_base_ptr = NULL;
#endif
/*
* Flag to mark SIGHUP. Whenever the main loop comes around it
@ -2288,6 +2294,35 @@ ProcessInterrupts(void)
}
/*
* IA64-specific code to fetch the AR.BSP register for stack depth checks.
*
* We currently support gcc and icc here.
*/
#if defined(__ia64__) || defined(__ia64)
#include <asm/ia64regs.h>
static __inline__ char *
ia64_get_bsp(void)
{
char *ret;
#ifndef __INTEL_COMPILER
/* the ;; is a "stop", seems to be required before fetching BSP */
__asm__ __volatile__(
";;\n"
" mov %0=ar.bsp \n"
: "=r"(ret));
#else
ret = (char *) __getReg(_IA64_REG_AR_BSP);
#endif
return ret;
}
#endif /* IA64 */
/*
* check_stack_depth: check for excessively deep recursion
*
@ -2335,6 +2370,27 @@ check_stack_depth(void)
errmsg("stack depth limit exceeded"),
errhint("Increase the configuration parameter \"max_stack_depth\".")));
}
/*
* On IA64 there is a separate "register" stack that requires its own
* independent check. For this, we have to measure the change in the
* "BSP" pointer from PostgresMain to here. Logic is just as above,
* except that we know IA64's register stack grows up.
*
* Note we assume that the same max_stack_depth applies to both stacks.
*/
#if defined(__ia64__) || defined(__ia64)
stack_depth = (long) (ia64_get_bsp() - register_stack_base_ptr);
if (stack_depth > max_stack_depth_bytes &&
register_stack_base_ptr != NULL)
{
ereport(ERROR,
(errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
errmsg("stack depth limit exceeded"),
errhint("Increase the configuration parameter \"max_stack_depth\".")));
}
#endif /* IA64 */
}
/* GUC assign hook to update max_stack_depth_bytes from max_stack_depth */
@ -2491,6 +2547,9 @@ PostgresMain(int argc, char *argv[], const char *username)
/* Set up reference point for stack depth checking */
stack_base_ptr = &stack_base;
#if defined(__ia64__) || defined(__ia64)
register_stack_base_ptr = ia64_get_bsp();
#endif
/* Compute paths, if we didn't inherit them from postmaster */
if (my_exec_path[0] == '\0')