Experiencing intermittent issues, related to named events when processes are running in different user contexts: WaitForSingleObject (and WaitForMultipleObjects too) for such event handle fails with WAIT_FAILED (GetLastError returns 6 - Invalid handle value).
We have an application to schedule tasks on Windows machines under user accounts, and issue happens after some tasks are completed.
Service part of application (JobManager) starting executable (JobLeader) under user account (CreateProcessAsUser) to run user task, and waiting for named event to be signaled.
Manual reset named event is created by JobLeader in the "Global\" namespace and signaled when user task is completed.
JobManager waiting in the loop, calling WFMO(WaitForMultipleObjects) with delay of 10 seconds, to see if named event or JobLeader process handle are signaled.
Periodically named event handle, opened by JobManager through OpenEvent API call, causes WFMO (WFSO is also called after to identify which handle is broken) to return WAIT_FAILED, with error code 6 - "Invalid handle value".
After reopening the event, this error may gone, or may not - WFMO may again returns WAIT_FAILED because of invalid handle value.
Interesting, that it may pass few dozens tasks without this error, and then - sequentially few tasks have it. Tasks used for testing are identical - just a cmd.exe script, dumping environment.
Anyone have ideas about this?
Regards,
Alex
Do you create the event in your JobManager and then open it in the 'JobLeader'? If not, how do you communicate the event handle (and/or name) between the two processes?
My gut tells me it's a race condition...
Related
Fellow experts!
I have faced the following dilemma: some of our tools (executables) are started as scheduled tasks, some are started as services and others as usual desktop apps with interactive Windows user. We are using the code sharing strategy for source management (this is not debatable for this question).
So the solution I want to find is the following:
Detect UI operation at run-time which leads to hanging service/background task (such as say call to Application.ShowException, ShowMessage, MessageDialog, TForm.Show etc.). And when such an action detected I want to raise the exception instead. Then the operation will fail, we will have stack trace etc. but the process will not hang up! The most problematic hang up is when some event processing is done in transaction and then in some of the code used to process event suddenly (because of error in code, design, whatever) there is UI code executed then the process hangs and the DB parts can be locked!
What I think I need to do is: Use DDetours library to intercept WinAPI calls to a certain routines and raise exception instead (so that the process does not hang, but just fail in some method). Also I know that the creation of forms and windows does not hang the app, but only the tries to show them to the user.
Is there some known method of handling this problem? Or maybe there is some list of WinAPI routine set which hangs in service mode?
Thank you in advance.
I want to run a process from the control room. On dragging the process to the only resource I have available, I get the error message: [Resource] is too busy to run that process. I have retired the other processes I used to run in the control room, set the business objects I use in the process I want to run as Exclusive to get highest priority, but I am still not able to run my process because my resource is still busy. How can I solve this?
Screenshot here: Busy Resource
Thanks!
the most common cause of that error is that there is "pending" session already waiting for the resource. Remove all filters from the bottom view and check if there's no pending session waiting for your "start" action.
I want to be able to catch any attempts of executing exit()/ExitProcess()/TerminateProcess() or any other such calls.
I thought about registering a handler with atexit(). This works fine for normal program termination (return from main()) or exit() calls (regardless of the thread that calls exit()), but ExitProcess() and TerminateProcess() bypass the handler I registered.
ExitProcess() documentation states:
Note that returning from the main function of an application results
in a call to ExitProcess.
But the observed behaviour is at least different in this regard.
Is there a method of registering a handler for process exit/termination what will always be called (except for external calls to TerminateProcess(), unhandled exceptions thrown by one of my threads or __failfast() calls, I'm guessing these are really impossible to catch).
There is the dirty option of hooking ExitProcess(), but I'd rather not do that.
EDIT: just so this is clear: I'm interested in my own process, not monitoring / controlling another process.
There is a Kernel Mode Event a device driver can subscribe to in order to get notifications of terminations of processes. This is preferred over trying to inject a DLL into processes for API hooks due to the myriad number of internal and external ways that process may end.
I'm working on a C++ Windows application, that runs as a process but not a windowed application (does not have WndProc). It has it's own message loop, which is used to process a quit message, and that's how we safely exit the application from within it's self.
What I want to do is somehow send a message to the process from another process, in order to tell the process to exit safely.
In Linux, we would do this by trapping signals, but I'm not sure how it's done on Windows.
PostThreadMessage can post messages to threads without requiring a window proc.
In the first process, do a GetCurrentThreadId to get a system wide id for the current thread. And somehow get that id to the second app.
In the second app, OpenThread will convert to a thread handle, that you can then use with PostThreadMessage.
Do note that if your 'windowprocless' application ever pops up a message box, the message box enters its own modal message loop, which will silently destroy any thread messages. If any kind of window is ever created on the thread you would be far better off creating an invisible message window that messages can be sent to to control the app.
Do you have the control over both processes i.e., do you have the code of both processes? If yes I suggest to expose a API to exit safely.
Our code library needs to be notified when the application is exiting. So we have subscribed to the System.Window.Forms.Application.ApplicationExit event. This works nicely for Winforms apps, but does it also work for other types of applications such as console apps, services, and web apps (such as ASP.NET)? The namespace would suggest that it doesn't, and it presumably gets raised when Application.Exit() is called (explicitly or implictly), which may not be correct to call for these other cases.
Is there some other event which would be better in these other cases or which would be more universal (great if it works for Winforms, too)? For example, is there an event for when Environment.Exit() is called (console app)?
I found a mention of an Exited event in System.Diagnostic.Process, but this appears to be for monitoring the exit of another process, and it does not appear to be received by a process about itself (for example, Process.GetCurrentProcess().Exited += Process_Exited; Process.GetCurrentProcess().EnableRaisingEvents = true;). I would think it might only be raised after the process has actually exited, so that wouldn't work.
This is particularly for .NET 2.0 and C#.
We finally found more about this (but by then my machine had been rebuilt and lost the cookies to my unregistered profile here; hopefully, it will let met post this answer).
Further investigation eventually found a few more events which we have found helpful:
System.Windows.Forms.Application.ThreadExit - Fires when a message loop exits
System.Windows.Forms.Application.ApplicationExit - Fires when all message loops exit
System.AppDomain.CurrentDomain.DomainUnload - Fires when a domain other than the default exits
System.AppDomain.CurrentDomain.ProcessExit - Fires when the default app domain exits
System.AppDomain.CurrentDomain.UnhandledException - Fires when an uncaught exception occurs, ending the app.
Only one of the DomainUnload or ProcessExit events are possible for a given app domain, depending on whether it is the default (top-level) domain for the process or was created as a subdomain (eg. on a web server). If an application doesn't know which it might be (as in our case), it needs to subscribe to both if it wants to catch the actual unload for itself. Also, it appears that UnhandledException (which as of .NET2.0 is always fatal) may prevent the other two events, so that may be a third case to handle. These three events should work for any .NET application.
There is a caveat that the execution time for ProcessExit is bounded (about 4 seconds?), so it may not be possible to do extensive "final" work in that event handler. It needs to be something which can be done quickly.
The Application events only apply to WinForms applications (we suspect they may not apply in pure WPF applications, however). The naming can be misleading because they are named for their most basic normal usage which has certain assumptions. ThreadExit does not relate to the actual System.Threading.Thread but rather to the message loop (Application.Run())) of a UI thread, and ApplicationExit similarly relates to the collection of application Forms on one or more UI threads. Normally, once the call to Application.Run() returns, called from the entry method of a thread, the entry method quickly concludes and the thread itself then ends. And once all UI threads have exited, a WinForms app is usually all done and exits.
Another event of note is the System.Windows.Forms.Application.ThreadException event. A Windows message loop can be configured to catch exceptions which occur in handling a message and send this event rather than let them be uncaught (and thus fatal) exceptions. Catching these exceptions allows the message loop (and that UI thread) to continue running (after aborting the current message handler). There can be only one subscriber to this event at any time for a given thread (subscriptions overwrite any previous subscriber), and it must be configured before any Form is created and subscribed before entering the message loop. See the MSDN help for this event and System.Windows.Forms.Applicaton.SetUnhandledExceptionMode() for more info.