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

Reply via email to