Skip to content

Commit

Permalink
Avoid sharing cygheaps across Cygwin versions
Browse files Browse the repository at this point in the history
It frequently leads to problems when trying, say, to call from Git for
Windows' Bash into Cygwin's or MSYS2's, merely because sharing that data
is pretty finicky.

For example, using the Git for Windows that is current at time of
writing, trying to call MSYS2's Bash from Git for Windows' Bash fails
somewhere in `_cmalloc()`, without any error message, and with the
rather misleading exit code 127 (a code which is reserved to indicate
that a command was not found).

Let's just treat these as completely incompatible with one another, by
virtue of using a different `CHILD_INFO_MAGIC` constant.

Let's take the msys2-runtime commit as the tell-tale whether two MSYS2
runtime versions are compatible with each other. To support building in
the MSYS2-packages repository (where we do not check out the
`msys2-runtime` but instead check out Cygwin and apply patches on top),
let's accept a hard-coded commit hash as `./configure` option.

One consequence is that spawned MSYS processes using a different MSYS2
runtime will not be visible as such to the parent process, i.e. they
cannot share any resources such as pseudo terminals. But that's okay,
they are simply treated as if they were regular Win32 programs.

This should also help the scenario where interactions between two
different versions of Git for Windows lead to those infamous `cygheap
base mismatch detected` problems mentioned e.g. in
git-for-windows/git#4255

Note: We have to use a very rare form of encoding the brackets in the
`expr` calls: quadrigraphs (for a thorough explanation, see
https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.70/html_node/Quadrigraphs.html#Quadrigraphs).
This is necessary because it is apparently impossible in `configure.ac`
files to encode brackets otherwise.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
  • Loading branch information
dscho committed Sep 6, 2023
1 parent e6add2f commit 4d86367
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 2 deletions.
28 changes: 28 additions & 0 deletions winsup/configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,34 @@ AC_CHECK_TOOL(RANLIB, ranlib, ranlib)
AC_CHECK_TOOL(STRIP, strip, strip)
AC_CHECK_TOOL(WINDRES, windres, windres)

# Record msys2-runtime commit
AC_ARG_WITH([msys2-runtime-commit],
[AS_HELP_STRING([--with-msys2-runtime-commit=COMMIT],
[indicate the msys2-runtime commit corresponding to this build])],
[MSYS2_RUNTIME_COMMIT=$withval], [MSYS2_RUNTIME_COMMIT=yes])
case "$MSYS2_RUNTIME_COMMIT" in
no)
MSYS2_RUNTIME_COMMIT=
MSYS2_RUNTIME_COMMIT_HEX=0
;;
yes|auto)
if MSYS2_RUNTIME_COMMIT="$(git --git-dir="$srcdir/../.git" rev-parse HEAD)"
then
MSYS2_RUNTIME_COMMIT_HEX="0x$(expr "$MSYS2_RUNTIME_COMMIT" : '\(.\{,8\}\)')ull"
else
AC_MSG_WARN([Could not determine msys2-runtime commit"])
MSYS2_RUNTIME_COMMIT=
MSYS2_RUNTIME_COMMIT_HEX=0
fi
;;
*)
expr "$MSYS2_RUNTIME_COMMIT" : '@<:@0-9a-f@:>@\{6,64\}$' ||
AC_MSG_ERROR([Invalid commit name: "$MSYS2_RUNTIME_COMMIT"])
MSYS2_RUNTIME_COMMIT_HEX="0x$(expr "$MSYS2_RUNTIME_COMMIT" : '\(.\{,8\}\)')ull"
;;
esac
AC_SUBST(MSYS2_RUNTIME_COMMIT_HEX)

AC_ARG_ENABLE(debugging,
[AS_HELP_STRING([--enable-debugging],[Build a cygwin DLL which has more consistency checking for debugging])],
[case "${enableval}" in
Expand Down
3 changes: 3 additions & 0 deletions winsup/cygwin/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ if TARGET_X86_64
COMMON_CFLAGS+=-mcmodel=small
endif

VERSION_CFLAGS = -DMSYS2_RUNTIME_COMMIT_HEX="@MSYS2_RUNTIME_COMMIT_HEX@"
COMMON_CFLAGS += $(VERSION_CFLAGS)

AM_CFLAGS=$(cflags_common) $(COMMON_CFLAGS)
AM_CXXFLAGS=$(cxxflags_common) $(COMMON_CFLAGS) -fno-threadsafe-statics

Expand Down
2 changes: 1 addition & 1 deletion winsup/cygwin/dcrt0.cc
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ get_cygwin_startup_info ()
child_info *res = (child_info *) si.lpReserved2;

if (si.cbReserved2 < EXEC_MAGIC_SIZE || !res
|| res->intro != PROC_MAGIC_GENERIC || res->magic != CHILD_INFO_MAGIC)
|| res->intro != PROC_MAGIC_GENERIC || res->magic != (CHILD_INFO_MAGIC ^ MSYS2_RUNTIME_COMMIT_HEX))
{
strace.activate (false);
res = NULL;
Expand Down
2 changes: 1 addition & 1 deletion winsup/cygwin/sigproc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,7 @@ int child_info::retry_count = 0;
child_info::child_info (unsigned in_cb, child_info_types chtype,
bool need_subproc_ready):
msv_count (0), cb (in_cb), intro (PROC_MAGIC_GENERIC),
magic (CHILD_INFO_MAGIC), type (chtype), cygheap (::cygheap),
magic (CHILD_INFO_MAGIC ^ MSYS2_RUNTIME_COMMIT_HEX), type (chtype), cygheap (::cygheap),
cygheap_max (::cygheap_max), flag (0), retry (child_info::retry_count),
rd_proc_pipe (NULL), wr_proc_pipe (NULL), sigmask (_my_tls.sigmask)
{
Expand Down

0 comments on commit 4d86367

Please sign in to comment.