in reply to Re^2: XS: free() outside of the main thread causes crash on Windows
in thread XS: free() outside of the main thread causes crash on Windows

I strongly suggest that you should compile your code with /E or equivalent to produce the post-preprocessor code and take a look at what is actually being call for malloc() and free(); because it almost certainly isn't the appropriate CRT routines.


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
  • Comment on Re^3: XS: free() outside of the main thread causes crash on Windows

Replies are listed 'Best First'.
Re^4: XS: free() outside of the main thread causes crash on Windows
by OlegG (Monk) on Sep 25, 2014 at 07:56 UTC
    It says that free() is win32_free() and malloc() is win32_malloc().

      If you look into win32.c/.h and unwind those functions, you'll find that they use a custom (pseudo-C++ style) allocator that uses different pools for different threads. (iThreads, that is.)

      But for that to work properly, it needs to be initialised and as you are not instantiating an interpreter in your thread(s), you are not getting that initialisation done.

      Basically, by using the perl environment to compile (what is essentially) pure C code, you're just opening yourself to a whole world of hurt. It, the Perl environment, simply isn't designed to be used that way.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
      If you do this on win32 I don't get this "double free" error
      #include <pthread.h> void *thread(void *arg) { char *msg = (char*)arg; printf("thread: %s\n", msg); free(msg); return NULL; } #include "EXTERN.h" ...
        I changed it to
        #include <pthread.h> void *thread(void *arg) { char *msg = (char*)arg; printf("thread: %s\n", msg); free(msg); return NULL; } #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" MODULE = My PACKAGE = My void test_thread(char *msg) PPCODE: char *thread_arg = malloc((strlen(msg)+1)*sizeof(char)); strcpy(thread_arg, msg); pthread_t tid; pthread_create(&tid, NULL, thread, (void*)thread_arg); void *rv; pthread_join(tid, &rv);

        And the problem still here: crash on each run
        And gdb output looks not very usefull
        (gdb) r t.pl Starting program: C:\Perl64\bin\perl.exe t.pl [New Thread 17748.0x6114] [New Thread 17748.0x61f8] thread: Just another XS hacker warning: Critical error detected c0000374 Program received signal SIGTRAP, Trace/breakpoint trap. [Switching to Thread 17748.0x61f8] 0x00000000770d40d0 in ntdll!RtlUnhandledExceptionFilter () from C:\WINDOWS\SYSTEM32\ntdll.dll (gdb) bt #0 0x00000000770d40d0 in ntdll!RtlUnhandledExceptionFilter () from C:\WINDOWS\SYSTEM32\ntdll.dll #1 0x00000000770d4746 in ntdll!EtwEnumerateProcessRegGuids () from C:\WINDOWS\SYSTEM32\ntdll.dll #2 0x00000000770d5952 in ntdll!RtlQueryProcessLockInformation () from C:\WINDOWS\SYSTEM32\ntdll.dll #3 0x00000000770d7604 in ntdll!RtlLogStackBackTrace () from C:\WINDOWS\SYSTEM32\ntdll.dll #4 0x000000007707dc47 in ntdll!RtlIsDosDeviceName_U () from C:\WINDOWS\SYSTEM32\ntdll.dll Backtrace stopped: previous frame inner to this frame (corrupt stack?) (gdb)
Re^4: XS: free() outside of the main thread causes crash on Windows
by Anonymous Monk on Sep 25, 2014 at 07:58 UTC
      But yes perl does redefine these things, ...

      The problem is that those also get redefined at various points. See win32\win32iop.h. Sometimes, multiple times depending upon where you are in the source code.

      And the allocator used under Windows is a custom allocator. See win32\vmem.h. (Though that is also dependent upon build-time options...)

      It's all very convoluted to work out exactly what is being compiled.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        The problem is that those also get redefined at various points

        Aaaah ... it seems to be the old "#undef free" trick that's needed here.
        The following rendition works fine for me on Strawberry:
        void *thread(void *arg) { #undef free char *msg = (char*)arg; printf("thread: %s\n", msg); free(msg); return NULL; }
        You can probably disregard my other post of a few minutes ago.

        (By undeffing free, we get to call the free() that we want, not the the free() that perl defined for us.)

        Cheers,
        Rob