tusooa has asked for the wisdom of the Perl Monks concerning the following question:

Hi there,

I need to somehow embed a Perl interpreter in a shared library, and call it dynamicly from another application. My idea is to create the interpreter in the constructor function, use it to call some functions when needed, and finally free it in the destructor function.

To test the library I wrote a one-liner using Win32::API of Perl to load it. The loading is no problem, but when it comes to FreeLibrary it gives out the message of `Perl interpreter has stopped working'. What is confusing me however, is that according to the messages printed in the terminal, the destructor function seems to be correctly executed. Then, when I use gdb it shows that there is a SIGSEGV, claiming the problem is in ntdll!RtlWaitOnAddress () from C:\WINDOWS\SYSTEM32\ntdll.dll.

I also wrote a C program invoking the shared library, which seem to have no problem loading and freeing.

I am using a 32-bit Strawberry Perl 5.24.0 on a 64-bit Windows 10.

Could anyone help with this problem please? Lots of thanks and sorry for my poor English.

Best regards,

The perlembed code is as follows:

#include <EXTERN.h> #include <perl.h> #include <windows.h> #include <stdio.h> static PerlInterpreter *my_perl = NULL; static __attribute__((constructor)) void init() { int num = 2; char *args[] = { "", "init.perl" }; PERL_SYS_INIT3((int *)NULL,(char ***)NULL,(char ***)NULL); my_perl = perl_alloc(); perl_construct(my_perl); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_parse(my_perl, NULL, num, args, (char **)NULL); perl_run(my_perl); } static __attribute__((destructor)) void quit() { if (my_perl) { PL_perl_destruct_level = 1; perl_destruct(my_perl);printf("1st\n"); perl_free(my_perl);printf("2nd\n"); PERL_SYS_TERM();printf("3rd\n"); } } // the following are functions to invoke in perl script extern __declspec(dllexport) void about() { dSP; SV *err_tmp; ENTER; SAVETMPS; PUSHMARK(SP); PUTBACK; call_pv("about", G_VOID|G_DISCARD|G_EVAL|G_NOARGS); SPAGAIN; err_tmp = ERRSV; if (SvTRUE(err_tmp)) { printf ("[error about]%s\n", SvPV_nolen(err_tmp)); POPs; } PUTBACK; FREETMPS; LEAVE; }

The perl script invoked is as follows, named init.perl:

#!/usr/bin/env perl use 5.012; say 'aaa'; sub about { say "bbb"; }

The output of GDB is:

(gdb) set args -e "use Win32;my $c = Win32::LoadLibrary('interp.dll'); +Win32::FreeLibrary($c);" (gdb) r Starting program: C:\Home\Programs\perl5\perl\bin\perl.exe -e "use Win +32;my $c = Win32::LoadLibrary('interp.dll');Win32: :FreeLibrary($c);" [New Thread 5764.0x10f4] warning: FTH: (5764): *** Fault tolerant heap shim applied to current +process. This is usually due to previous crashes. *** [New Thread 5764.0x1bc4] [New Thread 5764.0x1698] [New Thread 5764.0xc68] aaa 1st 2nd 3rd Program received signal SIGSEGV, Segmentation fault. 0x77616d39 in ntdll!RtlWaitOnAddress () from C:\WINDOWS\SYSTEM32\ntdll +.dll (gdb) info all-registers eax 0x0 0 ecx 0x6de7bf34 1843904308 edx 0xffffffff -1 ebx 0xffffff00 -256 esp 0x60fd20 0x60fd20 ebp 0x60fd4c 0x60fd4c esi 0x6de7bf24 1843904292 edi 0x0 0 eip 0x77616d39 0x77616d39 <ntdll!RtlWaitOnAddress+153 +> eflags 0x10213 [ CF AF IF RF ] cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x53 83 gs 0x2b 43 st0 0 (raw 0x00000000000000000000) st1 0 (raw 0x00000000000000000000) st2 0 (raw 0x00000000000000000000) st3 0 (raw 0x00000000000000000000) st4 12 (raw 0x4002c000000000000000) st5 1000 (raw 0x4008fa00000000000000) st6 5.0110000000000001207922650792170316 (raw 0x4001a05 +a1cac08312800) st7 1 (raw 0x3fff8000000000000000) fctrl 0x37f 895 fstat 0x420 1056 ftag 0xffff 65535 fiseg 0x0 0 fioff 0x6dcc9c40 1842125888 ---Type <return> to continue, or q <return> to quit--- foseg 0x0 0 fooff 0x60f188 6353288 fop 0x0 0 xmm0 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0 +}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0 +, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm1 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0 +}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0 +, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm2 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0 +}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0 +, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm3 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0 +}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0 +, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm4 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0 +}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0 +, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm5 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0 +}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int32 = {0x0 +, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000} xmm6 {v4_float = {0xbb, 0x0, 0x371, 0x0}, v2_double = {0x800 +0000000000000, 0x8000000000000000}, v16_int8 = { 0x69, 0x6e, 0x3b, 0x43, 0x3a, 0x5c, 0x48, 0x6f, 0x6d, 0x65, 0x5c, +0x44, 0x6f, 0x63, 0x75, 0x6d}, v8_int16 = { 0x6e69, 0x433b, 0x5c3a, 0x6f48, 0x656d, 0x445c, 0x636f, 0x6d75}, v +4_int32 = {0x433b6e69, 0x6f485c3a, 0x445c656d, 0x6d75636f}, v2_int64 = {0x6f485c3a433b6e69, 0x6d75636f445c656d}, +uint128 = 0x6d75636f445c656d6f485c3a433b6e69} xmm7 {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x800000 +0000000000, 0x8000000000000000}, v16_int8 = { 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x47, 0x69, 0x74, 0x48, 0x75, 0x62, +0x5c, 0x73, 0x63, 0x72, 0x69}, v8_int16 = { 0x6e65, 0x7374, 0x475c, 0x7469, 0x7548, 0x5c62, 0x6373, 0x6972}, v +4_int32 = {0x73746e65, 0x7469475c, 0x5c627548, 0x69726373}, v2_int64 = {0x7469475c73746e65, 0x697263735c627548}, +uint128 = 0x697263735c6275487469475c73746e65} ---Type <return> to continue, or q <return> to quit--- mxcsr 0x1f80 [ IM DM ZM OM UM PM ] mm0 {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, +0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}} mm1 {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, +0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}} mm2 {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, +0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}} mm3 {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, +0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}} mm4 {uint64 = 0xc000000000000000, v2_int32 = {0x0, 0xc00000 +00}, v4_int16 = {0x0, 0x0, 0x0, 0xc000}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0}} mm5 {uint64 = 0xfa00000000000000, v2_int32 = {0x0, 0xfa0000 +00}, v4_int16 = {0x0, 0x0, 0x0, 0xfa00}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfa}} mm6 {uint64 = 0xa05a1cac08312800, v2_int32 = {0x8312800, 0x +a05a1cac}, v4_int16 = {0x2800, 0x831, 0x1cac, 0xa05a}, v8_int8 = {0x0, 0x28, 0x31, 0x8, 0xac, 0x1c, 0x5a, 0xa0}} mm7 {uint64 = 0x8000000000000000, v2_int32 = {0x0, 0x800000 +00}, v4_int16 = {0x0, 0x0, 0x0, 0x8000}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80}} (gdb)