On Mon, 17 Apr 2023, sisyphus wrote:
On Mon, Apr 17, 2023 at 1:02 AM Martin Storsjö <[email protected]> wrote:
mingw-w64 never defined USE_NO_MINGW_SETJMP_TWO_ARGS. Do the perl sources
define it?
Yes - and for quite a long time. (But only for 32-bit builds of course.)
https://github.com/Perl/perl5/blob/blead/dist/threads/threads.xs begins with
###########################
#define PERL_NO_GET_CONTEXT
/* Workaround for mingw 32-bit compiler by mingw-w64.sf.net - has to come
before any #include.
* It also defines USE_NO_MINGW_SETJMP_TWO_ARGS for the mingw.org 32-bit
compilers ... but
* that's ok as that compiler makes no use of that symbol anyway */
#if defined(WIN32) && defined(__MINGW32__) && !defined(__MINGW64__)
# define USE_NO_MINGW_SETJMP_TWO_ARGS 1
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
/* Workaround for XSUB.h bug under WIN32 */
#ifdef WIN32
# undef setjmp
# if defined(USE_NO_MINGW_SETJMP_TWO_ARGS) || (!defined(__BORLANDC__) &&
!defined(__MINGW64__))
# define setjmp(x) _setjmp(x)
# endif
# if defined(__MINGW64__)
# include <intrin.h>
# define setjmp(x) _setjmpex((x), mingw_getsp())
# endif
#endif
....
##########################
Thanks; I see that this has been present since you added support for
mingw-w64 in perl in 2009 in
https://github.com/Perl/perl5/commit/fa58a56f3cdf71021d7d7a49e98845f57652a3fe.
This seems to extend on an existing setjmp tweak that did "#undef setjmp
#define setjmp(x) _setjmp(x)" since 2006 in
https://github.com/Perl/perl5/commit/4dcb9e53db5ab3b8d2b2f8eaba341cb2c0c5d2b8#diff-5663a0939c46ed136ef9d3ab8bd58486226561161957fe34bf1b0b08051ab6fb.
No comment there either about what the "XSUB.h bug under WIN32" that it
works around is.
As you can see, the aim is, for 32-bit builds only, to:
# define setjmp(x) _setjmp(x)
and, while that works fine with the 12.2.0 setjmp.h, it does not work with
the 13.0.1 setjmp.h.
Well, the perl threads.xs header seems to try to fix things in two ways:
- Defining USE_NO_MINGW_SETJMP_TWO_ARGS, which affects what mingw-w64
setjmp.h does (making setjmp expand to _setjmp() instead of _setjmp3()),
introduced in 2009
- Manually undeffing setjmp and redefining it to _setjmp(), introduced in
2006 (for all windows compilers except Borland, i.e. for MSVC too)
The mingw-w64 commit that removed use of USE_NO_MINGW_SETJMP_TWO_ARGS
would have affected the former, but I don't see why it would affect the
latter; if the latter works as intended there would be no need for
USE_NO_MINGW_SETJMP_TWO_ARGS in the first place.
Do the headers EXTERN.h, perl.h and XSUB.h include the system setjmp.h? I
guess they do, since otherwise there's little point in doing the undef of
setjmp after including them. Do those headers end up calling setjmp()
themselves, so that the redefine in threads.xs comes too late?
In that case it's understandable, but wouldn't the same issue (using the
system's default setjmp instead of the one Perl tries to redefine it to)
hit other compilers like MSVC too?
So in short, we'd need to know which code, where, ends up calling _setjmp3
instead of _setjmp, despite threads.xs's attempts to redefine it.
On a lower level, since commit
82347ded0d43a80de68ba6a35a209717bded5f28a in 2009, mingw-w64's setjmp.h
has been using _setjmp3 for i386, while setting the
USE_NO_MINGW_SETJMP_TWO_ARGS define makes it revert to using _setjmp.
We weren't aware of any issues with using _setjmp3 (and if there are,
maybe we should revisit that change from 2909?) - ideally user code
shouldn't need to know or care about this - the defaults are supposed to
work.
Yes - that might be pertinent to the issue
But the current threads.xs source just undefs that setjmp.h definition and
then defines setjmp() back to using _setjmp().
So I don't see that reverting 82347ded0d43a80de68b6a35a209717bded5f28a will
necessarily help.
I'm not exactly sure what's going on here, but I'm quite sure that
reverting that commit would fix things again. Didn't you say that picking
the setjmp.h header from your gcc 12 build into your gcc 13 build made
things work again? I believe that's fundamentally what reverting that
commit would do.
In case it's relevant, we use only msvcrt compilers to build perl. (Perl
source currently won't build with ucrt - because of the abundance of
msvcrt-specific code in certain places, I expect.)
FWIW, I'm curious about what that msvcrt-specific code is; I'd be happy to
help with pointers if you want to take a dive into that at some point.
AFAIK, it's quite possible that the perl source could be refactored to
use _setjmp3(). Should we (ie perl maintainers) be trying to do just
that ?
Since that's the default of mingw-w64 since 2009 on i386, I guess that'd
be a good direction, to reduce the amount of brittle hacks. I would
presume that doing that would reveal what the original reason for
redefining setjmp was.
// Martin
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public