mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
Supply a new memory manager for RuntimeDyld, to avoid crashes in generated code caused by memory placement that can overflow a 32 bit data type. This is a drop-in replacement for the llvm::SectionMemoryManager class in the LLVM library, with Michael Smith's proposed fix from https://www.github.com/llvm/llvm-project/pull/71968. We hereby slurp it into our own source tree, after moving into a new namespace llvm::backport and making some minor adjustments so that it can be compiled with older LLVM versions as far back as 12. It's harder to make it work on even older LLVM versions, but it doesn't seem likely that people are really using them so that is not investigated for now. The problem could also be addressed by switching to JITLink instead of RuntimeDyld, and that is the LLVM project's recommended solution as the latter is about to be deprecated. We'll have to do that soon enough anyway, and then when the LLVM version support window advances far enough in a few years we'll be able to delete this code. Unfortunately that wouldn't be enough for PostgreSQL today: in most relevant versions of LLVM, JITLink is missing or incomplete. Several other projects have already back-ported this fix into their fork of LLVM, which is a vote of confidence despite the lack of commit into LLVM as of today. We don't have our own copy of LLVM so we can't do exactly what they've done; instead we have a copy of the whole patched class so we can pass an instance of it to RuntimeDyld. The LLVM project hasn't chosen to commit the fix yet, and even if it did, it wouldn't be back-ported into the releases of LLVM that most of our users care about, so there is not much point in waiting any longer for that. If they make further changes and commit it to LLVM 19 or 20, we'll still need this for older versions, but we may want to resynchronize our copy and update some comments. The changes that we've had to make to our copy can be seen by diffing our SectionMemoryManager.{h,cpp} files against the ones in the tree of the pull request. Per the LLVM project's license requirements, a copy is in SectionMemoryManager.LICENSE. This should fix the spate of crash reports we've been receiving lately from users on large memory ARM systems. Back-patch to all supported releases. Co-authored-by: Thomas Munro <thomas.munro@gmail.com> Co-authored-by: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com> Reviewed-by: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com> Reviewed-by: Daniel Gustafsson <daniel@yesql.se> (license aspects) Reported-by: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com> Discussion: https://postgr.es/m/CAO6_Xqr63qj%3DSx7HY6ZiiQ6R_JbX%2B-p6sTPwDYwTWZjUmjsYBg%40mail.gmail.com
163 lines
6.3 KiB
Bash
Executable File
163 lines
6.3 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# Check (almost) all PostgreSQL include files for standalone build.
|
|
#
|
|
# Argument 1 is the top-level source directory, argument 2 the
|
|
# top-level build directory (they might be the same). If not set, they
|
|
# default to the current directory.
|
|
#
|
|
# Needs to be run after configuring and creating all generated headers.
|
|
# It's advisable to configure --with-perl --with-python, else you're
|
|
# likely to get errors from associated headers.
|
|
#
|
|
# No output if everything is OK, else compiler errors.
|
|
#
|
|
# src/tools/pginclude/headerscheck
|
|
# Copyright (c) 2009-2022, PostgreSQL Global Development Group
|
|
|
|
if [ -z "$1" ]; then
|
|
srcdir="."
|
|
else
|
|
srcdir="$1"
|
|
fi
|
|
|
|
if [ -z "$2" ]; then
|
|
builddir="."
|
|
else
|
|
builddir="$2"
|
|
fi
|
|
|
|
me=`basename $0`
|
|
|
|
# Pull some info from configure's results.
|
|
MGLOB="$builddir/src/Makefile.global"
|
|
CPPFLAGS=`sed -n 's/^CPPFLAGS[ ]*=[ ]*//p' "$MGLOB"`
|
|
CFLAGS=`sed -n 's/^CFLAGS[ ]*=[ ]*//p' "$MGLOB"`
|
|
CC=`sed -n 's/^CC[ ]*=[ ]*//p' "$MGLOB"`
|
|
PG_SYSROOT=`sed -n 's/^PG_SYSROOT[ ]*=[ ]*//p' "$MGLOB"`
|
|
perl_includespec=`sed -n 's/^perl_includespec[ ]*=[ ]*//p' "$MGLOB"`
|
|
python_includespec=`sed -n 's/^python_includespec[ ]*=[ ]*//p' "$MGLOB"`
|
|
|
|
# needed on Darwin
|
|
CPPFLAGS=`echo "$CPPFLAGS" | sed "s|\\\$(PG_SYSROOT)|$PG_SYSROOT|g"`
|
|
|
|
# (EXTRAFLAGS is not set here, but user can pass it in if need be.)
|
|
|
|
# Create temp directory.
|
|
tmp=`mktemp -d /tmp/$me.XXXXXX`
|
|
|
|
trap 'rm -rf $tmp' 0 1 2 3 15
|
|
|
|
# Scan all of src/ and contrib/ for header files.
|
|
for f in `cd "$srcdir" && find src contrib -name '*.h' -print`
|
|
do
|
|
# Ignore files that are unportable or intentionally not standalone.
|
|
|
|
# These files are platform-specific, and c.h will include the
|
|
# one that's relevant for our current platform anyway.
|
|
test "$f" = src/include/port/aix.h && continue
|
|
test "$f" = src/include/port/cygwin.h && continue
|
|
test "$f" = src/include/port/darwin.h && continue
|
|
test "$f" = src/include/port/freebsd.h && continue
|
|
test "$f" = src/include/port/hpux.h && continue
|
|
test "$f" = src/include/port/linux.h && continue
|
|
test "$f" = src/include/port/netbsd.h && continue
|
|
test "$f" = src/include/port/openbsd.h && continue
|
|
test "$f" = src/include/port/solaris.h && continue
|
|
test "$f" = src/include/port/win32.h && continue
|
|
|
|
# Additional Windows-specific headers.
|
|
test "$f" = src/include/port/win32_port.h && continue
|
|
test "$f" = src/include/port/win32/sys/socket.h && continue
|
|
test "$f" = src/include/port/win32_msvc/dirent.h && continue
|
|
test "$f" = src/include/port/win32_msvc/utime.h && continue
|
|
test "$f" = src/include/port/win32ntdll.h && continue
|
|
test "$f" = src/port/pthread-win32.h && continue
|
|
|
|
# Likewise, these files are platform-specific, and the one
|
|
# relevant to our platform will be included by atomics.h.
|
|
test "$f" = src/include/port/atomics/arch-arm.h && continue
|
|
test "$f" = src/include/port/atomics/arch-hppa.h && continue
|
|
test "$f" = src/include/port/atomics/arch-ia64.h && continue
|
|
test "$f" = src/include/port/atomics/arch-ppc.h && continue
|
|
test "$f" = src/include/port/atomics/arch-x86.h && continue
|
|
test "$f" = src/include/port/atomics/fallback.h && continue
|
|
test "$f" = src/include/port/atomics/generic.h && continue
|
|
test "$f" = src/include/port/atomics/generic-acc.h && continue
|
|
test "$f" = src/include/port/atomics/generic-gcc.h && continue
|
|
test "$f" = src/include/port/atomics/generic-msvc.h && continue
|
|
test "$f" = src/include/port/atomics/generic-sunpro.h && continue
|
|
|
|
# rusagestub.h is also platform-specific, and will be included
|
|
# by utils/pg_rusage.h if necessary.
|
|
test "$f" = src/include/rusagestub.h && continue
|
|
|
|
# sepgsql.h depends on headers that aren't there on most platforms.
|
|
test "$f" = contrib/sepgsql/sepgsql.h && continue
|
|
|
|
# These files are not meant to be included standalone, because
|
|
# they contain lists that might have multiple use-cases.
|
|
test "$f" = src/include/access/rmgrlist.h && continue
|
|
test "$f" = src/include/parser/kwlist.h && continue
|
|
test "$f" = src/pl/plpgsql/src/pl_reserved_kwlist.h && continue
|
|
test "$f" = src/pl/plpgsql/src/pl_unreserved_kwlist.h && continue
|
|
test "$f" = src/interfaces/ecpg/preproc/c_kwlist.h && continue
|
|
test "$f" = src/interfaces/ecpg/preproc/ecpg_kwlist.h && continue
|
|
test "$f" = src/include/regex/regerrs.h && continue
|
|
test "$f" = src/include/tcop/cmdtaglist.h && continue
|
|
test "$f" = src/pl/plpgsql/src/plerrcodes.h && continue
|
|
test "$f" = src/pl/plpython/spiexceptions.h && continue
|
|
test "$f" = src/pl/tcl/pltclerrcodes.h && continue
|
|
|
|
# Also not meant to be included standalone.
|
|
test "$f" = src/include/common/unicode_combining_table.h && continue
|
|
test "$f" = src/include/common/unicode_east_asian_fw_table.h && continue
|
|
|
|
# We can't make these Bison output files compilable standalone
|
|
# without using "%code require", which old Bison versions lack.
|
|
# parser/gram.h will be included by parser/gramparse.h anyway.
|
|
test "$f" = src/include/parser/gram.h && continue
|
|
test "$f" = src/backend/parser/gram.h && continue
|
|
test "$f" = src/pl/plpgsql/src/pl_gram.h && continue
|
|
test "$f" = src/interfaces/ecpg/preproc/preproc.h && continue
|
|
|
|
# This produces a "no previous prototype" warning.
|
|
test "$f" = src/include/storage/checksum_impl.h && continue
|
|
|
|
# SectionMemoryManager.h is C++
|
|
test "$f" = src/include/jit/SectionMemoryManager.h && continue
|
|
|
|
# ppport.h is not under our control, so we can't make it standalone.
|
|
test "$f" = src/pl/plperl/ppport.h && continue
|
|
|
|
# regression.h is not actually C, but ECPG code.
|
|
test "$f" = src/interfaces/ecpg/test/regression.h && continue
|
|
# printf_hack.h produces "unused function" warnings.
|
|
test "$f" = src/interfaces/ecpg/test/printf_hack.h && continue
|
|
|
|
# OK, create .c file to include this .h file.
|
|
{
|
|
test "$f" != src/include/postgres_fe.h && echo '#include "postgres.h"'
|
|
echo "#include \"$f\""
|
|
} >$tmp/test.c
|
|
|
|
# Some subdirectories need extra -I switches.
|
|
case "$f" in
|
|
src/pl/plperl/*)
|
|
EXTRAINCLUDES="$perl_includespec" ;;
|
|
src/pl/plpython/*)
|
|
EXTRAINCLUDES="$python_includespec" ;;
|
|
src/interfaces/ecpg/*)
|
|
EXTRAINCLUDES="-I $builddir/src/interfaces/ecpg/include -I $srcdir/src/interfaces/ecpg/include" ;;
|
|
*)
|
|
EXTRAINCLUDES="" ;;
|
|
esac
|
|
|
|
# Run the test.
|
|
${CC:-gcc} $CPPFLAGS $CFLAGS -I $builddir -I $srcdir \
|
|
-I $builddir/src/include -I $srcdir/src/include \
|
|
-I $builddir/src/interfaces/libpq -I $srcdir/src/interfaces/libpq \
|
|
$EXTRAINCLUDES $EXTRAFLAGS -c $tmp/test.c -o $tmp/test.o
|
|
|
|
done
|