Sun May 20 10:43:04 2012: Request 53914 was acted upon.
Transaction: Correspondence added by bulk88.
       Queue: Win32-API
     Subject: Bug report for Win32::API::Callback
   Broken in: (no value)
    Severity: (no value)
       Owner: Nobody
  Requestors: cho...@cpan.org, perls...@mail.bg
      Status: open
 Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=53914 >


On Tue Apr 10 14:39:35 2012, COSIMO wrote:
> Until we know more about this, I have modified the test case to 
> "skip_all". At least people can build Win32::API...

This is NEVER going to work. Read
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683242%28v=vs.85%29.aspx
. I'll quote.

_______________
Remarks

Because the system creates a new thread in the process to execute the
handler function, it is possible that the handler function will be
terminated by another thread in the process. Be sure to synchronize
threads in the process with the thread for the handler function.
________________

A new thread.

Here is a callstack from Win32::API::Callback's dynamically generated
callback.
________________
>       00833fbc()      
        kernel32.dll!_CtrlRoutine@4()  + 0x118  
        kernel32.dll!_BaseThreadStart@8()  + 0x37       
________________

The breakpoint is the first line below

________________
00833FBC 55               push        ebp  
00833FBD 8B EC            mov         ebp,esp 
00833FBF 83 EC 18         sub         esp,18h 
00833FC2 C7 45 E8 B4 F1 91 00 mov         dword ptr [ebp-18h],91F1B4h 
00833FC9 C7 45 F0 01 00 00 00 mov         dword ptr [ebp-10h],1 
00833FD0 8B 45 F0         mov         eax,dword ptr [ebp-10h] 
00833FD3 C1 E0 05         shl         eax,5 
00833FD6 50               push        eax  
00833FD7 E8 4E FA B9 FF   call        Perl_safesysmalloc (3D3A2Ah) 
00833FDC 83 C4 04         add         esp,4 
00833FDF 89 45 F8         mov         dword ptr [ebp-8],eax 
00833FE2 C7 45 F4 10 00 DE C0 mov         dword ptr [ebp-0Ch],0C0DE0010h 
00833FE9 C7 45 FC 00 00 00 00 mov         dword ptr [ebp-4],0 
00833FF0 8B 4D FC         mov         ecx,dword ptr [ebp-4] 
00833FF3 C1 E1 05         shl         ecx,5 
00833FF6 8B 55 F8         mov         edx,dword ptr [ebp-8] 
00833FF9 C7 04 0A 03 00 00 00 mov         dword ptr [edx+ecx],3 
__________________

There is no dTHX/my_perl in TLS in this new thread. You wouldn't want to
add one anyways due to the race problems of 2 OS threads, 1 perl interp.
___________________
I step into the safesysmalloc call.
___________________
    72: 
    73: /* paranoid version of system's malloc() */
    74: 
    75: Malloc_t
    76: Perl_safesysmalloc(MEM_SIZE size)
    77: {
281C2160 55               push        ebp  
281C2161 8B EC            mov         ebp,esp 
281C2163 83 EC 18         sub         esp,18h 
    78:     dTHX;
281C2166 E8 B5 19 E4 FF   call        @ILT+11035(_Perl_get_context)
(28003B20h) 
281C216B 89 45 FC         mov         dword ptr [my_perl],eax 
    79:     Malloc_t ptr;
    80: #ifdef HAS_64K_LIMIT
    81:         if (size > 0xffff) {
    82:             PerlIO_printf(Perl_error_log,
    83:                           "Allocation too large: %lx\n", size) FLUSH;
    84:             my_exit(1);
    85:         }
    86: #endif /* HAS_64K_LIMIT */
_______________________
I see a dTHX, step into that.
_______________________
    21: 
    22: void *
    23: Perl_get_context(void)
    24: {
281EA190 55               push        ebp  
281EA191 8B EC            mov         ebp,esp 
281EA193 83 EC 08         sub         esp,8 
    25: #if defined(USE_ITHREADS)
    26: #  ifdef USE_DECLSPEC_THREAD
    27:     return Perl_current_context;
    28: #  else
    29:     DWORD err = GetLastError();
281EA196 FF 15 38 78 22 28 call        dword ptr [__imp__GetLastError@0
(28227838h)] 
281EA19C 89 45 F8         mov         dword ptr [err],eax 
    30:     void *result = TlsGetValue(PL_thr_key);
281EA19F A1 D8 6E 22 28   mov         eax,dword ptr [_PL_thr_key
(28226ED8h)] 
281EA1A4 50               push        eax  
281EA1A5 FF 15 14 78 22 28 call        dword ptr [__imp__TlsGetValue@4
(28227814h)] 
281EA1AB 89 45 FC         mov         dword ptr [result],eax 
    31:     SetLastError(err);
281EA1AE 8B 4D F8         mov         ecx,dword ptr [err] 
___________________________
result is 
        result  0x00000000      void *

This is will never work unless you build a new ithread perl interp for
each callback run.

Perhaps a more graceful console warning, or less graceful console
warning + process exit that the dyn callback func ran from the wrong
thread is needed and then this bug can be closed. I may or may not put
this warning into my Win32 API 0.69.

Reply via email to