aboutsummaryrefslogtreecommitdiff
path: root/src/backend/port/sysv_shmem.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-01-29 20:04:14 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2014-01-29 20:04:14 -0500
commit01b882fd8468ad019f9dfeb4f7b0d286cc9ffbe5 (patch)
tree02d70ceeca40c1655b640c0eed2e0280462ad3bb /src/backend/port/sysv_shmem.c
parent5525529db191b6f4b893d445e5c801bc456ba3bb (diff)
downloadpostgresql-01b882fd8468ad019f9dfeb4f7b0d286cc9ffbe5.tar.gz
postgresql-01b882fd8468ad019f9dfeb4f7b0d286cc9ffbe5.zip
Fix unsafe references to errno within error messaging logic.
Various places were supposing that errno could be expected to hold still within an ereport() nest or similar contexts. This isn't true necessarily, though in some cases it accidentally failed to fail depending on how the compiler chanced to order the subexpressions. This class of thinko explains recent reports of odd failures on clang-built versions, typically missing or inappropriate HINT fields in messages. Problem identified by Christian Kruse, who also submitted the patch this commit is based on. (I fixed a few issues in his patch and found a couple of additional places with the same disease.) Back-patch as appropriate to all supported branches.
Diffstat (limited to 'src/backend/port/sysv_shmem.c')
-rw-r--r--src/backend/port/sysv_shmem.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c
index cd81aba0c03..98de9346ce4 100644
--- a/src/backend/port/sysv_shmem.c
+++ b/src/backend/port/sysv_shmem.c
@@ -79,15 +79,17 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
if (shmid < 0)
{
+ int shmget_errno = errno;
+
/*
* Fail quietly if error indicates a collision with existing segment.
* One would expect EEXIST, given that we said IPC_EXCL, but perhaps
* we could get a permission violation instead? Also, EIDRM might
* occur if an old seg is slated for destruction but not gone yet.
*/
- if (errno == EEXIST || errno == EACCES
+ if (shmget_errno == EEXIST || shmget_errno == EACCES
#ifdef EIDRM
- || errno == EIDRM
+ || shmget_errno == EIDRM
#endif
)
return NULL;
@@ -101,10 +103,8 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
* size against SHMMIN in the preexisting-segment case, so we will
* not get EINVAL a second time if there is such a segment.
*/
- if (errno == EINVAL)
+ if (shmget_errno == EINVAL)
{
- int save_errno = errno;
-
shmid = shmget(memKey, 0, IPC_CREAT | IPC_EXCL | IPCProtection);
if (shmid < 0)
@@ -130,19 +130,18 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
elog(LOG, "shmctl(%d, %d, 0) failed: %m",
(int) shmid, IPC_RMID);
}
-
- errno = save_errno;
}
/*
* Else complain and abort
*/
+ errno = shmget_errno;
ereport(FATAL,
(errmsg("could not create shared memory segment: %m"),
errdetail("Failed system call was shmget(key=%lu, size=%lu, 0%o).",
(unsigned long) memKey, (unsigned long) size,
IPC_CREAT | IPC_EXCL | IPCProtection),
- (errno == EINVAL) ?
+ (shmget_errno == EINVAL) ?
errhint("This error usually means that PostgreSQL's request for a shared memory "
"segment exceeded your kernel's SHMMAX parameter. You can either "
"reduce the request size or reconfigure the kernel with larger SHMMAX. "
@@ -155,7 +154,7 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
"The PostgreSQL documentation contains more information about shared "
"memory configuration.",
(unsigned long) size, NBuffers, MaxBackends) : 0,
- (errno == ENOMEM) ?
+ (shmget_errno == ENOMEM) ?
errhint("This error usually means that PostgreSQL's request for a shared "
"memory segment exceeded available memory or swap space. "
"To reduce the request size (currently %lu bytes), reduce "
@@ -164,7 +163,7 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
"The PostgreSQL documentation contains more information about shared "
"memory configuration.",
(unsigned long) size, NBuffers, MaxBackends) : 0,
- (errno == ENOSPC) ?
+ (shmget_errno == ENOSPC) ?
errhint("This error does *not* mean that you have run out of disk space. "
"It occurs either if all available shared memory IDs have been taken, "
"in which case you need to raise the SHMMNI parameter in your kernel, "