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: [email protected], [email protected]
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.