1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*--------------------------------------------------------------------
* Symbols referenced in this file:
* - stack_is_too_deep
* - stack_base_ptr
* - max_stack_depth_bytes
* - check_stack_depth
* - max_stack_depth
*--------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
*
* stack_depth.c
* Functions for monitoring and limiting process stack depth
*
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* src/backend/utils/misc/stack_depth.c
*
*-------------------------------------------------------------------------
*/
/* GUC variable for maximum stack depth (measured in kilobytes) */
__thread int max_stack_depth = 100;
/* max_stack_depth converted to bytes for speed of checking */
static __thread ssize_t max_stack_depth_bytes = 100 * 1024;
/*
* Stack base pointer -- initialized by set_stack_base(), which
* should be called from main().
*/
static __thread char *stack_base_ptr = NULL;
/*
* set_stack_base: set up reference point for stack depth checking
*
* Returns the old reference point, if any.
*/
/*
* 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.
*/
/*
* check_stack_depth/stack_is_too_deep: check for excessively deep recursion
*
* This should be called someplace in any recursive routine that might possibly
* recurse deep enough to overflow the stack. Most Unixen treat stack
* overflow as an unrecoverable SIGSEGV, so we want to error out ourselves
* before hitting the hardware limit.
*
* check_stack_depth() just throws an error summarily. stack_is_too_deep()
* can be used by code that wants to handle the error condition itself.
*/
void
bool
/* GUC check hook for max_stack_depth */
/* GUC assign hook for max_stack_depth */
/*
* 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".
*/