From: Gary Chanson on
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
Are you sure that is really correct? As far as I know, the (only) behavior
is that CSRSS creates an ephemeral worker thread in the target process, via
CreateRemoteThread, which calls the registered ctrl routine list and
performs the action returned by it. I do not believe that ctrl-c really has
much, if anything to do with APCs.

--
Ken Johnson (Skywing)
Windows SDK MVP
http://www.nynaeve.net
""Jeffrey Tan[MSFT]"" <jetan(a)online.microsoft.com> wrote in message
news:Aw8mKdBqHHA.3736(a)TK2MSFTNGHUB02.phx.gbl...
> Hi Emmanuel ,
>
> I do not think Windows has exposed any interface for configuring this. As
> I
> dig into the code, this behavior is by design. After the OS captured the
> Ctrl+C interrupt, it will initiate a user-mode APC to schedule another
> thread to call Kernel32!CtrlRoutine function, which finally calls your
> registered "CtrlHandler".
>
> Based on my knowledge, this type of asynchronous callback in Windows
> normally comes in 2 forms:
> 1. Windows created a second thread to call the callback function.
> 2. Main thread in the application calls certain type of Wait*** functions
> in a loop to retrieve the asynchronous notification. (This is because,
> the
> callback notification can not interrupt the main thread without at a safe
> point. ). I/O completion port uses this form
>
> Since there is not guarantee that the console application main thread will
> alway have a loop to call Wait*** functions, console handler uses the
> first
> form.
>
> Thanks.
>
> Best regards,
> Jeffrey Tan
> Microsoft Online Community Support
> ==================================================
> Get notification to my posts through email? Please refer to
> http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
> ications.
>
> Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
> where an initial response from the community or a Microsoft Support
> Engineer within 1 business day is acceptable. Please note that each follow
> up response may take approximately 2 business days as the support
> professional working with you may need further investigation to reach the
> most efficient resolution. The offering is not appropriate for situations
> that require urgent, real-time or phone-based interactions or complex
> project analysis and dump analysis issues. Issues of this nature are best
> handled working with a dedicated Microsoft Support Engineer by contacting
> Microsoft Customer Support Services (CSS) at
> http://msdn.microsoft.com/subscriptions/support/default.aspx.
> ==================================================
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>

From: Skywing [MVP] on
This seems a bit fishy and not-recommendable to me... Get/SetThreadContext
when you are in a system call will not have the expected result, some of the
volatile registers (which might be parameter registers for fastcall, or even
more problematic on x64) will be overwritten on return from the system call.
And setting the context will not take effect until the system call returns
anyway. There is also the problem that you don't have a way to wake a
thread that was sleeping.

Furthermore, if you happen to catch a thread "at a bad time", such as when
it owns an important lock (or even worse, is in the middle of acquiring an
important lock, like the critical section for the process heap, such that
you break recursive acquisition of it), you're likely to break the process
(deadlock).

--
Ken Johnson (Skywing)
Windows SDK MVP
http://www.nynaeve.net
"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
Obviously it checked for a thread currently in a wait state Ken, and - as
the old thread says - it relied on correct exception handling elsewhere to
release any locks/resources held at the point of interruption. I agree
though that it's not really recommenable in the general case. The only
reason it worked for me was probably because the code was C (not C++ so less
resource ownership issues), and I ended up wrapping every system call as
indicated, just in case (which was easy because all the low-level runtime
support had been abstracted for portability anyway)

Tony Proctor

"Skywing [MVP]" <skywing_NO_SPAM_(a)valhallalegends.com> wrote in message
news:%23b$LUGFqHHA.3892(a)TK2MSFTNGP05.phx.gbl...
> This seems a bit fishy and not-recommendable to me...
Get/SetThreadContext
> when you are in a system call will not have the expected result, some of
the
> volatile registers (which might be parameter registers for fastcall, or
even
> more problematic on x64) will be overwritten on return from the system
call.
> And setting the context will not take effect until the system call returns
> anyway. There is also the problem that you don't have a way to wake a
> thread that was sleeping.
>
> Furthermore, if you happen to catch a thread "at a bad time", such as when
> it owns an important lock (or even worse, is in the middle of acquiring an
> important lock, like the critical section for the process heap, such that
> you break recursive acquisition of it), you're likely to break the process
> (deadlock).
>
> --
> Ken Johnson (Skywing)
> Windows SDK MVP
> http://www.nynaeve.net
> "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: "Jeffrey Tan[MSFT]" on
Hi Ken,

Thank you for sharing your thought.

Actually, if I remember correct, all the CreateThread(CreateRemoteThread)
goes into the kernel and created the kernel-mode thread structures,
finally, kernel will initiate a user-mode APC to return control to the
user-mode. Then user-mode will resolve this user APC by executing
kernel32.dll!BaseThreadStart(). Sorry, I did not check the root cause of
who called CreateThread(CreateRemoteThread).

Anyway, my key point in the reply is the second paragraph.

Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.