Prev: Hook chain using TEB->Win32ThreadInfo
Next: HOMEDRIVE, HOMEPATH missing in CreateEnvironmentBlock
From: Marc Sherman on 7 Jun 2007 12:08 Assuming the signal handler does the minimum (ie. set a global, set an event) and never tries to acquire a lock (explicitly or implicitly), would there still be a problem in a multithreaded POSIX app? "Alexander Grigoriev" <alegr(a)earthlink.net> wrote in message news:u0k46rRqHHA.1208(a)TK2MSFTNGP02.phx.gbl... >A BIG BIG problem with asynchronous notifications is that in a >multithreaded process there is NO reliable interrupt point, other than >explicitly provided (alertable wait). Only a single-threaded POSIX >application can be interrupted at a random instruction without ill effects. > > "Marc Sherman" <masherman1970(a)yahoo.com> wrote in message > news:O1XaNaQqHHA.4520(a)TK2MSFTNGP04.phx.gbl... >> From "Windows Internals, 4th Edition" (p. 108) >> >> "The POSIX subsystem uses kernel-mode APCs to emulate the delivery of >> POSIX signals to POSIX processes". >> >> Also from the same page: >> >> "Kernel mode APCs interrupt a thread and execute a procedure without the >> thread's intervention or consent". >> >> That tells me they would behave like a UNIX developer would expect. >> >> Marc >> >> "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in >> message news:eEO3XfOqHHA.3296(a)TK2MSFTNGP03.phx.gbl... >>> ...actually, I don't suppose anyone knows how things like SIGINT are >>> implemented in the POSIX sub-system under Windows. Do they even work >>> like a >>> UNIX developer would expect? >>> >>> Tony Proctor >>> >>> "Gary Chanson" <gchanson(a)No.Spam.mvps.org> wrote in message >>> news:O$s$jsDqHHA.4132(a)TK2MSFTNGP02.phx.gbl... >>>> My solution for a similar situation was to redirect the exception >>>> to >>> the >>>> appropriate thread using a User APC. In my case, I can be reasonably >>>> certain that the task will enter an alertable state within a reasonable >>>> time, so this works very nicely and is a lot cleaner they your >>> alternative. >>>> >>>> -- >>>> >>>> - Gary Chanson (Windows SDK MVP) >>>> - Abolish Public Schools >>>> >>>> >>>> >>>> "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in >>> message >>>> news:eFnX5$BqHHA.1148(a)TK2MSFTNGP06.phx.gbl... >>>> > Windows is not very good at handling this sort of asynchronous >>>> > interrupt >>>> on >>>> > a single thread Emmanuel (i.e. similar to UNIX signals, or even VMS >>> ASTs) >>>> > >>>> > The question has been asked before: >>>> > >>>> >>> http://groups.google.ie/group/microsoft.public.win32.programmer.kernel/browse_frm/thread/608ad10204f76515/1e175f06dca6106f?hl=en#1e175f06dca6106f >>>> > >>>> > I've even found myself in the same boat in trying to port a language, >>> and >>>> > its framework, to the Windows O/S. In the end, I suspended the >>>> > thread, >>>> read >>>> > its context, redirected it to a point that would generate the >>>> > required >>>> > exception, and then released it. Surprisingly, it worked OK in >>>> > practice >>>> > (although not on Alpha AXP H/W) but there were a few issues with >>>> > win32 >>> api >>>> > calls that had to be addressed (mentioned in that old thread) >>>> > >>>> > Tony Proctor >>>> > >>>> > "Emmanuel Stapf [ES]" <manus(a)newsgroups.nospam> wrote in message >>>> > news:uQhAUi9pHHA.1144(a)TK2MSFTNGP02.phx.gbl... >>>> > > Hi, >>>> > > >>>> > > I've a console single threaded application and I'm trying to catch >>>> > > a >>>> > Ctrl+C. No >>>> > > matter if I use SetConsoleCtrlHandler or a signal handler, my code >>>> > > to >>>> > handle >>>> > > this gets called in another thread. Is there a way to have the >>>> > > handler >>>> > called >>>> > > from the main thread? >>>> > > >>>> > > In the code below, simply comment the call to `signal' or to >>>> > > `SetConsoleCtrlHandler' to observe the similar behavior. On Unix, >>> using >>>> > > `signal', it is called from the same thread. >>>> > > >>>> > > Thanks for any highlight, >>>> > > Manu >>>> > > >>>> > > PS: this is shown by the code: >>>> > > >>>> > > #include <windows.h> >>>> > > #include <stdio.h> >>>> > > #include <signal.h> >>>> > > >>>> > > BOOL CtrlHandler( DWORD fdwCtrlType ) >>>> > > { >>>> > > switch( fdwCtrlType ) { >>>> > > case CTRL_C_EVENT: >>>> > > printf( "Ctrl-C event\n\n" ); >>>> > > return TRUE; >>>> > > default: >>>> > > return FALSE; >>>> > > } >>>> > > } >>>> > > >>>> > > void handler (int sig) { >>>> > > printf ("From Signal\n"); >>>> > > signal (SIGINT, handler); >>>> > > } >>>> > > >>>> > > void main( void ) >>>> > > { >>>> > > signal (SIGINT, handler); >>>> > > //SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ); >>>> > > >>>> > > printf("Use Ctrl+C to see what is going on.\n" ); >>>> > > while( 1 ){ } >>>> > > } >>>> > >>>> > >>>> >>>> >>> >>> >> >> > >
From: Skywing [MVP] on 7 Jun 2007 12:25 You may still have problems with stuff like the process heap lock. Furthermore, I think you are still in danger even on a single threaded system. From taking a quick look at the way the critical section acquisition code works, it looks like if you interrupt RtlEnterCriticalSection at the right place, you'll have the CS in an intermediate state where it's owned but which thread owns it is not established, such that recursive acqusition doesn't work. That means you might be in for some trouble (race conditions resulting in a deadlock) if you rely on recursive lock acqusition in your "signal handler" - hard to avoid if you call anything that touches the process heap. Specifically, consider the tail end of the successful acquire path on RtlEnterCriticalSection: ntdll!RtlEnterCriticalSection+0x11: 00000000`76e52685 65488b042530000000 mov rax,qword ptr gs:[30h] 00000000`76e5268e 488b4848 mov rcx,qword ptr [rax+48h] 00000000`76e52692 c7420c01000000 mov dword ptr [rdx+0Ch],1 00000000`76e52699 33c0 xor eax,eax 00000000`76e5269b 48894a10 mov qword ptr [rdx+10h],rcx 00000000`76e5269f 4883c420 add rsp,20h 00000000`76e526a3 5b pop rbx 00000000`76e526a4 c3 ret If you suspend the thread at rip=00000000`76e52685 in this case, and then alter context to something that tries to re-enter the same critical section (say this is the process heap), the recursive acquire will deadlock in RtlpWaitOnCriticalSection because the first acquire didn't get around to marking the current thread as the owner of the critical section. (in that case, you might see a stack like this:) 0:000> k Child-SP RetAddr Call Site 00000000`0012fde8 00000000`76e4efc8 ntdll!NtWaitForSingleObject+0xa 00000000`0012fdf0 00000000`76e4ee8b ntdll!RtlpWaitOnCriticalSection+0xd8 00000000`0012fea0 00000000`010018ef ntdll!RtlEnterCriticalSection+0xf4 -- Ken Johnson (Skywing) Windows SDK MVP http://www.nynaeve.net "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in message news:O7u2I4RqHHA.4536(a)TK2MSFTNGP05.phx.gbl... >I see what you're saying Alexander, but it must depend to some extent on >how > closely interacting those threads are. For instance, an STA architecture > wouldn't be nearly as sensitive as a close-knit MTA one > > Tony Proctor > > "Alexander Grigoriev" <alegr(a)earthlink.net> wrote in message > news:u0k46rRqHHA.1208(a)TK2MSFTNGP02.phx.gbl... >> A BIG BIG problem with asynchronous notifications is that in a > multithreaded >> process there is NO reliable interrupt point, other than explicitly > provided >> (alertable wait). Only a single-threaded POSIX application can be >> interrupted at a random instruction without ill effects. >> >> "Marc Sherman" <masherman1970(a)yahoo.com> wrote in message >> news:O1XaNaQqHHA.4520(a)TK2MSFTNGP04.phx.gbl... >> > From "Windows Internals, 4th Edition" (p. 108) >> > >> > "The POSIX subsystem uses kernel-mode APCs to emulate the delivery of >> > POSIX signals to POSIX processes". >> > >> > Also from the same page: >> > >> > "Kernel mode APCs interrupt a thread and execute a procedure without >> > the >> > thread's intervention or consent". >> > >> > That tells me they would behave like a UNIX developer would expect. >> > >> > Marc >> > >> > "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in >> > message news:eEO3XfOqHHA.3296(a)TK2MSFTNGP03.phx.gbl... >> >> ...actually, I don't suppose anyone knows how things like SIGINT are >> >> implemented in the POSIX sub-system under Windows. Do they even work > like >> >> a >> >> UNIX developer would expect? >> >> >> >> Tony Proctor >> >> >> >> "Gary Chanson" <gchanson(a)No.Spam.mvps.org> wrote in message >> >> news:O$s$jsDqHHA.4132(a)TK2MSFTNGP02.phx.gbl... >> >>> My solution for a similar situation was to redirect the exception > to >> >> the >> >>> appropriate thread using a User APC. In my case, I can be reasonably >> >>> certain that the task will enter an alertable state within a > reasonable >> >>> time, so this works very nicely and is a lot cleaner they your >> >> alternative. >> >>> >> >>> -- >> >>> >> >>> - Gary Chanson (Windows SDK MVP) >> >>> - Abolish Public Schools >> >>> >> >>> >> >>> >> >>> "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in >> >> message >> >>> news:eFnX5$BqHHA.1148(a)TK2MSFTNGP06.phx.gbl... >> >>> > Windows is not very good at handling this sort of asynchronous >> >>> > interrupt >> >>> on >> >>> > a single thread Emmanuel (i.e. similar to UNIX signals, or even VMS >> >> ASTs) >> >>> > >> >>> > The question has been asked before: >> >>> > >> >>> >> >> > http://groups.google.ie/group/microsoft.public.win32.programmer.kernel/browse_frm/thread/608ad10204f76515/1e175f06dca6106f?hl=en#1e175f06dca6106f >> >>> > >> >>> > I've even found myself in the same boat in trying to port a > language, >> >> and >> >>> > its framework, to the Windows O/S. In the end, I suspended the > thread, >> >>> read >> >>> > its context, redirected it to a point that would generate the > required >> >>> > exception, and then released it. Surprisingly, it worked OK in >> >>> > practice >> >>> > (although not on Alpha AXP H/W) but there were a few issues with > win32 >> >> api >> >>> > calls that had to be addressed (mentioned in that old thread) >> >>> > >> >>> > Tony Proctor >> >>> > >> >>> > "Emmanuel Stapf [ES]" <manus(a)newsgroups.nospam> wrote in message >> >>> > news:uQhAUi9pHHA.1144(a)TK2MSFTNGP02.phx.gbl... >> >>> > > Hi, >> >>> > > >> >>> > > I've a console single threaded application and I'm trying to >> >>> > > catch > a >> >>> > Ctrl+C. No >> >>> > > matter if I use SetConsoleCtrlHandler or a signal handler, my >> >>> > > code >> >>> > > to >> >>> > handle >> >>> > > this gets called in another thread. Is there a way to have the >> >>> > > handler >> >>> > called >> >>> > > from the main thread? >> >>> > > >> >>> > > In the code below, simply comment the call to `signal' or to >> >>> > > `SetConsoleCtrlHandler' to observe the similar behavior. On Unix, >> >> using >> >>> > > `signal', it is called from the same thread. >> >>> > > >> >>> > > Thanks for any highlight, >> >>> > > Manu >> >>> > > >> >>> > > PS: this is shown by the code: >> >>> > > >> >>> > > #include <windows.h> >> >>> > > #include <stdio.h> >> >>> > > #include <signal.h> >> >>> > > >> >>> > > BOOL CtrlHandler( DWORD fdwCtrlType ) >> >>> > > { >> >>> > > switch( fdwCtrlType ) { >> >>> > > case CTRL_C_EVENT: >> >>> > > printf( "Ctrl-C event\n\n" ); >> >>> > > return TRUE; >> >>> > > default: >> >>> > > return FALSE; >> >>> > > } >> >>> > > } >> >>> > > >> >>> > > void handler (int sig) { >> >>> > > printf ("From Signal\n"); >> >>> > > signal (SIGINT, handler); >> >>> > > } >> >>> > > >> >>> > > void main( void ) >> >>> > > { >> >>> > > signal (SIGINT, handler); >> >>> > > //SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, >> >>> > > TRUE ); >> >>> > > >> >>> > > printf("Use Ctrl+C to see what is going on.\n" ); >> >>> > > while( 1 ){ } >> >>> > > } >> >>> > >> >>> > >> >>> >> >>> >> >> >> >> >> > >> > >> >> > >
From: Tony Proctor on 7 Jun 2007 12:48 True, but for an "asynchronous abort operation", which I think is what both myself and the OP were discussing, that wouldn't be an issue Ken (as long as it threw a s/w exception that could be handled) Tony Proctor "Skywing [MVP]" <skywing_NO_SPAM_(a)valhallalegends.com> wrote in message news:e%23ZmnBSqHHA.3296(a)TK2MSFTNGP03.phx.gbl... > You may still have problems with stuff like the process heap lock. > Furthermore, I think you are still in danger even on a single threaded > system. From taking a quick look at the way the critical section > acquisition code works, it looks like if you interrupt > RtlEnterCriticalSection at the right place, you'll have the CS in an > intermediate state where it's owned but which thread owns it is not > established, such that recursive acqusition doesn't work. That means you > might be in for some trouble (race conditions resulting in a deadlock) if > you rely on recursive lock acqusition in your "signal handler" - hard to > avoid if you call anything that touches the process heap. > > Specifically, consider the tail end of the successful acquire path on > RtlEnterCriticalSection: > > ntdll!RtlEnterCriticalSection+0x11: > 00000000`76e52685 65488b042530000000 mov rax,qword ptr gs:[30h] > 00000000`76e5268e 488b4848 mov rcx,qword ptr [rax+48h] > 00000000`76e52692 c7420c01000000 mov dword ptr [rdx+0Ch],1 > 00000000`76e52699 33c0 xor eax,eax > 00000000`76e5269b 48894a10 mov qword ptr [rdx+10h],rcx > 00000000`76e5269f 4883c420 add rsp,20h > 00000000`76e526a3 5b pop rbx > 00000000`76e526a4 c3 ret > > If you suspend the thread at rip=00000000`76e52685 in this case, and then > alter context to something that tries to re-enter the same critical section > (say this is the process heap), the recursive acquire will deadlock in > RtlpWaitOnCriticalSection because the first acquire didn't get around to > marking the current thread as the owner of the critical section. > > (in that case, you might see a stack like this:) > > 0:000> k > Child-SP RetAddr Call Site > 00000000`0012fde8 00000000`76e4efc8 ntdll!NtWaitForSingleObject+0xa > 00000000`0012fdf0 00000000`76e4ee8b ntdll!RtlpWaitOnCriticalSection+0xd8 > 00000000`0012fea0 00000000`010018ef ntdll!RtlEnterCriticalSection+0xf4 > > > -- > Ken Johnson (Skywing) > Windows SDK MVP > http://www.nynaeve.net > "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in message > news:O7u2I4RqHHA.4536(a)TK2MSFTNGP05.phx.gbl... > >I see what you're saying Alexander, but it must depend to some extent on > >how > > closely interacting those threads are. For instance, an STA architecture > > wouldn't be nearly as sensitive as a close-knit MTA one > > > > Tony Proctor > > > > "Alexander Grigoriev" <alegr(a)earthlink.net> wrote in message > > news:u0k46rRqHHA.1208(a)TK2MSFTNGP02.phx.gbl... > >> A BIG BIG problem with asynchronous notifications is that in a > > multithreaded > >> process there is NO reliable interrupt point, other than explicitly > > provided > >> (alertable wait). Only a single-threaded POSIX application can be > >> interrupted at a random instruction without ill effects. > >> > >> "Marc Sherman" <masherman1970(a)yahoo.com> wrote in message > >> news:O1XaNaQqHHA.4520(a)TK2MSFTNGP04.phx.gbl... > >> > From "Windows Internals, 4th Edition" (p. 108) > >> > > >> > "The POSIX subsystem uses kernel-mode APCs to emulate the delivery of > >> > POSIX signals to POSIX processes". > >> > > >> > Also from the same page: > >> > > >> > "Kernel mode APCs interrupt a thread and execute a procedure without > >> > the > >> > thread's intervention or consent". > >> > > >> > That tells me they would behave like a UNIX developer would expect. > >> > > >> > Marc > >> > > >> > "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in > >> > message news:eEO3XfOqHHA.3296(a)TK2MSFTNGP03.phx.gbl... > >> >> ...actually, I don't suppose anyone knows how things like SIGINT are > >> >> implemented in the POSIX sub-system under Windows. Do they even work > > like > >> >> a > >> >> UNIX developer would expect? > >> >> > >> >> Tony Proctor > >> >> > >> >> "Gary Chanson" <gchanson(a)No.Spam.mvps.org> wrote in message > >> >> news:O$s$jsDqHHA.4132(a)TK2MSFTNGP02.phx.gbl... > >> >>> My solution for a similar situation was to redirect the exception > > to > >> >> the > >> >>> appropriate thread using a User APC. In my case, I can be reasonably > >> >>> certain that the task will enter an alertable state within a > > reasonable > >> >>> time, so this works very nicely and is a lot cleaner they your > >> >> alternative. > >> >>> > >> >>> -- > >> >>> > >> >>> - Gary Chanson (Windows SDK MVP) > >> >>> - Abolish Public Schools > >> >>> > >> >>> > >> >>> > >> >>> "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in > >> >> message > >> >>> news:eFnX5$BqHHA.1148(a)TK2MSFTNGP06.phx.gbl... > >> >>> > Windows is not very good at handling this sort of asynchronous > >> >>> > interrupt > >> >>> on > >> >>> > a single thread Emmanuel (i.e. similar to UNIX signals, or even VMS > >> >> ASTs) > >> >>> > > >> >>> > The question has been asked before: > >> >>> > > >> >>> > >> >> > > http://groups.google.ie/group/microsoft.public.win32.programmer.kernel/browse_frm/thread/608ad10204f76515/1e175f06dca6106f?hl=en#1e175f06dca6106f > >> >>> > > >> >>> > I've even found myself in the same boat in trying to port a > > language, > >> >> and > >> >>> > its framework, to the Windows O/S. In the end, I suspended the > > thread, > >> >>> read > >> >>> > its context, redirected it to a point that would generate the > > required > >> >>> > exception, and then released it. Surprisingly, it worked OK in > >> >>> > practice > >> >>> > (although not on Alpha AXP H/W) but there were a few issues with > > win32 > >> >> api > >> >>> > calls that had to be addressed (mentioned in that old thread) > >> >>> > > >> >>> > Tony Proctor > >> >>> > > >> >>> > "Emmanuel Stapf [ES]" <manus(a)newsgroups.nospam> wrote in message > >> >>> > news:uQhAUi9pHHA.1144(a)TK2MSFTNGP02.phx.gbl... > >> >>> > > Hi, > >> >>> > > > >> >>> > > I've a console single threaded application and I'm trying to > >> >>> > > catch > > a > >> >>> > Ctrl+C. No > >> >>> > > matter if I use SetConsoleCtrlHandler or a signal handler, my > >> >>> > > code > >> >>> > > to > >> >>> > handle > >> >>> > > this gets called in another thread. Is there a way to have the > >> >>> > > handler > >> >>> > called > >> >>> > > from the main thread? > >> >>> > > > >> >>> > > In the code below, simply comment the call to `signal' or to > >> >>> > > `SetConsoleCtrlHandler' to observe the similar behavior. On Unix, > >> >> using > >> >>> > > `signal', it is called from the same thread. > >> >>> > > > >> >>> > > Thanks for any highlight, > >> >>> > > Manu > >> >>> > > > >> >>> > > PS: this is shown by the code: > >> >>> > > > >> >>> > > #include <windows.h> > >> >>> > > #include <stdio.h> > >> >>> > > #include <signal.h> > >> >>> > > > >> >>> > > BOOL CtrlHandler( DWORD fdwCtrlType ) > >> >>> > > { > >> >>> > > switch( fdwCtrlType ) { > >> >>> > > case CTRL_C_EVENT: > >> >>> > > printf( "Ctrl-C event\n\n" ); > >> >>> > > return TRUE; > >> >>> > > default: > >> >>> > > return FALSE; > >> >>> > > } > >> >>> > > } > >> >>> > > > >> >>> > > void handler (int sig) { > >> >>> > > printf ("From Signal\n"); > >> >>> > > signal (SIGINT, handler); > >> >>> > > } > >> >>> > > > >> >>> > > void main( void ) > >> >>> > > { > >> >>> > > signal (SIGINT, handler); > >> >>> > > //SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, > >> >>> > > TRUE ); > >> >>> > > > >> >>> > > printf("Use Ctrl+C to see what is going on.\n" ); > >> >>> > > while( 1 ){ } > >> >>> > > } > >> >>> > > >> >>> > > >> >>> > >> >>> > >> >> > >> >> > >> > > >> > > >> > >> > > > > >
From: Skywing [MVP] on 7 Jun 2007 13:07 Sorry, but you're toast if you throw an SEH exception. With vectored exception handling support, the user exception dispatcher path (RtlDispatchException) in ntdll both acquires a critical section and can touch the heap, in RtlpCallVectoredHandlers. If you happened to already be in RtlEnterCriticalSection within the VEH dispatching phase of SEH exception dispatching, you'll deadlock as soon as you raise another SEH exception. -- Ken Johnson (Skywing) Windows SDK MVP http://www.nynaeve.net "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in message news:uyZ9vOSqHHA.1220(a)TK2MSFTNGP04.phx.gbl... > True, but for an "asynchronous abort operation", which I think is what > both > myself and the OP were discussing, that wouldn't be an issue Ken (as long > as > it threw a s/w exception that could be handled) > > Tony Proctor > > "Skywing [MVP]" <skywing_NO_SPAM_(a)valhallalegends.com> wrote in message > news:e%23ZmnBSqHHA.3296(a)TK2MSFTNGP03.phx.gbl... >> You may still have problems with stuff like the process heap lock. >> Furthermore, I think you are still in danger even on a single threaded >> system. From taking a quick look at the way the critical section >> acquisition code works, it looks like if you interrupt >> RtlEnterCriticalSection at the right place, you'll have the CS in an >> intermediate state where it's owned but which thread owns it is not >> established, such that recursive acqusition doesn't work. That means you >> might be in for some trouble (race conditions resulting in a deadlock) if >> you rely on recursive lock acqusition in your "signal handler" - hard to >> avoid if you call anything that touches the process heap. >> >> Specifically, consider the tail end of the successful acquire path on >> RtlEnterCriticalSection: >> >> ntdll!RtlEnterCriticalSection+0x11: >> 00000000`76e52685 65488b042530000000 mov rax,qword ptr gs:[30h] >> 00000000`76e5268e 488b4848 mov rcx,qword ptr [rax+48h] >> 00000000`76e52692 c7420c01000000 mov dword ptr [rdx+0Ch],1 >> 00000000`76e52699 33c0 xor eax,eax >> 00000000`76e5269b 48894a10 mov qword ptr [rdx+10h],rcx >> 00000000`76e5269f 4883c420 add rsp,20h >> 00000000`76e526a3 5b pop rbx >> 00000000`76e526a4 c3 ret >> >> If you suspend the thread at rip=00000000`76e52685 in this case, and then >> alter context to something that tries to re-enter the same critical > section >> (say this is the process heap), the recursive acquire will deadlock in >> RtlpWaitOnCriticalSection because the first acquire didn't get around to >> marking the current thread as the owner of the critical section. >> >> (in that case, you might see a stack like this:) >> >> 0:000> k >> Child-SP RetAddr Call Site >> 00000000`0012fde8 00000000`76e4efc8 ntdll!NtWaitForSingleObject+0xa >> 00000000`0012fdf0 00000000`76e4ee8b ntdll!RtlpWaitOnCriticalSection+0xd8 >> 00000000`0012fea0 00000000`010018ef ntdll!RtlEnterCriticalSection+0xf4 >> >> >> -- >> Ken Johnson (Skywing) >> Windows SDK MVP >> http://www.nynaeve.net >> "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in > message >> news:O7u2I4RqHHA.4536(a)TK2MSFTNGP05.phx.gbl... >> >I see what you're saying Alexander, but it must depend to some extent on >> >how >> > closely interacting those threads are. For instance, an STA >> > architecture >> > wouldn't be nearly as sensitive as a close-knit MTA one >> > >> > Tony Proctor >> > >> > "Alexander Grigoriev" <alegr(a)earthlink.net> wrote in message >> > news:u0k46rRqHHA.1208(a)TK2MSFTNGP02.phx.gbl... >> >> A BIG BIG problem with asynchronous notifications is that in a >> > multithreaded >> >> process there is NO reliable interrupt point, other than explicitly >> > provided >> >> (alertable wait). Only a single-threaded POSIX application can be >> >> interrupted at a random instruction without ill effects. >> >> >> >> "Marc Sherman" <masherman1970(a)yahoo.com> wrote in message >> >> news:O1XaNaQqHHA.4520(a)TK2MSFTNGP04.phx.gbl... >> >> > From "Windows Internals, 4th Edition" (p. 108) >> >> > >> >> > "The POSIX subsystem uses kernel-mode APCs to emulate the delivery >> >> > of >> >> > POSIX signals to POSIX processes". >> >> > >> >> > Also from the same page: >> >> > >> >> > "Kernel mode APCs interrupt a thread and execute a procedure without >> >> > the >> >> > thread's intervention or consent". >> >> > >> >> > That tells me they would behave like a UNIX developer would expect. >> >> > >> >> > Marc >> >> > >> >> > "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in >> >> > message news:eEO3XfOqHHA.3296(a)TK2MSFTNGP03.phx.gbl... >> >> >> ...actually, I don't suppose anyone knows how things like SIGINT >> >> >> are >> >> >> implemented in the POSIX sub-system under Windows. Do they even >> >> >> work >> > like >> >> >> a >> >> >> UNIX developer would expect? >> >> >> >> >> >> Tony Proctor >> >> >> >> >> >> "Gary Chanson" <gchanson(a)No.Spam.mvps.org> wrote in message >> >> >> news:O$s$jsDqHHA.4132(a)TK2MSFTNGP02.phx.gbl... >> >> >>> My solution for a similar situation was to redirect the > exception >> > to >> >> >> the >> >> >>> appropriate thread using a User APC. In my case, I can be > reasonably >> >> >>> certain that the task will enter an alertable state within a >> > reasonable >> >> >>> time, so this works very nicely and is a lot cleaner they your >> >> >> alternative. >> >> >>> >> >> >>> -- >> >> >>> >> >> >>> - Gary Chanson (Windows SDK MVP) >> >> >>> - Abolish Public Schools >> >> >>> >> >> >>> >> >> >>> >> >> >>> "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote > in >> >> >> message >> >> >>> news:eFnX5$BqHHA.1148(a)TK2MSFTNGP06.phx.gbl... >> >> >>> > Windows is not very good at handling this sort of asynchronous >> >> >>> > interrupt >> >> >>> on >> >> >>> > a single thread Emmanuel (i.e. similar to UNIX signals, or even > VMS >> >> >> ASTs) >> >> >>> > >> >> >>> > The question has been asked before: >> >> >>> > >> >> >>> >> >> >> >> > > http://groups.google.ie/group/microsoft.public.win32.programmer.kernel/browse_frm/thread/608ad10204f76515/1e175f06dca6106f?hl=en#1e175f06dca6106f >> >> >>> > >> >> >>> > I've even found myself in the same boat in trying to port a >> > language, >> >> >> and >> >> >>> > its framework, to the Windows O/S. In the end, I suspended the >> > thread, >> >> >>> read >> >> >>> > its context, redirected it to a point that would generate the >> > required >> >> >>> > exception, and then released it. Surprisingly, it worked OK in >> >> >>> > practice >> >> >>> > (although not on Alpha AXP H/W) but there were a few issues with >> > win32 >> >> >> api >> >> >>> > calls that had to be addressed (mentioned in that old thread) >> >> >>> > >> >> >>> > Tony Proctor >> >> >>> > >> >> >>> > "Emmanuel Stapf [ES]" <manus(a)newsgroups.nospam> wrote in message >> >> >>> > news:uQhAUi9pHHA.1144(a)TK2MSFTNGP02.phx.gbl... >> >> >>> > > Hi, >> >> >>> > > >> >> >>> > > I've a console single threaded application and I'm trying to >> >> >>> > > catch >> > a >> >> >>> > Ctrl+C. No >> >> >>> > > matter if I use SetConsoleCtrlHandler or a signal handler, my >> >> >>> > > code >> >> >>> > > to >> >> >>> > handle >> >> >>> > > this gets called in another thread. Is there a way to have the >> >> >>> > > handler >> >> >>> > called >> >> >>> > > from the main thread? >> >> >>> > > >> >> >>> > > In the code below, simply comment the call to `signal' or to >> >> >>> > > `SetConsoleCtrlHandler' to observe the similar behavior. On > Unix, >> >> >> using >> >> >>> > > `signal', it is called from the same thread. >> >> >>> > > >> >> >>> > > Thanks for any highlight, >> >> >>> > > Manu >> >> >>> > > >> >> >>> > > PS: this is shown by the code: >> >> >>> > > >> >> >>> > > #include <windows.h> >> >> >>> > > #include <stdio.h> >> >> >>> > > #include <signal.h> >> >> >>> > > >> >> >>> > > BOOL CtrlHandler( DWORD fdwCtrlType ) >> >> >>> > > { >> >> >>> > > switch( fdwCtrlType ) { >> >> >>> > > case CTRL_C_EVENT: >> >> >>> > > printf( "Ctrl-C event\n\n" ); >> >> >>> > > return TRUE; >> >> >>> > > default: >> >> >>> > > return FALSE; >> >> >>> > > } >> >> >>> > > } >> >> >>> > > >> >> >>> > > void handler (int sig) { >> >> >>> > > printf ("From Signal\n"); >> >> >>> > > signal (SIGINT, handler); >> >> >>> > > } >> >> >>> > > >> >> >>> > > void main( void ) >> >> >>> > > { >> >> >>> > > signal (SIGINT, handler); >> >> >>> > > //SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, >> >> >>> > > TRUE ); >> >> >>> > > >> >> >>> > > printf("Use Ctrl+C to see what is going on.\n" ); >> >> >>> > > while( 1 ){ } >> >> >>> > > } >> >> >>> > >> >> >>> > >> >> >>> >> >> >>> >> >> >> >> >> >> >> >> > >> >> > >> >> >> >> >> > >> > >> > >
From: Marc Sherman on 7 Jun 2007 13:10
From my Solaris days, IIRC, you're supposed to do the bare minimum in a signal handler. Kind of like win32's DllMain restrictions. Sticking to the "bare minimum" principal should work even in multithreaded POSIX apps, I believe. "Skywing [MVP]" <skywing_NO_SPAM_(a)valhallalegends.com> wrote in message news:e%23ZmnBSqHHA.3296(a)TK2MSFTNGP03.phx.gbl... > You may still have problems with stuff like the process heap lock. > Furthermore, I think you are still in danger even on a single threaded > system. From taking a quick look at the way the critical section > acquisition code works, it looks like if you interrupt > RtlEnterCriticalSection at the right place, you'll have the CS in an > intermediate state where it's owned but which thread owns it is not > established, such that recursive acqusition doesn't work. That means you > might be in for some trouble (race conditions resulting in a deadlock) if > you rely on recursive lock acqusition in your "signal handler" - hard to > avoid if you call anything that touches the process heap. > > Specifically, consider the tail end of the successful acquire path on > RtlEnterCriticalSection: > > ntdll!RtlEnterCriticalSection+0x11: > 00000000`76e52685 65488b042530000000 mov rax,qword ptr gs:[30h] > 00000000`76e5268e 488b4848 mov rcx,qword ptr [rax+48h] > 00000000`76e52692 c7420c01000000 mov dword ptr [rdx+0Ch],1 > 00000000`76e52699 33c0 xor eax,eax > 00000000`76e5269b 48894a10 mov qword ptr [rdx+10h],rcx > 00000000`76e5269f 4883c420 add rsp,20h > 00000000`76e526a3 5b pop rbx > 00000000`76e526a4 c3 ret > > If you suspend the thread at rip=00000000`76e52685 in this case, and then > alter context to something that tries to re-enter the same critical > section (say this is the process heap), the recursive acquire will > deadlock in RtlpWaitOnCriticalSection because the first acquire didn't get > around to marking the current thread as the owner of the critical section. > > (in that case, you might see a stack like this:) > > 0:000> k > Child-SP RetAddr Call Site > 00000000`0012fde8 00000000`76e4efc8 ntdll!NtWaitForSingleObject+0xa > 00000000`0012fdf0 00000000`76e4ee8b ntdll!RtlpWaitOnCriticalSection+0xd8 > 00000000`0012fea0 00000000`010018ef ntdll!RtlEnterCriticalSection+0xf4 > > > -- > Ken Johnson (Skywing) > Windows SDK MVP > http://www.nynaeve.net > "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in > message news:O7u2I4RqHHA.4536(a)TK2MSFTNGP05.phx.gbl... >>I see what you're saying Alexander, but it must depend to some extent on >>how >> closely interacting those threads are. For instance, an STA architecture >> wouldn't be nearly as sensitive as a close-knit MTA one >> >> Tony Proctor >> >> "Alexander Grigoriev" <alegr(a)earthlink.net> wrote in message >> news:u0k46rRqHHA.1208(a)TK2MSFTNGP02.phx.gbl... >>> A BIG BIG problem with asynchronous notifications is that in a >> multithreaded >>> process there is NO reliable interrupt point, other than explicitly >> provided >>> (alertable wait). Only a single-threaded POSIX application can be >>> interrupted at a random instruction without ill effects. >>> >>> "Marc Sherman" <masherman1970(a)yahoo.com> wrote in message >>> news:O1XaNaQqHHA.4520(a)TK2MSFTNGP04.phx.gbl... >>> > From "Windows Internals, 4th Edition" (p. 108) >>> > >>> > "The POSIX subsystem uses kernel-mode APCs to emulate the delivery of >>> > POSIX signals to POSIX processes". >>> > >>> > Also from the same page: >>> > >>> > "Kernel mode APCs interrupt a thread and execute a procedure without >>> > the >>> > thread's intervention or consent". >>> > >>> > That tells me they would behave like a UNIX developer would expect. >>> > >>> > Marc >>> > >>> > "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in >>> > message news:eEO3XfOqHHA.3296(a)TK2MSFTNGP03.phx.gbl... >>> >> ...actually, I don't suppose anyone knows how things like SIGINT are >>> >> implemented in the POSIX sub-system under Windows. Do they even work >> like >>> >> a >>> >> UNIX developer would expect? >>> >> >>> >> Tony Proctor >>> >> >>> >> "Gary Chanson" <gchanson(a)No.Spam.mvps.org> wrote in message >>> >> news:O$s$jsDqHHA.4132(a)TK2MSFTNGP02.phx.gbl... >>> >>> My solution for a similar situation was to redirect the >>> >>> exception >> to >>> >> the >>> >>> appropriate thread using a User APC. In my case, I can be >>> >>> reasonably >>> >>> certain that the task will enter an alertable state within a >> reasonable >>> >>> time, so this works very nicely and is a lot cleaner they your >>> >> alternative. >>> >>> >>> >>> -- >>> >>> >>> >>> - Gary Chanson (Windows SDK MVP) >>> >>> - Abolish Public Schools >>> >>> >>> >>> >>> >>> >>> >>> "Tony Proctor" <tony_proctor(a)aimtechnology_NoMoreSPAM_.com> wrote in >>> >> message >>> >>> news:eFnX5$BqHHA.1148(a)TK2MSFTNGP06.phx.gbl... >>> >>> > Windows is not very good at handling this sort of asynchronous >>> >>> > interrupt >>> >>> on >>> >>> > a single thread Emmanuel (i.e. similar to UNIX signals, or even >>> >>> > VMS >>> >> ASTs) >>> >>> > >>> >>> > The question has been asked before: >>> >>> > >>> >>> >>> >> >> http://groups.google.ie/group/microsoft.public.win32.programmer.kernel/browse_frm/thread/608ad10204f76515/1e175f06dca6106f?hl=en#1e175f06dca6106f >>> >>> > >>> >>> > I've even found myself in the same boat in trying to port a >> language, >>> >> and >>> >>> > its framework, to the Windows O/S. In the end, I suspended the >> thread, >>> >>> read >>> >>> > its context, redirected it to a point that would generate the >> required >>> >>> > exception, and then released it. Surprisingly, it worked OK in >>> >>> > practice >>> >>> > (although not on Alpha AXP H/W) but there were a few issues with >> win32 >>> >> api >>> >>> > calls that had to be addressed (mentioned in that old thread) >>> >>> > >>> >>> > Tony Proctor >>> >>> > >>> >>> > "Emmanuel Stapf [ES]" <manus(a)newsgroups.nospam> wrote in message >>> >>> > news:uQhAUi9pHHA.1144(a)TK2MSFTNGP02.phx.gbl... >>> >>> > > Hi, >>> >>> > > >>> >>> > > I've a console single threaded application and I'm trying to >>> >>> > > catch >> a >>> >>> > Ctrl+C. No >>> >>> > > matter if I use SetConsoleCtrlHandler or a signal handler, my >>> >>> > > code >>> >>> > > to >>> >>> > handle >>> >>> > > this gets called in another thread. Is there a way to have the >>> >>> > > handler >>> >>> > called >>> >>> > > from the main thread? >>> >>> > > >>> >>> > > In the code below, simply comment the call to `signal' or to >>> >>> > > `SetConsoleCtrlHandler' to observe the similar behavior. On >>> >>> > > Unix, >>> >> using >>> >>> > > `signal', it is called from the same thread. >>> >>> > > >>> >>> > > Thanks for any highlight, >>> >>> > > Manu >>> >>> > > >>> >>> > > PS: this is shown by the code: >>> >>> > > >>> >>> > > #include <windows.h> >>> >>> > > #include <stdio.h> >>> >>> > > #include <signal.h> >>> >>> > > >>> >>> > > BOOL CtrlHandler( DWORD fdwCtrlType ) >>> >>> > > { >>> >>> > > switch( fdwCtrlType ) { >>> >>> > > case CTRL_C_EVENT: >>> >>> > > printf( "Ctrl-C event\n\n" ); >>> >>> > > return TRUE; >>> >>> > > default: >>> >>> > > return FALSE; >>> >>> > > } >>> >>> > > } >>> >>> > > >>> >>> > > void handler (int sig) { >>> >>> > > printf ("From Signal\n"); >>> >>> > > signal (SIGINT, handler); >>> >>> > > } >>> >>> > > >>> >>> > > void main( void ) >>> >>> > > { >>> >>> > > signal (SIGINT, handler); >>> >>> > > //SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, >>> >>> > > TRUE ); >>> >>> > > >>> >>> > > printf("Use Ctrl+C to see what is going on.\n" ); >>> >>> > > while( 1 ){ } >>> >>> > > } >>> >>> > >>> >>> > >>> >>> >>> >>> >>> >> >>> >> >>> > >>> > >>> >>> >> >> > |