[postgresql/f15] Work around gcc 4.6.0 bug
Tom Lane
tgl at fedoraproject.org
Fri Jun 10 21:18:22 UTC 2011
commit 975a357c7db4295ce49bffa908aa2e10eec78364
Author: Tom Lane <tgl at redhat.com>
Date: Fri Jun 10 17:16:01 2011 -0400
Work around gcc 4.6.0 bug
postgresql-gcc-workaround.patch | 111 +++++++++++++++++++++++++++++++++++++++
postgresql.spec | 7 ++-
2 files changed, 117 insertions(+), 1 deletions(-)
---
diff --git a/postgresql-gcc-workaround.patch b/postgresql-gcc-workaround.patch
new file mode 100644
index 0000000..7850821
--- /dev/null
+++ b/postgresql-gcc-workaround.patch
@@ -0,0 +1,111 @@
+Back-patch upstream patch to cope with a gcc 4.6.0 bug. This will be
+in PG 9.0.5 and later, but we need it in Fedora *now* because the bug
+breaks WAL replay, thus causing crash recovery failures as well as the
+originally reported symptom of frequent reconnections during standby.
+
+
+commit 45d792f70272ed57b932816562f31c2f79426c2a
+Author: Tom Lane <tgl at sss.pgh.pa.us>
+Date: Fri Jun 10 17:03:11 2011 -0400
+
+ Work around gcc 4.6.0 bug that breaks WAL replay.
+
+ ReadRecord's habit of using both direct references to tmpRecPtr and
+ references to *RecPtr (which is pointing at tmpRecPtr) triggers an
+ optimization bug in gcc 4.6.0, which apparently has forgotten about
+ aliasing rules. Avoid the compiler bug, and make the code more readable
+ to boot, by getting rid of the direct references. Improve the comments
+ while at it.
+
+ Back-patch to all supported versions, in case they get built with 4.6.0.
+
+ Tom Lane, with some cosmetic suggestions from Alex Hunsaker
+
+diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
+index bf8075d..6c18db4 100644
+--- a/src/backend/access/transam/xlog.c
++++ b/src/backend/access/transam/xlog.c
+@@ -3676,23 +3676,32 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
+ RecPtr = &tmpRecPtr;
+
+ /*
+- * Align recptr to next page if no more records can fit on the current
+- * page.
++ * RecPtr is pointing to end+1 of the previous WAL record. We must
++ * advance it if necessary to where the next record starts. First,
++ * align to next page if no more records can fit on the current page.
+ */
+ if (XLOG_BLCKSZ - (RecPtr->xrecoff % XLOG_BLCKSZ) < SizeOfXLogRecord)
+- {
+- NextLogPage(tmpRecPtr);
+- /* We will account for page header size below */
+- }
++ NextLogPage(*RecPtr);
+
+- if (tmpRecPtr.xrecoff >= XLogFileSize)
++ /* Check for crossing of xlog segment boundary */
++ if (RecPtr->xrecoff >= XLogFileSize)
+ {
+- (tmpRecPtr.xlogid)++;
+- tmpRecPtr.xrecoff = 0;
++ (RecPtr->xlogid)++;
++ RecPtr->xrecoff = 0;
+ }
++
++ /*
++ * If at page start, we must skip over the page header. But we can't
++ * do that until we've read in the page, since the header size is
++ * variable.
++ */
+ }
+ else
+ {
++ /*
++ * In this case, the passed-in record pointer should already be
++ * pointing to a valid record starting position.
++ */
+ if (!XRecOffIsValid(RecPtr->xrecoff))
+ ereport(PANIC,
+ (errmsg("invalid record offset at %X/%X",
+@@ -3721,11 +3730,13 @@ retry:
+ if (targetRecOff == 0)
+ {
+ /*
+- * Can only get here in the continuing-from-prev-page case, because
+- * XRecOffIsValid eliminated the zero-page-offset case otherwise. Need
+- * to skip over the new page's header.
++ * At page start, so skip over page header. The Assert checks that
++ * we're not scribbling on caller's record pointer; it's OK because we
++ * can only get here in the continuing-from-prev-record case, since
++ * XRecOffIsValid rejected the zero-page-offset case otherwise.
+ */
+- tmpRecPtr.xrecoff += pageHeaderSize;
++ Assert(RecPtr == &tmpRecPtr);
++ RecPtr->xrecoff += pageHeaderSize;
+ targetRecOff = pageHeaderSize;
+ }
+ else if (targetRecOff < pageHeaderSize)
+diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
+index 3f0930f..367de37 100644
+--- a/src/include/access/xlog_internal.h
++++ b/src/include/access/xlog_internal.h
+@@ -154,13 +154,13 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
+ /* Align a record pointer to next page */
+ #define NextLogPage(recptr) \
+ do { \
+- if (recptr.xrecoff % XLOG_BLCKSZ != 0) \
+- recptr.xrecoff += \
+- (XLOG_BLCKSZ - recptr.xrecoff % XLOG_BLCKSZ); \
+- if (recptr.xrecoff >= XLogFileSize) \
++ if ((recptr).xrecoff % XLOG_BLCKSZ != 0) \
++ (recptr).xrecoff += \
++ (XLOG_BLCKSZ - (recptr).xrecoff % XLOG_BLCKSZ); \
++ if ((recptr).xrecoff >= XLogFileSize) \
+ { \
+- (recptr.xlogid)++; \
+- recptr.xrecoff = 0; \
++ ((recptr).xlogid)++; \
++ (recptr).xrecoff = 0; \
+ } \
+ } while (0)
+
diff --git a/postgresql.spec b/postgresql.spec
index 8ec8fc1..45e863f 100644
--- a/postgresql.spec
+++ b/postgresql.spec
@@ -54,7 +54,7 @@ Summary: PostgreSQL client programs
Name: postgresql
%global majorversion 9.0
Version: 9.0.4
-Release: 2%{?dist}
+Release: 3%{?dist}
# The PostgreSQL license is very similar to other MIT licenses, but the OSI
# recognizes it as an independent license, so we do as well.
License: PostgreSQL
@@ -85,6 +85,7 @@ Source15: postgresql-bashprofile
Patch1: rpm-pgsql.patch
Patch2: postgresql-logging.patch
Patch3: postgresql-perl-rpath.patch
+Patch4: postgresql-gcc-workaround.patch
BuildRequires: perl(ExtUtils::MakeMaker) glibc-devel bison flex gawk
BuildRequires: perl(ExtUtils::Embed), perl-devel
@@ -302,6 +303,7 @@ system, including regression tests and benchmarks.
%patch1 -p1
%patch2 -p1
%patch3 -p1
+%patch4 -p1
# We used to run autoconf here, but there's no longer any real need to,
# since Postgres ships with a reasonably modern configure script.
@@ -820,6 +822,9 @@ rm -rf $RPM_BUILD_ROOT
%endif
%changelog
+* Fri Jun 10 2011 Tom Lane <tgl at redhat.com> 9.0.4-3
+- Work around gcc 4.6.0 bug (temporary backport from next upstream release)
+
* Tue May 10 2011 Tom Lane <tgl at redhat.com> 9.0.4-2
- Add LSB init block to initscript, to ensure sane ordering at system boot
Resolves: #703215
More information about the scm-commits
mailing list