aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2025-01-30 16:44:47 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2025-01-30 16:44:47 -0500
commitb9d232b9de89aa9282f9a2e7c85f783bcd334af2 (patch)
treef80e8c9c53e69761113beed93118beb33897dc09
parentb9aa4166fa3823d4f1f76286ca21fcfa991ce036 (diff)
downloadpostgresql-b9d232b9de89aa9282f9a2e7c85f783bcd334af2.tar.gz
postgresql-b9d232b9de89aa9282f9a2e7c85f783bcd334af2.zip
Use "ssize_t" not "long" in max_stack_depth-related code.
This change adapts these functions to the machine's address width without depending on "long" to be the right size. (It isn't on Win64, for example.) While it seems unlikely anyone would care to run with a stack depth limit exceeding 2GB, this is part of a general push to avoid using type "long" to represent memory sizes. It's convenient to use ssize_t rather than the perhaps-more-obvious choice of size_t/Size, because the code involved depends on working with a signed data type. Our MAX_KILOBYTES limit already ensures that ssize_t will be sufficient to represent the maximum value of max_stack_depth. Extracted from a larger patch by Vladlen, plus additional hackery by me. Author: Vladlen Popolitov <v.popolitov@postgrespro.ru> Author: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/1a01f0-66ec2d80-3b-68487680@27595217
-rw-r--r--src/backend/utils/misc/guc.c6
-rw-r--r--src/backend/utils/misc/stack_depth.c30
-rw-r--r--src/include/miscadmin.h4
3 files changed, 22 insertions, 18 deletions
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index f822b069f41..12192445218 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -1589,7 +1589,7 @@ static void
InitializeGUCOptionsFromEnvironment(void)
{
char *env;
- long stack_rlimit;
+ ssize_t stack_rlimit;
env = getenv("PGPORT");
if (env != NULL)
@@ -1613,7 +1613,7 @@ InitializeGUCOptionsFromEnvironment(void)
stack_rlimit = get_stack_depth_rlimit();
if (stack_rlimit > 0)
{
- long new_limit = (stack_rlimit - STACK_DEPTH_SLOP) / 1024L;
+ ssize_t new_limit = (stack_rlimit - STACK_DEPTH_SLOP) / 1024;
if (new_limit > 100)
{
@@ -1627,7 +1627,7 @@ InitializeGUCOptionsFromEnvironment(void)
new_limit = 2048;
source = PGC_S_DYNAMIC_DEFAULT;
}
- snprintf(limbuf, sizeof(limbuf), "%ld", new_limit);
+ snprintf(limbuf, sizeof(limbuf), "%d", (int) new_limit);
SetConfigOption("max_stack_depth", limbuf,
PGC_POSTMASTER, source);
}
diff --git a/src/backend/utils/misc/stack_depth.c b/src/backend/utils/misc/stack_depth.c
index 1c79b919f45..8f7cf531fbc 100644
--- a/src/backend/utils/misc/stack_depth.c
+++ b/src/backend/utils/misc/stack_depth.c
@@ -26,7 +26,7 @@
int max_stack_depth = 100;
/* max_stack_depth converted to bytes for speed of checking */
-static long max_stack_depth_bytes = 100 * 1024L;
+static ssize_t max_stack_depth_bytes = 100 * (ssize_t) 1024;
/*
* Stack base pointer -- initialized by set_stack_base(), which
@@ -109,12 +109,12 @@ bool
stack_is_too_deep(void)
{
char stack_top_loc;
- long stack_depth;
+ ssize_t stack_depth;
/*
* Compute distance from reference point to my local variables
*/
- stack_depth = (long) (stack_base_ptr - &stack_top_loc);
+ stack_depth = (ssize_t) (stack_base_ptr - &stack_top_loc);
/*
* Take abs value, since stacks grow up on some machines, down on others
@@ -141,13 +141,13 @@ stack_is_too_deep(void)
bool
check_max_stack_depth(int *newval, void **extra, GucSource source)
{
- long newval_bytes = *newval * 1024L;
- long stack_rlimit = get_stack_depth_rlimit();
+ ssize_t newval_bytes = *newval * (ssize_t) 1024;
+ ssize_t stack_rlimit = get_stack_depth_rlimit();
if (stack_rlimit > 0 && newval_bytes > stack_rlimit - STACK_DEPTH_SLOP)
{
- GUC_check_errdetail("\"max_stack_depth\" must not exceed %ldkB.",
- (stack_rlimit - STACK_DEPTH_SLOP) / 1024L);
+ GUC_check_errdetail("\"max_stack_depth\" must not exceed %zdkB.",
+ (stack_rlimit - STACK_DEPTH_SLOP) / 1024);
GUC_check_errhint("Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent.");
return false;
}
@@ -158,7 +158,7 @@ check_max_stack_depth(int *newval, void **extra, GucSource source)
void
assign_max_stack_depth(int newval, void *extra)
{
- long newval_bytes = newval * 1024L;
+ ssize_t newval_bytes = newval * (ssize_t) 1024;
max_stack_depth_bytes = newval_bytes;
}
@@ -167,12 +167,16 @@ assign_max_stack_depth(int newval, void *extra)
* Obtain platform stack depth limit (in bytes)
*
* Return -1 if unknown
+ *
+ * Note: we choose to use ssize_t not size_t as the result type because
+ * callers compute values that could theoretically go negative,
+ * such as "result - STACK_DEPTH_SLOP".
*/
-long
+ssize_t
get_stack_depth_rlimit(void)
{
#if defined(HAVE_GETRLIMIT)
- static long val = 0;
+ static ssize_t val = 0;
/* This won't change after process launch, so check just once */
if (val == 0)
@@ -182,10 +186,10 @@ get_stack_depth_rlimit(void)
if (getrlimit(RLIMIT_STACK, &rlim) < 0)
val = -1;
else if (rlim.rlim_cur == RLIM_INFINITY)
- val = LONG_MAX;
+ val = SSIZE_MAX;
/* rlim_cur is probably of an unsigned type, so check for overflow */
- else if (rlim.rlim_cur >= LONG_MAX)
- val = LONG_MAX;
+ else if (rlim.rlim_cur >= SSIZE_MAX)
+ val = SSIZE_MAX;
else
val = rlim.rlim_cur;
}
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index d016a9c9248..a2b63495eec 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -293,7 +293,7 @@ extern PGDLLIMPORT bool VacuumCostActive;
extern PGDLLIMPORT int max_stack_depth;
/* Required daylight between max_stack_depth and the kernel limit, in bytes */
-#define STACK_DEPTH_SLOP (512 * 1024L)
+#define STACK_DEPTH_SLOP (512 * 1024)
typedef char *pg_stack_base_t;
@@ -301,7 +301,7 @@ 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);
extern bool stack_is_too_deep(void);
-extern long get_stack_depth_rlimit(void);
+extern ssize_t get_stack_depth_rlimit(void);
/* in tcop/utility.c */
extern void PreventCommandIfReadOnly(const char *cmdname);