Description
Description
I was looking ancient p5p code, and found PERL_FLEXIBLE_EXCEPTIONS
it was removed long ago, but it used Win32 C++ exceptions or MS's C89 SEH exceptions. https://www.nntp.perl.org/group/perl.perl5.porters/2004/07/msg93069.html
Some IRC talk happened, and I've realized perlembed.pod has a large amount of unsafe demo code. Specifically calling into the perl XS API, without a root PP eval frame (jmpenv_t). A test showed that will be a "panic; top_env" not a SEGV as I originally thought. But still, "panic; top_env" doesn't separate P5P internals's emitting "panic; top_env" from bad root proc XS code emitting "panic; top_env".
Still worse, Perl_set_context()/PERL_SET_CONTEXT(), does nothing to disable, still active, jmpbuf_t'es collected from the PREVIOUS OS THREAD in the current my_perl/ithread. Perl_set_context()/PERL_SET_CONTEXT() does nothing to disable jmpbuf_t'es of the previous ithread if any. nGinx/CGI/GUI thread pool r real use cases for suspending/swapping OS threads between my_perls.
Very rare, but undiagnosable, what if a C++ exception erases the C stack frames of PP code (p5p C code), or XS modules (cpan' c code) unaware, are 5 layers deep in C stack frames and PP stack frames, in nested BEGIN {} blocks at use; time?
See IRC chatlog for details that MS's 1993-ucrtbase.dll setjmp() is too dangerous to use because of C++ and C89 SEH objects. And a peculiar MS choice, that C++/C89 SEH frames get "event objects" from 100%/ALL executions of longjmp(), but setjmp()/longjmp()/jmpbuf_t get 0 events going back. Win32 has the minimum-that-passed-CI, setjmp() impl, written for the "C abtract VM" and not a real win32 proc.
I dont see any way around this, except to sample the very proprietary "OS cur tid ", and keep it next to each jmpbuf_t struct, on every OS. perhaps even on no-threads perl, because no-threads perl can still be moved between OS threads (synchronously/safe and blocking-ish).
Perl's Configure needs logic to detect C stack grows up, down, or is a pure voodoo linked list malloc implementation. I can't think of any other way to detect "higher" former-C call stack frames that are now uninit memory Because someone threw a C++ exception but didnt kill the process yet.
In addition to the big 3 (Win/Lin/OSX) [# 2 android, # 3BSD], how do we support all the unix, esp commercial unixes, or dont? the posix world isn't entirely libpthreads.so or go home.
Callstacks with test # 1, the "sleeper" proc, RtlRaiseStatus() was passed error code 0xC0000028 STATUS_BAD_STACK, and generated a long crash callstack insite active running OS this # 2.
ntdll.dll!RtlRaiseStatus�()
ntdll.dll!string "Enabling heap debug options\n"�()
ntdll.dll!RtlUnwind�()
vcruntime140.dll!__longjmp_internal() Line 141
perl541.dll!Perl_die_unwind(interpreter * my_perl, sv * msv) Line 2108 C++
perl541.dll!Perl_croak_sv(interpreter * my_perl, sv * baseex) Line 1856 C++
perl541.dll!Perl_die_sv(interpreter * my_perl, sv * baseex) Line 1775 C++
perl541.dll!Perl_pp_die(interpreter * my_perl) Line 639 C++
perl541.dll!Perl_runops_standard(interpreter * my_perl) Line 41 C++
perl541.dll!Perl_call_sv(interpreter * my_perl, sv * sv, long arg_flags) Line 3236 C++
setcxt_pl_4840.dll!newRunner(void * p) Line 17 C++
kernel32.dll!BaseThreadInitThunk�()
ntdll.dll!RtlUserThreadStart�()
The infinity sleep root thread
ntdll.dll!NtDelayExecution�()
KernelBase.dll!SleepEx()
setcxt_pl_4840.dll!switch_osthd(unsigned __int64 test) Line 46 C++
setcxt_pl_4840.dll!XS_main_switch_osthd(interpreter * my_perl, cv * cv) Line 62 C++
[Inline Frame] perl541.dll!Perl_rpp_invoke_xs(interpreter *) Line 1177 C++
perl541.dll!Perl_pp_entersub(interpreter * my_perl) Line 6529 C++
perl541.dll!Perl_runops_standard(interpreter * my_perl) Line 41 C++
perl541.dll!S_run_body(interpreter * my_perl, long oldscope) Line 2885 C++
perl541.dll!perl_run(interpreter * my_perl) Line 2798 C++
perl541.dll!RunPerl(int argc, char * * argv, char * * env) Line 206 C++
[Inline Frame] perl.exe!invoke_main() Line 78 C++
perl.exe!__scrt_common_main_seh() Line 288 C++
kernel32.dll!BaseThreadInitThunk�()
ntdll.dll!RtlUserThreadStart�()
Test # 2 is less interesting, root thread is on purpose gone/dealloced already by the time of the crash.
Unhandled exception thrown: read access violation.
my_perl->Itop_env was 0x2AFD30.
If there is a handler for this exception, the program may be safely continued.
perl541.dll!Perl_call_sv(interpreter * my_perl, sv * sv, long arg_flags) Line 3170 C++
setcxt_pl_d3cd.dll!newRunner(void * p) Line 17 C++
kernel32.dll!BaseThreadInitThunk�()
ntdll.dll!RtlUserThreadStart�()
Steps to Reproduce
Change for your OS.
use Inline 'noclean';
use Inline C => Config =>
PRE_HEAD => '#define PERL_NO_GET_CONTEXT 1',
;
use Inline C => Config => BUILD_NOISY => 1;
use Inline C => <<'END_OF_C_CODE';
static DWORD WINAPI newRunner(LPVOID p) {
void ** pa = (void **)p;
dTHXa(pa[0]);
PERL_SET_CONTEXT(aTHX);
Sleep(500);
{
dSP;
PUSHMARK(SP);
PUTBACK;
call_pv("do_die", G_DISCARD);
croak(" unreachable !!!! ");
ExitThread(1);
}
return 1;/*silence*/
}
void switch_osthd(UV test) {
dTHX;
void * parr[3]; // future, [1] maybe a mutex to sleep on, [2] IDK what
HANDLE thd;
parr[0] = (void *)aTHX;
warn("entered xsub switch_osthd() with test type %" UVf "\n", test);
thd = CreateThread(NULL,0,newRunner,(LPVOID)&parr,0,NULL);
CloseHandle(thd); //or WFSO() on it??
if(test == 1)
Sleep(INFINITE);
else if(test == 2)
ExitThread(0);
else if(test == 3)
croak("good croak from XS switch_osthd()");
else
croak("XS switch_osthd(): arg 1 'UV test' test_type unknown");
}
END_OF_C_CODE
sub do_die {
warn "entered sub do_die {} ";
die "throwing the die";
}
{ my $died = eval { switch_osthd(2); };#test type, only values 1 or 2 or 3 allowed
warn( (!defined($died) ? "did get (ok)" : "did not get (bad)")
." a die(), \$@=$@"
);
}
Expected behavior
Throwing a PP perl exception after an ithread/my_perl was detached/attached to another OS thread, using perlembed.pod's public API, will print a "panic :" to console+exit process, not a SEGV popup that 90% of users can't diagnose. Separating P5P bugs from CPAN XS bugs is #2 priority. Example of an ancient P5P caused crash/panic, https://www.perlmonks.org/?node_id=331565 and also this #10441 for CPAN/community bugs google top_env perl
.
PP->CPAN XS->C++ "bsearch"->CPAN XS->PP->CPAN XS->C++ std::SomeClass->C++ exception\|/
/|\---------------------------------------------------------------------------------------------------
also needs to be detected/fatal console error/"silently" "fix it" and "continue execution" C-wise (PERL_FLEXIBLE_EXCEPTIONS), because that C problem was fixed and is now a high level $@
scalar / PP die() exception object.
Perl configuration
Summary of my perl5 (revision 5 version 41 subversion 7) configuration:
Derived from: 73172a67eaae5671dffc06b427f005810d151472
Platform:
osname=MSWin32
osvers=6.1.7601
archname=MSWin32-x64-multi-thread
uname=''
config_args='undef'
hint=recommended
useposix=true
d_sigaction=undef
useithreads=define
usemultiplicity=define
use64bitint=define
use64bitall=undef
uselongdouble=undef
usemymalloc=n
default_inc_excludes_dot=define
Compiler:
cc='cl'
ccflags ='-nologo -GF -W3 -MD -TP -EHsc -std:c++20 -DWIN32 -D_CONSOLE -DNO_S
TRICT -DWIN64 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_WINSOCK_
DEPRECATED_NO_WARNINGS -DPERL_TEXTMODE_SCRIPTS -DMULTIPLICITY -DPERL_IMPLICIT_SY
S -DWIN32_NO_REGISTRY -DUSE_PERLIO'
optimize='-O1 -Zi -GL -fp:precise'
cppflags='-DWIN32'
ccversion='19.36.32535'
gccversion=''
gccosandvers=''
intsize=4
longsize=4
ptrsize=8
doublesize=8
byteorder=12345678
doublekind=3
d_longlong=undef
longlongsize=8
d_longdbl=define
longdblsize=8
longdblkind=0
ivtype='__int64'
ivsize=8
nvtype='double'
nvsize=8
Off_t='__int64'
lseeksize=8
alignbytes=8
prototype=define
Linker and Libraries:
ld='link'
ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf -ltcg -libpath:"c:\pb64\
lib\CORE" -machine:AMD64 -subsystem:console,"5.02"'
libpth="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSV
C\14.36.32532\\lib\x64"
libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.li
b advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_32.l
ib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
vcruntime.lib ucrt.lib
perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg3
2.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_
32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt
.lib vcruntime.lib ucrt.lib
libc=ucrt.lib
so=dll
useshrplib=true
libperl=perl541.lib
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_win32.xs
dlext=dll
d_dlsymun=undef
ccdlflags=' '
cccdlflags=' '
lddlflags='-dll -nologo -nodefaultlib -debug -opt:ref,icf -ltcg -libpath:"c:
\pb64\lib\CORE" -machine:AMD64 -subsystem:console,"5.02"'
Characteristics of this binary (from libperl):
Compile-time options:
HAS_LONG_DOUBLE
HAS_TIMES
HAVE_INTERP_INTERN
MULTIPLICITY
PERLIO_LAYERS
PERL_COPY_ON_WRITE
PERL_DONT_CREATE_GVSV
PERL_HASH_FUNC_SIPHASH13
PERL_HASH_USE_SBOX32
PERL_IMPLICIT_SYS
PERL_MALLOC_WRAP
PERL_OP_PARENT
PERL_PRESERVE_IVUV
PERL_USE_SAFE_PUTENV
USE_64_BIT_INT
USE_ITHREADS
USE_LARGE_FILES
USE_LOCALE
USE_LOCALE_COLLATE
USE_LOCALE_CTYPE
USE_LOCALE_NUMERIC
USE_LOCALE_TIME
USE_NO_REGISTRY
USE_PERLIO
USE_PERL_ATOF
USE_THREAD_SAFE_LOCALE
Locally applied patches:
uncommitted-changes
Built under MSWin32
Compiled at Dec 20 2024 10:03:46
@INC:
C:/pb64/site/lib
C:/pb64/lib
This IRC log was trimmed and paraphrased, except for my lines, but contains more of the details on setjmp/P_S_C(), and ways to fix.
<bulk88> hmm, was doing archaeology, PERL_FLEXIBLE_EXCEPTIONS (libc.setjmp() -> Linux GCC C++ try{}/catch{} [really ISO C++ spec's try{}/catch{}])
<bulk88> Looking at PERL_SET_CONTEXT()/Perl_set_context(), what invalidates all the longjmp_buf_t'es on the PP scope stack, if the perl proc, switches OS threads? An XS mod or embedder did it using public P5 API.
<> Yeah, try/catch sounds a little too tight for what we need to do
<bulk88> Im more thinking about MS's plain C SEH API, Win32/64 Perl is already compatible with it (no weird JIT), MS's setjmp()/longjmp() already unwind C++ frames and Dtor C++ objs if any in a Perl proc, and setjmp()/longjmp() are SEH internally anyway
<bulk88> I can't find the bug tickets/ML posts b/c google link rot, but I think PERL_FLEXIBLE_EXCEPTIONS died, b/c core's Perl_set_context() forgot to wipe/invalidate flag, all the jumbuf_t'es
<bulk88> and the interp interestingly, refuses to EVER recording an integer called "tid" lol
<bulk88> a jmpbuf_t is uninit memory without recording the thread_id it was sampled with, if the app/proc/framework/code base permits creating OS threads
<> Probably because an interpreter can switch threads. Most famously it actually does during thread startup
<> S_ithread_create in threads.xs
<bulk88> right, so P_S_C() must push XSomething onto a stack, saying all jmpbuf_t'es before save_stack_ix_foo, are temp invalid (untrap print panic and exit proc), along with the new OS thread_id
<bulk88> perl core has no way of knowing if the old OS thread is suspended timeslots until X minutes/hours later, or old OS thread was freed, along with its C stack
<bulk88> webservers, thread pooling, a GUI/TUI IDE with 2 plugins in 1 OS proc, both plugins using libperl, and both plugins are unaware of each other
<bulk88> Coro/Lehman's frameworks too
<bulk88> my test case I randomly thought of, what stops the interp/core, when doing a eval{} die("");, from SEGVing, or what interp code, makes doing a cross OS thread, PP code " eval{}; die("");" actually safe?
<bulk88> https://perldoc.perl.org/perlembed#Performing-Perl-pattern-matches-and-substitutions-from-your-C-program
<bulk88> perlembed also cargo cult-ed a ticking timebomb, of running the interp instance, without a eval/die/setjmp frame of last resort
<bulk88> text = newSV(0);
<bulk88> sv_setpv(text, "When he is at a convenience store and the ");
<bulk88> perlembed's sample code, from C main(), called sv_setpv() and documented the entire public API, func wise, can execute without a PP eval frame of last resort
<bulk88> even if perl_parse()/perl_run() are good citizens, SvPV() and SvIV() don't set up PP eval frames
<bulk88> I've thought for years, PERL_SYS_INIT3 macro needs a secret setjmp() in it. Since a PERL_SYS_INIT/PERL_SYS_TERM pair, look perfect to slide in, secret MS C89 try{}/catch{} syntax if Perl's setjmp() exceptions are ever turned into formal MS-C89 SEH exceptions.
<bulk88> seems perl always guarded against an embedded without a PP eval frame, see https://github.com/Perl/perl5/blob/blead/cop.h#L61
<bulk88> but "panic: top_env" in STDERR, in the console, is a terrible diag message, and it doesn't instantly separate P5P bugs, vs end user's/cpan's problem bugs, since an embedder's C main() frame doesnt have a specific "its the embedder" indentity
<bulk88> also https://github.com/Perl/perl5/blob/blead/cop.h#L163 JMPENV_JUMP(arg1) doesn't have any protection against jumping into a future/deeper/now-invalid/former C stack frame, b/c unbalanced POP/PUSHes in CPAN XS or CORE
<bulk88> doing the highly illegal crime, of recording abs pointers of C stack args, saving those pointers into perl's jmpenv_t, along with current TID, should be done
<bulk88> note that comparing &c_stk_args, is a war crime in C abstract VM, since C doesn't define if the C stack grows upwards or downwards as an int, or the C stack is a linked list of malloc blocks, but maybe its time to break the law vs a SEGV
<bulk88> and C++ code can silently throw/jmp through P5P controlled, and 3rd party code
<> bulk88: how hard is it to make test cases that demonstrate this is really broken?
<bulk88> https://lists.mimedefang.org/pipermail/mimedefang_lists.mimedefang.org/2010-February/115850.html
<bulk88> https://github.com/perl/perl5/issues/8975
<bulk88> https://www.perlmonks.org/?node_id=368099
<bulk88> the community has triggered "panic: top_env" many times, P5P bugs, or their own XS bugs
<> bulk88: are those cases entered into core perl tests?
<shadowpaste> "bulk88" at pasted "Perl_set_context() OS Thd CHAOS example" (61 lines) at http://paste.scsys.co.uk/RMVED
<dipsy> [ magnet_web paste from "bulk88" at ... ]
<bulk88> play around with the sample or port it to pthreads, only real gonna crash tests are UV 1 and UV 2
<> if these things can crash perl, can they be tested and, maybe, fixed?
<bulk88> test UV 1 models a "most innocent" "most accidental" bug, UV 2 is models a high throughput production "nginix" / "apache" threadpool bug
<bulk88> "crash perl, they should be captured in tests and, maybe, fixed?" IIRC its forbidden for P5P self make test, to "prove" the interp core dump/SIGBUS/SEGV as a test pass
<bulk88> supposedly some platforms/various community CI builders, hate that since it creates many 100MBs dump files in /home, that perl doesn't know about
<> my thinking was the SEGV would be prevented
<bulk88> fixing Perl_set_context(), I sorta can think of some improvements, I can definently make Perl_set_context() bulletproof on Win32, but theres alot of portability and new XS public/p5 private API design problems
<bulk88> a big one is, P5P perl currently has no idea what "int thread_id" is in a posix or any os portable way
<> do you have an idea?
<> how does cpython deal with this?
<bulk88> #include "pthreads.h" on "Unix" is as proprietary as #include "windows.h", since "int thread_id" is completely alien to POSIX and libc
<bulk88> https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_self.html
<> ah, 'pthread_t' right?
<bulk88> pthread_t pthread_self(void)
<bulk88> is maximum "not a portable" spec as you can get, or just call it Linux proprietary
<> well, that's a POSIX doc & spec, not linux
<> does windows have an equivalent?
<bulk88> python has the GIL, its illegal to transfer control to libpython.so from 2 simul OS threads
<bulk88> IDK if cpython uses setjmp() or ever samples CPU registers as normal control flow (
<bulk88> pthread_t pthread_self(void)) is GetCurrentThreadId() on Win32,
<> is there a way to define `PerlOSThreadId_t` for each of those?
<bulk88> GetCurrentThreadId() internally is exactly 3 x86 CPU ops, just 3x pointer derefs, stupid cheap, stupid fast, its the FS/GS registers, just like a sane pthreads lib on Linux
<> you're saying it's expensive on linux?
<bulk88> PerlOSThreadId_t? yes you can, but each P5 platform, will need a volunteer to add the backend, and the boogie man is, what about ithreads-not-supported Unix'es? like if Configure reports OS threads not avail, but that weird commercial Unix, really does have OS threads
<bulk88> a no-threads-libperl, can still get moved between OS threads by someone's code
<> my thought for that type would just be to generalise between POSIX and Windows threads, no more. if the platform doesn't have one of those, nothing to be done, nothing lost
<bulk88> Win32/Linux/OSX are 98% of the world ATM, android is Linux and FreeBSD is OSX
<bulk88> its only VMS/AIX/solaris/hpux/etc that have problems
<bulk88> https://github.com/search?q=repo%3Alattera/glibc%20THREAD_SELF&type=code
<bulk88> pthread_self(() is asm code on all (almost?) all pthread CPUs/Unixes
<> ok, i'm not seeing why that matters here?
<bulk88> so extreme fast and cheap, not a kernel call
<> i'm sure it does! just not comprehending
<bulk88> PerlOSTID_t for rare commercial Unixes is more of a wishlist/trollist/close the bug ticket thing than a push to blead blocker
<> what is the problem that means Perl can't stop some/all of these SEGVs?
<bulk88> exotic unix will keep SEGVing just like current situation, but 98% of users will get a panic message instead a segv
<bulk88> which is a huge improvement
<> sometimes one has to give up, but a good error message is worth a lot
<bulk88> also im not qualified to answer the security/exploit question of, are PIDs/TIDs randomized enough to be secure anti-repeat values, after the PID/TID is "freed" at kernel/backend/libc front end level?
<bulk88> if a PID/TID is like a unix FD, which struggles to get above int 10 or int 30, and instantly get reused, they aren't indentifiers of anything
<bulk88> if after a posix waitpid(), does the spec allow the XYZ Posix kernel to instantly reissue the PID value for the next process created on that box?
<> "POSIX prohibits the re-use of a process ID where a process group with that identifier still exists"
<bulk88> IDK enough internals of posix, my knowledge ends at, kernel metadata and the pid will stay around forever until some process executes C func waitpid()
<bulk88> http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/kern/kern_fork.c.diff?r1=1.7&r2=1.8&f=h
<bulk88> prior to 1997 OpenBSD had "insecure PIDs"", insecure is self declared
<bulk88> these segvs are 99% caused by non p5p code, since threads.xs and psuedofork are tested to death/well maintained as is by p5p
<> of course, there's only so much one can do to stop people crashing their programs
<bulk88> IMHO, thread_id capture only covers 50% of segv risks, perl has to do C stack position capture also, so its impossible to jump into a ex-deeper-now_uninit memory C stack frame
<bulk88> perl 5 can't ask for C++ automatic dtor execution, when c++ autos go out of scope
<> is there anything it *could* do towards that?
<bulk88> thats the bullet proof way, to make sure a C89/99/c++ return can never leave a perl jmpenv_t snapshot half-alive
<> how would it do so?
<bulk88> I can think of ways, but the tomato throwing mob, will protest capturing and comparing positions on the C stack
<bulk88> and HPUX's C stack grows numerically upward like perl's @_ stack, while everything else grows numerically down
<bulk88> "grows numerically down" is so ISO C func arguments, and va_start() ... and friends, can blind cast between void ** type and a va_args_t type
<bulk88> and my_call(5,4,3,2,1); stays as execution order in ISO C
<bulk88> va_start() va_end() va_copy() might be internally doing a malloc() and flipping around all the C stack args, without a C dev knowing
<bulk88> alien random pure C libs, accepting user C callback fns, and the alien C lib itself doing setjmp()/longjmp(), zero integration with perl, its extremely scary to me
<bulk88> same for C++ try catch frames, perl is unaware of C++ and C++ is unaware of setjmp(), and spec authors decided, "user error, get the malware [from cpan or apt-get] out of your process"
<bulk88> https://linux.die.net/man/3/dlopen is not part of ISO C or C++, RFC ticket rejected
<> there's probably a few who'd agree C++ is malware
<bulk88> there is a large opinion in GNU/BSD core C lib projects, that the user compiled his own executable process, and has 100% full control over all code except for glibc.so in his virtual memory space
<bulk88> plugin architectures like perl 5, and .so files are too unprofessional to entertain supporting
<bulk88> "if you can't debug C code, or step debug a linux kernel driver, you should hire a professional to operator your new PDP-11"
<bulk88> if a certain family member was at home, I wouldve put a photo right now of a pdp-11 assembly book and the camel book, the DAT tapes are somewhere also with the source code
<bulk88> MS CRT's setjmp() internally captures 11 vanilla general purpose CPU regs, &(jmp_buf* Buf), &(((void**)(Buf))[-1]), SSE MCREG (master control reg 64b), x87 legacy MCREG 64b, 10 128bit SSE regs, return; /* 's */
<bulk88> 00xF0 or 0xFF bytes of CPU registers on AMD64
<bulk88> public API MS CRT's longjmp, internaly sanity checks that, previously captured ptr "&(jmp_buf* Buf)", is between the current OS thread's C stack's 4096-byte-units start address, and dynamically stretched/grown current 4096-byte-unit end address
<bulk88> "end address" will ALWAYS BE UNINIT memory, end address is the last/highest currently alloced 4KB page in the current Win32 OS thread's C stack pre-reserved range, so bounds checking anything against that 4096-aligned address, isn't that safe, because 0-4096 bytes worth of FUTURE C stack frames, are always garbage bytes.
<bulk88> If the user passed jmpbuf_t *, fails the security bounds test, IE Perl 5 and Perl_set_context() drama
<bulk88> MS Libc basically will do a SEGV, and pop up the Windows GUI segv box, nobody will learn the real error code unless they attach a C debugger and learn its "SIG __fastfail(0xd) " not a SEGV/BUS/ILL
<bulk88> if jmpbuf_t * passes sanitizing checks, longjmp() fires STATUS_LONGJMP 0x80000026 exception objects at all SEH frame objects, until those SEH objects are freed
<bulk88> IDK how C89 exception object 0x80000026 shows up in ISO C++
<bulk88> after all C++/SEH frames are nuked, 10+2+11 CPU regs are restored, and JMP op back to Perl/XS
<bulk88> MS's/Win32's setjmp()/longjmp() is too dangerous in anything production/realistic, b/c longjmp() sends "events" to all C++ objects, but C++ and MS C89/99/23 SEH don't send "events" to setjmp()
<bulk88> MS's/Win32's setjmp()/longjmp() was written to pass the CI test suite, for "C99/C23 abstract virtual machine" and nothing else
<bulk88> switch (PerlProc_setjmp(cur_env.je_buf, SCOPE_SAVES_SIGNAL_MASK)) {
<bulk88> case 0: cur_env.je_ret = 0; break;
<bulk88> default: Perl_croak(aTHX_ "panic: unexpected setjmp() result\n");
<bulk88> }
<bulk88> very little to change in generic P5 core, to replace setjmp with SEH frames, if P5 ever gets any kind of exception object, in ()'es of catch(){} the message is already sitting there
<bulk88> I dont think its sane to continue the process, or repair the "process state" if private/CPAN XS called into a C++ lib that threw a C++ object, game over, you lost.
<bulk88> if that XS mod, was buggy/too beta-ish, to remember to capture C++ exceptions, when that XS mod fully knows its calling "::" C++ functions, there isn't anyway for the perl proc to continue
<> bulk88: makes sense, thank you
<> it's a pity perl can't engage in that C++ bit though