summaryrefslogtreecommitdiff
path: root/contrib/pageinspect/rawpage.c
diff options
context:
space:
mode:
authorTom Lane2017-02-03 16:34:41 +0000
committerTom Lane2017-02-03 16:34:47 +0000
commit14e9b18fed289e483ed28daec60fdab95da9cc48 (patch)
tree928ca1c449c1ba884748758d2d52959c3af76881 /contrib/pageinspect/rawpage.c
parent29e312bc1301061ae9f897ff39f3b230c421a5fb (diff)
In pageinspect/hashfuncs.c, avoid crashes on alignment-picky machines.
On machines with MAXALIGN = 8, the payload of a bytea is not maxaligned, since it will start 4 bytes into a palloc'd value. On alignment-picky hardware, this will cause failures in accesses to 8-byte-wide values within the page. We already encountered this problem when we introduced GIN index inspection functions, and fixed it in commit 84ad68d64. Make use of the same function for hash indexes. A small difficulty is that up to now contrib/pageinspect has not shared any functions at all across files. To support that, introduce a common header file "pageinspect.h" for the module. Also, move get_page_from_raw() out of ginfuncs.c, where it didn't especially belong, and put it in rawpage.c which seems a more natural home. Per buildfarm. Discussion: https://postgr.es/m/17311.1486134714@sss.pgh.pa.us
Diffstat (limited to 'contrib/pageinspect/rawpage.c')
-rw-r--r--contrib/pageinspect/rawpage.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index a2ac078d404..102f360c6f7 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -15,6 +15,8 @@
#include "postgres.h"
+#include "pageinspect.h"
+
#include "access/htup_details.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
@@ -158,6 +160,42 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
return raw_page;
}
+
+/*
+ * get_page_from_raw
+ *
+ * Get a palloc'd, maxalign'ed page image from the result of get_raw_page()
+ *
+ * On machines with MAXALIGN = 8, the payload of a bytea is not maxaligned,
+ * since it will start 4 bytes into a palloc'd value. On alignment-picky
+ * machines, this will cause failures in accesses to 8-byte-wide values
+ * within the page. We don't need to worry if accessing only 4-byte or
+ * smaller fields, but when examining a struct that contains 8-byte fields,
+ * use this function for safety.
+ */
+Page
+get_page_from_raw(bytea *raw_page)
+{
+ Page page;
+ int raw_page_size;
+
+ raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
+
+ if (raw_page_size != BLCKSZ)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid page size"),
+ errdetail("Expected %d bytes, got %d.",
+ BLCKSZ, raw_page_size)));
+
+ page = palloc(raw_page_size);
+
+ memcpy(page, VARDATA(raw_page), raw_page_size);
+
+ return page;
+}
+
+
/*
* page_header
*