Skip to content

t/DynaLoader.t and DynaLoader::dl_unload_file() are SEGVing, are they right, or libperl is right and they are broken? #23406

@bulk88

Description

@bulk88

Module: DynaLoader

Description

This is a race condition SEGV [*inaccurate, keep reading] I somehow triggered, or a .t that was doing crazy bad innovative things. I've never seen it before in my life and have no idea what the fix would inside the Perl VM. There are 2 different APIs/files of that can be at fault, and only 1 of 2 files can be "broken" or "wrong" or "responsible" for being "defective". Not both files. Its either A or B that needs fixes. IDK which one is guilt.

The crash happened because the [*inaccurate, see very end] DynaLoader:: API's destructor/DESTROY/END/libc at_exit()/libperl Perl_at_exit(), fired, and unloaded my XS DLL from address space, before the Perl VM got around to firing my \&main::Socket::END XSUB during global destruction. I know global destruction phase is completly random what objects/PP dtors/C level dtors fire in what order.

The location of the crash was at https://github.com/Perl/perl5/blame/5fa00eaee8c35ee39c06df498d522dd07d2fce4c/inline.h#L1176 because

CV* field at crash site is

	cv->sv_any->xcv_root_u.xcv_xsub	0x000007fef33a2cc0	void(*)(interpreter *, cv *)

and holds a function pointer to an unmapped address, causing the SEGV. "2cc0" is the former address of my Socket.xs's new XS_Socket_END function inside the formerly mapped Socket.dll image.

.text:0000000180002CC0 ; void XS_Socket_END(interpreter *my_perl, cv *cv)
.text:0000000180002CC0 XS_Socket_END   proc near
.text:0000000180002CC0                 mov     rax, [rcx+0E68h]
.text:0000000180002CC7                 add     qword ptr [rcx+70h], 0FFFFFFFFFFFFFFFCh
.text:0000000180002CCC                 movsxd  rcx, cs:my_cxt_index
.text:0000000180002CD3                 mov     rcx, [rax+rcx*8]
.text:0000000180002CD7                 and     qword ptr [rcx], 0
.text:0000000180002CDB                 retn
.text:0000000180002CDB XS_Socket_END   endp

Crash call stack from C.

>	000007fef33a2cc0()	Unknown
 	[Inline Frame] perl543.dll!Perl_rpp_invoke_xs(interpreter *) Line 1176	C
 	perl543.dll!Perl_pp_entersub(interpreter * my_perl) Line 6553	C
 	perl543.dll!Perl_runops_standard(interpreter * my_perl) Line 41	C
 	perl543.dll!Perl_call_sv(interpreter * my_perl, sv * sv, long arg_flags) Line 3254	C
 	perl543.dll!Perl_call_list(interpreter * my_perl, long oldscope, av * paramList) Line 5323	C
 	perl543.dll!perl_destruct(interpreter * my_perl) Line 676	C
 	perl543.dll!RunPerl(int argc, char * * argv, char * * env) Line 220	C++
 	[Inline Frame] perl.exe!invoke_main() Line 78	C++
 	perl.exe!__scrt_common_main_seh() Line 288	C++
 	kernel32.dll!BaseThreadInitThunk�()	Unknown
 	ntdll.dll!RtlUserThreadStart�()	Unknown

the values inside PL_curcop, at the crash location says I am at (line is junk/weird value of 0, IDK why)

	my_perl->Icurcop->cop_line	0x00000000	unsigned long
	my_perl->Icurcop->cop_file	0x0000000000272608 "t/DynaLoader.t"	char *

reading through https://github.com/Perl/perl5/blob/blead/ext/DynaLoader/t/DynaLoader.t

I see this very very fascinating test

my $r = eval { DynaLoader::dl_unload_file($libref) };

which executes the DynaLoader::dl_unload_file() XSUB which is burned into my perl543.dll file.

DynaLoader::dl_unload_file() on Win32 obviously is Perl's PP front end to Microsoft's C level FreeLibrary() function.

https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-freelibrary

And perhaps this bug ticket is excellent human dev verification CV* DynaLoader::dl_unload_file(); work perfectly as designed, and t/DynaLoader.t does not have any bugs in its code.

So that probably explains how my Socket.dll disappeared from address space before CV* Socket::END holding an XSUB func ptr executed.

At the crash point, here is a list of all DLLs still mapped in address space. "File\Glob\Glob.dll" is the last and only Perl XS DLL still in address space at the crash point.

advapi32.dll	advapi32.dll	C:\Windows\System32\advapi32.dll	000007FEFD6C0000-000007FEFD79B000	Symbols loaded without source information.
api-ms-win-core-file-l1-2-0.dll	api-ms-win-core-file-l1-2-0.dll	C:\Windows\System32\api-ms-win-core-file-l1-2-0.dll	000007FEF7AA0000-000007FEF7AA3000	Symbols loaded without source information.
api-ms-win-core-file-l2-1-0.dll	api-ms-win-core-file-l2-1-0.dll	C:\Windows\System32\api-ms-win-core-file-l2-1-0.dll	000007FEF7AD0000-000007FEF7AD3000	Symbols loaded without source information.
api-ms-win-core-localization-l1-2-0.dll	api-ms-win-core-localization-l1-2-0.dll	C:\Windows\System32\api-ms-win-core-localization-l1-2-0.dll	000007FEF7AC0000-000007FEF7AC3000	Symbols loaded without source information.
api-ms-win-core-processthreads-l1-1-1.dll	api-ms-win-core-processthreads-l1-1-1.dll	C:\Windows\System32\api-ms-win-core-processthreads-l1-1-1.dll	000007FEF7AB0000-000007FEF7AB3000	Symbols loaded without source information.
api-ms-win-core-synch-l1-2-0.dll	api-ms-win-core-synch-l1-2-0.dll	C:\Windows\System32\api-ms-win-core-synch-l1-2-0.dll	000007FEFC440000-000007FEFC443000	Symbols loaded without source information.
api-ms-win-core-timezone-l1-1-0.dll	api-ms-win-core-timezone-l1-1-0.dll	C:\Windows\System32\api-ms-win-core-timezone-l1-1-0.dll	000007FEF7AE0000-000007FEF7AE3000	Symbols loaded without source information.
api-ms-win-crt-convert-l1-1-0.dll	api-ms-win-crt-convert-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-convert-l1-1-0.dll	000007FEF4590000-000007FEF4594000	Symbols loaded without source information.
api-ms-win-crt-environment-l1-1-0.dll	api-ms-win-crt-environment-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-environment-l1-1-0.dll	000007FEE12A0000-000007FEE12A3000	Symbols loaded without source information.
api-ms-win-crt-filesystem-l1-1-0.dll	api-ms-win-crt-filesystem-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-filesystem-l1-1-0.dll	000007FEE1A50000-000007FEE1A53000	Symbols loaded without source information.
api-ms-win-crt-heap-l1-1-0.dll	api-ms-win-crt-heap-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-heap-l1-1-0.dll	000007FEF4A60000-000007FEF4A63000	Symbols loaded without source information.
api-ms-win-crt-locale-l1-1-0.dll	api-ms-win-crt-locale-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-locale-l1-1-0.dll	000007FEE3610000-000007FEE3613000	Symbols loaded without source information.
api-ms-win-crt-math-l1-1-0.dll	api-ms-win-crt-math-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-math-l1-1-0.dll	000007FEE1290000-000007FEE1295000	Symbols loaded without source information.
api-ms-win-crt-process-l1-1-0.dll	api-ms-win-crt-process-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-process-l1-1-0.dll	000007FEFAAC0000-000007FEFAAC3000	Symbols loaded without source information.
api-ms-win-crt-runtime-l1-1-0.dll	api-ms-win-crt-runtime-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-runtime-l1-1-0.dll	000007FEF6340000-000007FEF6344000	Symbols loaded without source information.
api-ms-win-crt-stdio-l1-1-0.dll	api-ms-win-crt-stdio-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-stdio-l1-1-0.dll	000007FEF4710000-000007FEF4714000	Symbols loaded without source information.
api-ms-win-crt-string-l1-1-0.dll	api-ms-win-crt-string-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-string-l1-1-0.dll	000007FEF4970000-000007FEF4974000	Symbols loaded without source information.
api-ms-win-crt-time-l1-1-0.dll	api-ms-win-crt-time-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-time-l1-1-0.dll	000007FEE1A40000-000007FEE1A43000	Symbols loaded without source information.
api-ms-win-crt-utility-l1-1-0.dll	api-ms-win-crt-utility-l1-1-0.dll	C:\Windows\System32\api-ms-win-crt-utility-l1-1-0.dll	000007FEE1280000-000007FEE1283000	Symbols loaded without source information.
comctl32.dll	comctl32.dll	C:\Windows\winsxs\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.24483_none_e372d88f30fbb845\comctl32.dll	000007FEFB890000-000007FEFBA85000	Symbols loaded without source information.
gdi32.dll	gdi32.dll	C:\Windows\System32\gdi32.dll	000007FEFD650000-000007FEFD6B7000	Symbols loaded without source information.
Glob.dll	Glob.dll	C:\sources\perl5\lib\auto\File\Glob\Glob.dll	000007FEF2580000-000007FEF258A000	Symbols loaded.
imm32.dll	imm32.dll	C:\Windows\System32\imm32.dll	000007FEFDE80000-000007FEFDEAE000	Symbols loaded without source information.
kernel32.dll	kernel32.dll	C:\Windows\System32\kernel32.dll	00000000774D0000-00000000775EF000	Symbols loaded without source information.
KernelBase.dll	KernelBase.dll	C:\Windows\System32\KernelBase.dll	000007FEFD340000-000007FEFD3A7000	Symbols loaded without source information.
lpk.dll	lpk.dll	C:\Windows\System32\lpk.dll	000007FEFF600000-000007FEFF60E000	Symbols loaded without source information.
msctf.dll	msctf.dll	C:\Windows\System32\msctf.dll	000007FEFF300000-000007FEFF40B000	Symbols loaded without source information.
msvcrt.dll	msvcrt.dll	C:\Windows\System32\msvcrt.dll	000007FEFD7A0000-000007FEFD83F000	Symbols loaded without source information.
nsi.dll	nsi.dll	C:\Windows\System32\nsi.dll	000007FEFF5D0000-000007FEFF5D8000	Symbols loaded without source information.
ntdll.dll	ntdll.dll	C:\Windows\System32\ntdll.dll	00000000776F0000-000000007788F000	Symbols loaded without source information.
perl.exe	perl.exe	C:\sources\perl5\t\perl.exe	000000013F6C0000-000000013F6C8000	Symbols loaded.
perl543.dll	perl543.dll	C:\sources\perl5\t\perl543.dll	000007FEE9EA0000-000007FEEA1D1000	Symbols loaded.
rpcrt4.dll	rpcrt4.dll	C:\Windows\System32\rpcrt4.dll	000007FEFE360000-000007FEFE48C000	Symbols loaded without source information.
sechost.dll	sechost.dll	C:\Windows\System32\sechost.dll	000007FEFF410000-000007FEFF42F000	Symbols loaded without source information.
shlwapi.dll	shlwapi.dll	C:\Windows\System32\shlwapi.dll	000007FEFF760000-000007FEFF7D1000	Symbols loaded without source information.
ucrtbase.dll	ucrtbase.dll	C:\Windows\System32\ucrtbase.dll	000007FEF7AF0000-000007FEF7BE4000	Symbols loaded without source information.
user32.dll	user32.dll	C:\Windows\System32\user32.dll	00000000775F0000-00000000776EB000	Symbols loaded without source information.
usp10.dll	usp10.dll	C:\Windows\System32\usp10.dll	000007FEFF690000-000007FEFF75B000	Symbols loaded without source information.
vcruntime140.dll	vcruntime140.dll	C:\Windows\System32\vcruntime140.dll	000007FEE1FF0000-000007FEE200D000	Symbols loaded.
vcruntime140_1.dll	vcruntime140_1.dll	C:\Windows\System32\vcruntime140_1.dll	000007FEF44D0000-000007FEF44DC000	Symbols loaded without source information.
ws2_32.dll	ws2_32.dll	C:\Windows\System32\ws2_32.dll	000007FEFD600000-000007FEFD64D000	Symbols loaded without source information.

I have no idea how to go forward.

IDC what the short term solution is. I have to do something to stop the SEGV that ext/DynaLoader/t/DynaLoader.t is currently doing on purpose so Socket.xs can have a MY_CXT struct. And none of my ideas or fixes are short term solutions I can actually use today/tomorrow.


If you, the reader know the best fix, stop reading now, and just reply what you think it is. I dont have any realistic fixes in my head that I can use right now.


historical Backstory and research of P5P ppl vs XSUB DynaLoader::dl_unload_file();

Nicholas Clark in ancient history did alot of interactions and experiments talking about DynaLoader::dl_unload_file(); and how it is evil. The exact post from NC that is in my head, has disappeared from public record. TPF deleted all grant reports prior to 2015, so grant reports from any mid or late 2000s are gone.

But NC said something like "After a ton of work and effort on my part, I have determined Perl will never support [as part of P5P public API] unloading an XS shared library from the interpreter prior to process termination. I'm moving on to other things now."

the closest things I found to the NC post that I have in my head is this

https://news.perlfoundation.org/post/improving_perl_5_grant_report_9

https://groups.google.com/g/perl.perl5.porters/c/Xd_KDiETUSE/m/Zp2ohNZCxKoJ

relink from above #13186

https://groups.google.com/g/perl.perl5.changes/c/3J_5ksXVV9A/m/5L-YrtXB5cMJ

relink from above fbe4ac3

FC makes a new API to fix my SEGV in ancient history.

But commit that creates a new bespoke, 1 off API, as a fix, for my SEGV bug in this ticket, for 1 particular XS module, by name (File::Glob), that no other XS module is allowed to use.

ed57bf8

https://groups.google.com/g/perl.perl5.porters/c/aUGc3msK_Kw/m/xrBpJhc3gR8J titled "newCONSTSUB_flags() fiddles with PL_curcop"

Usenet Post about WinPerl outside the normal Perl Ecosystem titled "DLL unload question for embedded Perl on Windows" from Nov 27, 2009, 5:46:30 AM

https://groups.google.com/g/comp.lang.perl.misc/c/N8i1mE_d9OQ/m/ZE3zLH2Cht0J

no intelligent content about DynaLoader::dl_unload_file(), just complaints about DynaLoader::dl_unload_file() in this thread titled "perl_parse memory leak with dynamic loaded modules"

https://groups.google.com/g/perl.xs/c/dZY_XRLkoXM/m/-vKKKN10RWYJ

A very engineering, very long, very technical SO post about Perl's DynaLoader:: and Linux OS's Kernel/ELF/userland runtime enviroment I stopped reading 1/4 of the way in.

It started to sound like Linux's ld.so does not, and never will, support unmapping a .so file from address space, so here is the very black shade of grey solution to runtime modifying the machine code inside ld.so and messing with its undocumented C structs.

https://stackoverflow.com/questions/46738256/can-i-use-a-module-and-later-unload-it-shrinking-the-optree

I'll take a pause now, there are 2 ways to fix this bug ticket. Declare t/DynaLoader.t is the bug, and edit t/DynaLoader.t to use another random core XS module to test DynaLoader::dl_unload_file().

Or declare the Perl Interp and DynaLoader.pm are the bug, and DynaLoader::dl_unload_file() has to be safe because DynaLoader::dl_unload_file() has a "API Contract" with Perl users, that it is "safe" to call at any time on any shared library handle DynaLoader.pm loaded into address space.

Its #1 or #2.

Easiest solution and shortest solution on earth in my head for #2 is the problem, is add the following code, use https://metacpan.org/release/ETHER/Devel-Gladiator-0.08/source/Gladiator.xs and start an iter loop, check each CV* if its marked XSUB, and match against a High/Low address range, representing the .so or .dll file about to be unmapped by DynaLoader::dl_unload_file(), and undef the CV* wiping the function pointer.

Now for the very hard and very long and slightly unrealistic solutions.

https://stackoverflow.com/questions/46738256/can-i-use-a-module-and-later-unload-it-shrinking-the-optree

This post I think towards the end says "Your PC, your machine, is your property. ld.so and Linux Kernel are also your property. They are open source. You can always make an ELF C symbol go back to Unresolved-Unlinked-state by rip apart ld.so's undocumented C structs and the PLT/GOT structs at runtime.

Ummm, well I like the idea, but Umm. Egh. No thank you if its my opinion. I've already implemented this for Windows privately, and it was no fun.

If anyone is interested I can donate the code to do this for WinPerl. The XSUB C function pointers still "work" at the same exact numerical address for the rest of the WinPerl's PID, but the XS .dll is long gone from the SSD SATA drive's disk sectors and long gone from the Windows paging file disk sectors, and long gone from physical DDR RAM.

This is too much generic design architecture of dynamic prog lang VM runtimes and not about DynaLoader.pm The code i have demap from address space the live mmaped .dll files, [not for WinPerl] zero their bytes on the FS disk, then [not for WinPerl] hard delete the .dll files from the SSD. I think I've privately shown the code to a couple of well known Perl+C WinPerl people in the past that mmaped disk files are always deleteable on the NT Kernel if you use Native API along with very high knowledge of the Win64's PE ABI.

All of this is done from inside the very same perl.exe process , that has a refcount on that .dll disk file, and without exiting the perl.exe process or proprietary process. Also, all function pointers, into the .dll will continue to work, but I can promise you wont find bytes on the SATA drive of the desktop anymore if you yank the SDD's SATA cable and plug into another PC.

Its technical C++ code right now, but I wrote it in psuedo-C99 and it would take 5 mins to make it valid C99 code.

I don't think the solution is appropriate for the Perl VM, since it would be a WinPerl only feature that benefits too few people, and to replicate it on POSIX basically requires a P5P dev to also be a Linux or FreeBSD/OSX kernel driver author, like the SO post implies.

That SO post is actually "production grade" safe. It doesn't sound crazy or unstable to me at all.

For example, I don't know the full details, but AFAIK, the Go Virtual Machine, has a Security Policy, to not allow any 3rd party machine code, into a Go process's virtual address space for any reason. All machine code in a Go process was created by the Go VM or Go developers (aka Google developers). GNU, FSF, Linux, Microsoft, Android, Solaris, FreeBSD, and NetBSD intellectual property is not allowed in a Go process. Just start reading this, it is crazy to me, that in 2025, the design of the GO VM is called "enterprise production grade" SW, just start scrolling and clicking around.

https://github.com/golang/go/tree/master/src/runtime

Go processes because of Go Co-routines, have no concept of "threads", "thread ids", "C stacks", "C function calls", C callstacks or C data or function linker symbols, and have no concept of C types "unsigned int" "int64_t" or "char".

https://go.dev/tour/concurrency/1

If a Go Co-routine wants to do a = assignment to a high level "int" variable it rewrites its own machine code or another Co-routines machine code holding the const literal "int" constant in executable memory.

Go Co-routine invoke other Go function calls, by doing https://en.wikipedia.org/wiki/Return-to-libc_attack or https://en.wikipedia.org/wiki/Return-oriented_programming on the return address of itself on the same CPU core, or for asyncronously atomic message passing, rewriting the return address of another Go routine on another CPU core.

The JavaScript Promises API, was implemented literally implemented in any-CPU-arch very fast and tiny CPU specific Assembly, and the Assembly code was written execute exactly how the high level JS Promises spec describes Promises will execute in the viewpoint of a JS developer.

Well, if Go corrupted and destroyed all concepts of Linux/BSD/Win64's "thread" "function call" and "stack".

"ld.so", "glibc.so", "kernel32.dll" and "ntdll.dll" are extremly dangrous files to be inside a Go Co-routine process. So Go directly executes Interrupt 0x21 or SYSENTER or BRANCH_TO_SUPERVISOR instructions itself.

I stopped reading the parts of https://github.com/golang/go/tree/master/src/runtime how a Linux Signal firing in an TLDR "empty" virt addr space works correctly and safely.

But good news, now WinPerl and Time::HiRes on Win32/64 can turn Perl's/Time::HiRes's gettimeofday() into 1 CPU instruction https://github.com/golang/go/blob/master/src/runtime/time_windows_amd64.s and its not crazy.

Microsoft's offset into that C struct with gettimeofday(), has been the same value, from March 31, 1992 thru Windows 11 right now. I'm calling that ABI frozen, Go devs also agree the struct/ABI is frozen.

Also I've long planned to fix thread WinPerl's rediculously slow Perl_get_context() function once and for all, to be exactly the same as my Debian Perl's Perl_get_context(), which is "pthread_specific_???()" something in Perl C code, but inside my libperl.so, C grammer tokens "Perl_get_context()" and "pthread_specific_???()" are just 3 or 4 CPU inline intrinsics builtins CPU opcodes. Not 450 CPU instructions like Perl_get_context() on WinPerl. MS's HeapFree() is only 120 CPU instructions for comparison. I need to finish the branch that converts miniperl.exe and no thread and yes threads perl.exe to directly call HeapAlloc() and HeapFree().

I've gotten miniperl.exe to finish a "gmake all" without SEGVing so far. But I have to make 9-12 PRs fixing goofy stupid illogical bugs where Perl is has triggered every single possible permutation of undefined behavior, against malloc()/realloc()/free(), listed in https://www.open-std.org/jtc1/sc22/wg14/www/docs/c99_drs.html times 2.

while(i < 79) {
free(realloc(malloc(0), ~0));
}

Stuff like ^^^^.

Its just easier for the Perl Interp or my_perl object, to have better book keeping of the toxic CV*s at runtime that came out of DynaLoader.pm and all other source code written in any language that criminally associates with the evil DynaLoader.pm module. Since DynaLoader.pm dragged those toxic CV* structs into Pure Perl Virtual Machine State, DynaLoader.pm is responsible for evicting them, RIGHT?

Basically, the solution for p5p/.git, should be written in plain ISO C code. Not JIT/Asm along with Ring 0/3 ABI magic.

https://metacpan.org/release/ETHER/Devel-Gladiator-0.08/source/Gladiator.xs solution and "match against a High/Low address range" is very difficult to solve in ISO Plain C, without asking Linux's /proc or /dev, or same Win32 APIs, "I have a pointer to a mmaped file, where is its start address and end address of the mmapping?"

It can be solved in ISO Plain C + XS + some minor changes to DynaLoader.pm/DynaLoader.xs, and I've partially prototyped this, which for all CV*s having flag CVf_ISXSUB 0x0008 on, turns CV* struct's CvFILE() into a RCed SV* ptr.

The half finished patch is more about stopping the crazy burn rate of 4K private byte pages caused by use POSIX;, because Perl_newCONSTSUB_flags() has a really really badly designed sub-API called

#define CVf_DYNFILE	0x1000	/* The filename is malloced  */

The rest of this possible but max complicated proposed fix I putting on the bottom. IDC what the short term solution is. I have to do something to stop the SEGV that ext/DynaLoader/t/DynaLoader.t is currently doing on purpose so Socket.xs can have a MY_CXT struct.

Steps to Reproduce

Add some thing like this

void
END(...)
    CODE:
        warn("hello world");
        /* skip implicit PUTBACK, returning @_ to caller, more efficient*/
        return;

to perl5\cpan\Socket\Socket.xs, recompile, then run ext/DynaLoader/t/DynaLoader.t.

Expected behavior

Either /t/DynaLoader.t does not SEGV if Socket.xs adds a Socket::END XSUB/CV* or XSUB DynaLoader::dl_unload_file() is 100% safe, stable and part of the P5P supported Perl public API.

Perl configuration

C:\sources\perl5>perl -V
Summary of my perl5 (revision 5 version 43 subversion 0) configuration:
  Commit id: b9b797f2d87d00673b84c29a17c345aaa6f2c426
  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 -DWIN32 -D_CONSOLE -DNO_STRICT -DWIN64 -D_CRT_
SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_WINSOCK_DEPRECATED_NO_WARNING
S -DPERL_TEXTMODE_SCRIPTS -DMULTIPLICITY -DPERL_IMPLICIT_SYS -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:\perl\
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=perl543.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:
\perl\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_PERLIO
    USE_PERL_ATOF
    USE_THREAD_SAFE_LOCALE
  Built under MSWin32
  Compiled at Jul  4 2025 22:44:40
  @INC:
    C:/sources/perl5/lib

C:\sources\perl5>

Complicated solutions:

I never finished the patch because it breaks (syntax errors) P5P Public C API for 4-7 tarballs on CPAN, and makes upto 6 more tarballs on CPAN theoretically have "new bugs" introduced, but they will still compile in the CC and run inside the perl perl process, and not leak. A log .txt file feature nobody remembers about, or is #if 0-ed, in that CPAN XS module, will now have the wrong FILE disk file in it. I dont think it wold be a problem.

So for a total of 12 modules that need patching, or they need a death certificate because CPANTesters bots were last able to build them in 5.14.0. Would be broken by a new feature change that says

CvFILE() is a const char * of opaque storage and opaque allocator.
It is UB to write to the const char * ptr.
Assume opaque storage means Ref-Counted, similar to SV*s but CvFILE()
is not a SV* ptr, it is a const char *.

Please use new macros CvFILE_setsv() CvFILE_setpvs(), CvFILE_setFoo_V_Ehn(),
CvFILE_setnull(), CvFILE2mortal(), sv_setcvcvf(), blah blah blah.

I didnt check CPANTester logs for death certificates. Its just 12 tarballs on
grepcpan.

#define CvFILE() gets the +0 rval treatment NC used to bring bad CPAN
XS code under control during 5.5.0/5.6.0 eta, for the CPAN author has to read perlguts and perlapi.

The final intention of adding a refcounted CvFILE() feature, is to then internally turn that SV* ptrs, into a DynaLoader::SourceFile class object (aka SV* POK string "C:/devcode/perl-data-foo/lib/Data/Foo/Foo.xs"), and DynaLoader::SourceFile objects hold refs to DynaLoader::ShLibFile class objects (2 hash keys, first an OS handle from dl_open/LoadLibrary, 2nd key is "C:/perl/site/lib/auto/Data/Foo/Foo.dll").

Now that XSUB CV ptrs have refs to DynaLoader::SourceFile ptrs, that hold refs to DynaLoader::ShLibFile ptrs. perl5db.pl and PP caller() will show XSUB frames in a backtrace from Pure Perl. Feature maybe is controlled by use v5.50; or %^H tricks.

And now @bulk88 can easily see the PP call stack from Visual Studio IDE from inside the C debugger, and all SEGVs on WinPerl will print a PP backtrace on STDERR after a SEGV automatically unless a C debugger port occupied in the PEB (someone is single stepping perl.exe).

The watch window expression written in actual ISO C lang to see the PP call stack from a C debugger, is the same size as this bug ticket. Ive wriiten only 2x ever. Remember Perl 5 interp has NEVER been written in ISO C. The C Pre Processor is a separate binary that has nothing to do with ISO C Abstract Virtual Machine. Same committee, wrong document!

I also could write a .dll that loads into VS IDE to read the PP callstack in a frozen perl PID, but that would take me longer to write than my proposals above.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions