Skip Menu |

This queue is for tickets about the Win32-API CPAN distribution.

Report information
The Basics
Id: 53914
Status: resolved
Priority: 0/
Queue: Win32-API

People
Owner: BULKDD [...] cpan.org
Requestors: CHORNY [...] cpan.org
perlsite [...] mail.bg
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.68
Fixed in: 0.70_01



Subject: Bug report for Win32::API::Callback
Date: Fri, 22 Jan 2010 13:24:21 +0200
To: bug-Win32-API [...] rt.cpan.org
From: perlsite [...] mail.bg
Hello, The code below generate exception and application dies with the following "Error signature" AppName: perl.exe AppVer: 5.10.0.1004 ModName: perl510.dll ModVer: 5.10.0.1004 Offset: 000961d5 # --- code start --- #!/usr/bin/perl use strict; use Win32::API; use Win32::API::Callback; Win32::API->Import('kernel32', 'SetConsoleCtrlHandler', 'KL', 'L'); Win32::API->Import('kernel32', 'GenerateConsoleCtrlEvent', 'LL', 'L'); Win32::API->Import('kernel32', 'GetLastError', '', 'L'); sub cb { my ($dwCtrlType) = @_; open (FILE, '>c:/QUIT.TXT'); print FILE "RECEIVED SIGNAL: $dwCtrlType\n"; close FILE; return 0; } my $callback = Win32::API::Callback->new(\&cb, "L", "L"); SetConsoleCtrlHandler($callback, 1) or die "Error: " . GetLastError() . "\n"; sleep(1); GenerateConsoleCtrlEvent(0, 0); sleep(2); # --- code end --- The error occurs when cb() routine is called, no matter whether it is triggered through GenerateConsoleCtrlEvent call or via while(1){} and Ctrl+C. Also specific implementation of cb() routine doesn't matter, i.e. callback body can be just return 0 or return 1 - same effect (in my implementation no file is created, so I assume that exception is generated when OS try to call the callback). My personal opinion is that $callback handler is not properly implemented. My test fails both with Win32-API version 0.55 and 0.58 (ActiveState build). I'm using Windows XP Professional, SP3 (up-to-date installation). Regards, Julian ------------------------------------- Хостинг от 3.60 лв/м| Домейни от 17.46 лв/с ДДС| Сървъри, VPS от 48.00 лв/м с ДДС! 18 GB място, Неограничен трафик, Безплатен домейн – 6.90 лв./м с ДДС! 25 GB място, 1200 GB трафик, Безплатен домейн – 11.46 лв./м с ДДС!
On Fri Jan 22 06:26:39 2010, perlsite@mail.bg wrote: Show quoted text
> The error occurs when cb() routine is called, no matter whether it is > triggered through GenerateConsoleCtrlEvent call or via while(1){} and > Ctrl+C. Also specific implementation of cb() routine doesn't matter, > i.e. callback body can be just return 0 or return 1 - same effect (in > my implementation no file is created, so I assume that exception is > generated when OS try to call the callback). My personal opinion is > that $callback handler is not properly implemented.
Hi Julian, sorry for the late reply. I have to admit I don't have too much time to debug this, but I also have no clue about what's going wrong. I guess you haven't found a way around your problem... -- Cosimo
my (wild enough) guess is that there is something different in the PHANDLER_ROUTINE (the callback SetConsoleCtrlHandler expects) from other working callbacks. Namely: BOOL WINAPI HandlerRoutine( __in DWORD dwCtrlType ); versus e.g.: BOOL CALLBACK EnumWindowsProc( __in HWND hwnd, __in LPARAM lParam ); the difference is the WINAPI instead of CALLBACK definition. I think it may have something to do with calling conventions and how parameters are pushed to the stack. this would man that callbacks defined in C as WINAPI are not supported, only those defined as CALLBACK are. but digging in the C headers to find the real difference between WINAPI and CALLBACK, or even adding support for different calling conventions in Win32::API::Callback is beyond my scope at the moment, sorry :-( cheers, Aldo
On Tue Sep 07 07:51:32 2010, ACALPINI wrote: Show quoted text
> the difference is the WINAPI instead of CALLBACK definition. I think it > may have something to do with calling conventions and how parameters are > pushed to the stack. > > this would man that callbacks defined in C as WINAPI are not supported, > only those defined as CALLBACK are. > > but digging in the C headers to find the real difference between WINAPI > and CALLBACK, or even adding support for different calling conventions > in Win32::API::Callback is beyond my scope at the moment, sorry :-(
I think WINAPI and CALLBACK are both synonyms for __stdcall, so that should not make any difference. Cheers, -Jan
Subject: Re: [rt.cpan.org #53914] Bug report for Win32::API::Callback
Date: Tue, 07 Sep 2010 14:30:15 -0700
To: bug-Win32-API [...] rt.cpan.org
From: Bill Luebkert <dbecoll [...] roadrunner.com>
On 9/7/2010 4:51 AM, Aldo Calpini via RT wrote: Show quoted text
> Tue Sep 07 07:51:32 2010: Request 53914 was acted upon. > Transaction: Correspondence added by ACALPINI > Queue: Win32-API > Subject: Bug report for Win32::API::Callback > Broken in: (no value) > Severity: (no value) > Owner: Nobody > Requestors: perlsite@mail.bg > Status: open > Ticket<URL: https://rt.cpan.org/Ticket/Display.html?id=53914> > > > my (wild enough) guess is that there is something different in the > PHANDLER_ROUTINE (the callback SetConsoleCtrlHandler expects) from other > working callbacks. Namely: > > BOOL WINAPI HandlerRoutine( > __in DWORD dwCtrlType > ); > > versus e.g.: > > BOOL CALLBACK EnumWindowsProc( > __in HWND hwnd, > __in LPARAM lParam > ); > > the difference is the WINAPI instead of CALLBACK definition. I think it > may have something to do with calling conventions and how parameters are > pushed to the stack. > > this would man that callbacks defined in C as WINAPI are not supported, > only those defined as CALLBACK are. > > but digging in the C headers to find the real difference between WINAPI > and CALLBACK, or even adding support for different calling conventions > in Win32::API::Callback is beyond my scope at the moment, sorry :-(
They appear to be the esentially the same. Looks like it's just a matter of whether __stdcall calling convention is in use or not. WINDEF.H: #if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) #define CALLBACK __stdcall #define WINAPI __stdcall #define WINAPIV __cdecl #define APIENTRY WINAPI #define APIPRIVATE __stdcall #define PASCAL __stdcall #else #define CALLBACK #define WINAPI #define WINAPIV #define APIENTRY WINAPI #define APIPRIVATE #define PASCAL pascal #endif
CC: libwin32 [...] perl.org
Subject: Re: [rt.cpan.org #53914] Bug report for Win32::API::Callback
Date: Wed, 8 Sep 2010 08:14:20 +0200
To: bug-Win32-API [...] rt.cpan.org
From: Reini Urban <rurban [...] x-ray.at>
2010/9/7 Cosimo Streppone via RT <bug-Win32-API@rt.cpan.org>: Show quoted text
> Tue Sep 07 07:04:22 2010: Request 53914 was acted upon. > Transaction: Correspondence added by COSIMO >       Queue: Win32-API >     Subject: Bug report for Win32::API::Callback >   Broken in: (no value) >    Severity: (no value) >       Owner: Nobody >  Requestors: perlsite@mail.bg >      Status: new >  Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=53914 > > > > On Fri Jan 22 06:26:39 2010, perlsite@mail.bg wrote: >
>> The error occurs when cb() routine is called, no matter whether it is >> triggered through GenerateConsoleCtrlEvent call or via while(1){} and >> Ctrl+C. Also specific implementation of cb() routine doesn't matter, >> i.e. callback body can be just return 0 or return 1 - same effect (in >> my implementation no file is created, so I assume that exception is >> generated when OS try to call the callback). My personal opinion is >> that $callback handler is not properly implemented.
> > Hi Julian, > > sorry for the late reply. > I have to admit I don't have too much time to debug this, > but I also have no clue about what's going wrong. > > I guess you haven't found a way around your problem...
/usr/include/w32api/windef.h:#define CALLBACK __stdcall So it should just work, both are the same calling convention, CALLBACK is not using cdecl. I'll check if I see something wrong how callbacks (T_CODE) are handled in API.xs But I rather believe the user callback sub is just wrong. You have to debug into the perl-side of the callback. -- Reini Urban
CC: libwin32 [...] perl.org
Subject: Re: [rt.cpan.org #53914] Bug report for Win32::API::Callback
Date: Wed, 8 Sep 2010 10:40:08 +0200
To: bug-Win32-API [...] rt.cpan.org
From: Reini Urban <rurban [...] x-ray.at>
2010/9/8 Reini Urban <rurban@x-ray.at>: Show quoted text
> I'll check if I see something wrong how callbacks (T_CODE) > are handled in API.xs > But I rather believe the user callback sub is just wrong. > You have to debug into the perl-side of the callback.
In my app the Ctrl-C or Ctrl-Break signal is never generated. Maybe we need a AllocConsole beforehand. Attached is a test case. -- Reini Urban http://phpwiki.org/           http://murbreak.at/

Message body is not shown because sender requested not to inline it.

RT-Send-CC: rurban [...] x-ray.at, libwin32 [...] perl.org, dbecoll [...] roadrunner.com
On Wed Sep 08 04:40:17 2010, rurban@x-ray.at wrote: Show quoted text
> 2010/9/8 Reini Urban <rurban@x-ray.at>:
> > I'll check if I see something wrong how callbacks (T_CODE) > > are handled in API.xs > > But I rather believe the user callback sub is just wrong. > > You have to debug into the perl-side of the callback.
> > In my app the Ctrl-C or Ctrl-Break signal is never generated. > Maybe we need a AllocConsole beforehand. > Attached is a test case.
Took me almost a year to come back to this bug. I have now included the test script under the Callback/t folder. Unfortunately, I don't have a test Win32 install available. I'll try to find one to see if that test can trigger the callback. https://github.com/cosimo/perl5-win32-api/
On Sun Aug 28 16:02:10 2011, COSIMO wrote: Show quoted text
> On Wed Sep 08 04:40:17 2010, rurban@x-ray.at wrote:
> > 2010/9/8 Reini Urban <rurban@x-ray.at>:
> > Took me almost a year to come back to this bug. > I have now included the test script under the Callback/t folder.
I get a failure (actually a crash) on Callback/t/04_rt_53914.t during GenerateConsoleCtrlEvent(1, 0). All other tests pass. For 32-bit Strawberry perl 5.14.2 on a 64-bit machine.
On 2012-02-14 14:35:12, DOUGW wrote: Show quoted text
> On Sun Aug 28 16:02:10 2011, COSIMO wrote:
> > On Wed Sep 08 04:40:17 2010, rurban@x-ray.at wrote:
> > > 2010/9/8 Reini Urban <rurban@x-ray.at>:
> > > > Took me almost a year to come back to this bug. > > I have now included the test script under the Callback/t folder.
> > I get a failure (actually a crash) on Callback/t/04_rt_53914.t during > GenerateConsoleCtrlEvent(1, 0). > > All other tests pass. > For 32-bit Strawberry perl 5.14.2 on a 64-bit machine.
I get similar results with perl 5.10.1 from the Cygwin distribution: Perl crashes (leaves stackdump), and the RXVT window it's running in closes.
On Mon Feb 20 10:15:13 2012, JDHEDDEN wrote: Show quoted text
> On 2012-02-14 14:35:12, DOUGW wrote:
> > On Sun Aug 28 16:02:10 2011, COSIMO wrote:
> > > On Wed Sep 08 04:40:17 2010, rurban@x-ray.at wrote:
> > > > 2010/9/8 Reini Urban <rurban@x-ray.at>:
> > > > > > Took me almost a year to come back to this bug. > > > I have now included the test script under the Callback/t folder.
> > > > I get a failure (actually a crash) on Callback/t/04_rt_53914.t
during Show quoted text
> > GenerateConsoleCtrlEvent(1, 0). > > > > All other tests pass. > > For 32-bit Strawberry perl 5.14.2 on a 64-bit machine.
> > I get similar results with perl 5.10.1 from the Cygwin distribution: > Perl crashes (leaves stackdump), and the RXVT window it's running in
closes. All the reports I got so far, or those that I have managed to keep track of in my email, are from users of 64-bit Windows, but running a 32 bit perl. My guess is that in this case a Win32::API->Import() with "L" as type considers "L" as 32 bits, while on the native machine is 64 bits. Is this the case? Can we do something?
On Fri Mar 23 13:02:58 2012, COSIMO wrote: Show quoted text
> All the reports I got so far, or those that I have managed to keep > track of in my email, are from users of 64-bit Windows, but running a > 32 bit perl.
I have 32-bit Perl on 32-bit Windows XP t/04_rt_53914.t .. 1/2 # callback installed, sleep 1, generate Ctrl-C signal Terminating on signal SIGBREAK(21) # callback called or not ^C^C^C -- Alexandr Ciornii, http://chorny.net
Until we know more about this, I have modified the test case to "skip_all". At least people can build Win32::API...
From: bulk88(1) [...] hotmail.com
On Tue Apr 10 14:39:35 2012, COSIMO wrote: Show quoted text
> 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. Show quoted text
_______________ 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.
From: bulk88(1) [...] hotmail.com
Show quoted text
> I may or may not put > this warning into my Win32 API 0.69.
I'm working on putting the warning in. Its very complicated. CallbackTemplate has no jmp codes or branches, and CreateCallback doesn't detect or adjust them currently. I think I will be successful though.
RT-Send-CC: bulk88 [...] hotmail.com, libwin32 [...] perl.org, rurban [...] x-ray.at, dbecoll [...] roadrunner.com, perlsite [...] mail.bg
On Sun May 20 13:58:03 2012, bulk88. wrote: Show quoted text
> > I may or may not put > > this warning into my Win32 API 0.69.
> > > I'm working on putting the warning in. Its very complicated. > CallbackTemplate has no jmp codes or branches, and CreateCallback > doesn't detect or adjust them currently. I think I will be successful > though.
As of Win32::API 0.69 this will not crash, only a fatal error (see this code chunk https://metacpan.org/source/COSIMO/Win32-API-0.72/Callback/Callback.xs#L204 ) and possible resource leaks (ExitThread()). Is this a good enough resolution to the problem or does someone seriously want the Perl interp to be automatically moved between OS threads? The GenerateConsoleCtrlEvent API always runs the callback in a brand new OS thread each time Ctrl-C or synthesized equivalent happens, unlike Unix signals. To automatically move the threaded interp between OS threads without an explicit command to suspend and transfer the interp on a Script level, reenterancy and race conditions *I think* will make it very unstable. This would involve adding an "event loop" to Win32::API or integration with the event loop in the interp's alarm/Windows Messages/Win32 safe signals system. Does anyone want Win32::API to move the interp between OS threads or is the fatal error to console enough? If I dont get any responses in the next couple days or week I will close this ticket as resolved/fixed (as fatal error in 0.69 rather than previous crash).
RT-Send-CC: libwin32 [...] perl.org, rurban [...] x-ray.at, dbecoll [...] roadrunner.com, perlsite [...] mail.bg
On Fri Oct 19 21:43:20 2012, BULKDD wrote: Show quoted text
> As of Win32::API 0.69 this will not crash, only a fatal error (see this > code chunk >
https://metacpan.org/source/COSIMO/Win32-API-0.72/Callback/Callback.xs#L204 Show quoted text
> ) and possible resource leaks (ExitThread()). Is this a good enough > resolution to the problem or does someone seriously want the Perl interp > to be automatically moved between OS threads? The > GenerateConsoleCtrlEvent API always runs the callback in a brand new OS > thread each time Ctrl-C or synthesized equivalent happens, unlike Unix > signals. > > To automatically move the threaded interp between OS threads without an > explicit command to suspend and transfer the interp on a Script level, > reenterancy and race conditions *I think* will make it very unstable. > This would involve adding an "event loop" to Win32::API or integration > with the event loop in the interp's alarm/Windows Messages/Win32 safe > signals system. Does anyone want Win32::API to move the interp between > OS threads or is the fatal error to console enough? If I dont get any > responses in the next couple days or week I will close this ticket as > resolved/fixed (as fatal error in 0.69 rather than previous crash).
This was fixed with a fatal error in 0.69 instead of the previous crash. No response 30 days, closing as resolved.