88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.511 2006/10/07 16:43 :28 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.512 2006/10/07 19:25 :28 tgl Exp $
1212 *
1313 * NOTES
1414 * this is the "main" module of the postgres backend and
2323#include <signal.h>
2424#include <fcntl.h>
2525#include <sys/socket.h>
26- #if HAVE_SYS_SELECT_H
26+ #ifdef HAVE_SYS_SELECT_H
2727#include <sys/select.h>
2828#endif
29+ #ifdef HAVE_SYS_RESOURCE_H
30+ #include <sys/resource.h>
31+ #endif
2932#ifdef HAVE_GETOPT_H
3033#include <getopt.h>
3134#endif
3235
36+ #ifndef HAVE_GETRUSAGE
37+ #include "rusagestub.h"
38+ #endif
39+
3340#include "access/printtup.h"
3441#include "access/xact.h"
3542#include "catalog/pg_type.h"
@@ -78,7 +85,7 @@ bool Log_disconnections = false;
7885LogStmtLevel log_statement = LOGSTMT_NONE ;
7986
8087/* GUC variable for maximum stack depth (measured in kilobytes) */
81- int max_stack_depth = 2048 ;
88+ int max_stack_depth = 100 ;
8289
8390/* wait N seconds to allow attach from a debugger */
8491int PostAuthDelay = 0 ;
@@ -91,7 +98,7 @@ int PostAuthDelay = 0;
9198 */
9299
93100/* max_stack_depth converted to bytes for speed of checking */
94- static long max_stack_depth_bytes = 2048 * 1024L ;
101+ static long max_stack_depth_bytes = 100 * 1024L ;
95102
96103/*
97104 * Stack base pointer -- initialized by PostgresMain. This is not static
@@ -2490,9 +2497,7 @@ ProcessInterrupts(void)
24902497 * This should be called someplace in any recursive routine that might possibly
24912498 * recurse deep enough to overflow the stack. Most Unixen treat stack
24922499 * overflow as an unrecoverable SIGSEGV, so we want to error out ourselves
2493- * before hitting the hardware limit. Unfortunately we have no direct way
2494- * to detect the hardware limit, so we have to rely on the admin to set a
2495- * GUC variable for it ...
2500+ * before hitting the hardware limit.
24962501 */
24972502void
24982503check_stack_depth (void )
@@ -2530,13 +2535,24 @@ check_stack_depth(void)
25302535 }
25312536}
25322537
2533- /* GUC assign hook to update max_stack_depth_bytes from max_stack_depth */
2538+ /* GUC assign hook for max_stack_depth */
25342539bool
25352540assign_max_stack_depth (int newval , bool doit , GucSource source )
25362541{
2537- /* Range check was already handled by guc.c */
2542+ long newval_bytes = newval * 1024L ;
2543+ long stack_rlimit = get_stack_depth_rlimit ();
2544+
2545+ if (stack_rlimit > 0 && newval_bytes > stack_rlimit - STACK_DEPTH_SLOP )
2546+ {
2547+ ereport ((source >= PGC_S_INTERACTIVE ) ? ERROR : LOG ,
2548+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
2549+ errmsg ("\"max_stack_depth\" must not exceed %ldkB" ,
2550+ (stack_rlimit - STACK_DEPTH_SLOP ) / 1024L ),
2551+ errhint ("Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." )));
2552+ return false;
2553+ }
25382554 if (doit )
2539- max_stack_depth_bytes = newval * 1024L ;
2555+ max_stack_depth_bytes = newval_bytes ;
25402556 return true;
25412557}
25422558
@@ -3635,11 +3651,36 @@ PostgresMain(int argc, char *argv[], const char *username)
36353651 return 1 ; /* keep compiler quiet */
36363652}
36373653
3638- #ifndef HAVE_GETRUSAGE
3639- #include "rusagestub.h"
3640- #else
3641- #include <sys/resource.h>
3642- #endif /* HAVE_GETRUSAGE */
3654+
3655+ /*
3656+ * Obtain platform stack depth limit (in bytes)
3657+ *
3658+ * Return -1 if unlimited or not known
3659+ */
3660+ long
3661+ get_stack_depth_rlimit (void )
3662+ {
3663+ #if defined(HAVE_GETRLIMIT ) && defined(RLIMIT_STACK )
3664+ static long val = 0 ;
3665+
3666+ /* This won't change after process launch, so check just once */
3667+ if (val == 0 )
3668+ {
3669+ struct rlimit rlim ;
3670+
3671+ if (getrlimit (RLIMIT_STACK , & rlim ) < 0 )
3672+ val = -1 ;
3673+ else if (rlim .rlim_cur == RLIM_INFINITY )
3674+ val = -1 ;
3675+ else
3676+ val = rlim .rlim_cur ;
3677+ }
3678+ return val ;
3679+ #else /* no getrlimit */
3680+ return -1 ;
3681+ #endif
3682+ }
3683+
36433684
36443685static struct rusage Save_r ;
36453686static struct timeval Save_t ;
0 commit comments