diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 1dac6954885cdc7295817cc09ecf662256927e08..a481eef2c28297c09ff5d0b056f73b91ca8933bb 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -970,6 +970,11 @@ PostmasterMain(int argc, char *argv[]) */ set_max_safe_fds(); + /* + * Set reference point for stack-depth checking. + */ + set_stack_base(); + /* * Initialize the list of active backends. */ @@ -3977,6 +3982,11 @@ SubPostmasterMain(int argc, char *argv[]) memset(&port, 0, sizeof(Port)); read_backend_variables(argv[2], &port); + /* + * Set reference point for stack-depth checking + */ + set_stack_base(); + /* * Set up memory area for GSS information. Mirrors the code in ConnCreate * for the non-exec case. diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 02be36362ce99f57fe7b05b76f391f3dceb3e835..999f63bffb747ed35254ec9c307ed734bf5c4b49 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -115,8 +115,10 @@ int PostAuthDelay = 0; static long max_stack_depth_bytes = 100 * 1024L; /* - * Stack base pointer -- initialized by PostgresMain. This is not static - * so that PL/Java can modify it. + * Stack base pointer -- initialized by PostmasterMain and inherited by + * subprocesses. This is not static because old versions of PL/Java modify + * it directly. Newer versions use set_stack_base(), but we want to stay + * binary-compatible for the time being. */ char *stack_base_ptr = NULL; @@ -2957,6 +2959,53 @@ ia64_get_bsp(void) #endif /* IA64 */ +/* + * set_stack_base: set up reference point for stack depth checking + * + * Returns the old reference point, if any. + */ +pg_stack_base_t +set_stack_base(void) +{ + char stack_base; + pg_stack_base_t old; + +#if defined(__ia64__) || defined(__ia64) + old.stack_base_ptr = stack_base_ptr; + old.register_stack_base_ptr = register_stack_base_ptr; +#else + old = stack_base_ptr; +#endif + + /* 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 + + return old; +} + +/* + * restore_stack_base: restore reference point for stack depth checking + * + * This can be used after set_stack_base() to restore the old value. This + * is currently only used in PL/Java. When PL/Java calls a backend function + * from different thread, the thread's stack is at a different location than + * the main thread's stack, so it sets the base pointer before the call, and + * restores it afterwards. + */ +void +restore_stack_base(pg_stack_base_t base) +{ +#if defined(__ia64__) || defined(__ia64) + stack_base_ptr = base.stack_base_ptr; + register_stack_base_ptr = base.register_stack_base_ptr; +#else + stack_base_ptr = base; +#endif +} + /* * check_stack_depth: check for excessively deep recursion * @@ -2972,7 +3021,7 @@ check_stack_depth(void) long stack_depth; /* - * Compute distance from PostgresMain's local variables to my own + * Compute distance from reference point to to my local variables */ stack_depth = (long) (stack_base_ptr - &stack_top_loc); @@ -3434,7 +3483,6 @@ PostgresMain(int argc, char *argv[], const char *username) { const char *dbname; int firstchar; - char stack_base; StringInfoData input_message; sigjmp_buf local_sigjmp_buf; volatile bool send_ready_for_query = true; @@ -3461,10 +3509,7 @@ PostgresMain(int argc, char *argv[], const char *username) SetProcessingMode(InitProcessing); /* 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 + set_stack_base(); /* Compute paths, if we didn't inherit them from postmaster */ if (my_exec_path[0] == '\0') diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 610cb5907e5c0e547fafca7d817397ca57f567e9..b186eed8f478ae66ca1fde3ee8f08e613d97c54d 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -246,6 +246,19 @@ extern bool VacuumCostActive; /* in tcop/postgres.c */ + +#if defined(__ia64__) || defined(__ia64) +typedef struct +{ + char *stack_base_ptr; + char *register_stack_base_ptr; +} pg_stack_base_t; +#else +typedef char *pg_stack_base_t; +#endif + +extern pg_stack_base_t set_stack_base(void); +extern void restore_stack_base(pg_stack_base_t base); extern void check_stack_depth(void); /* in tcop/utility.c */