C++ Exception Handler problem - c++

I written an exception handler routine that helps us catch problems with our software. I use
SetUnhandledExceptionFilter();
to catch any uncaught exceptions, and it works very well.
However my handler pop's up a dialog asking the user to detail what they were doing at the time of the crash. This is where the problem comes, because the dialog is in the same thread context as the crash, the dialog continues to pump the messages of application. This causes me a problem, as one of our crashes is in a WM_TIMER, which goes off every minute. As you can imagine if the dialog has been on the screen for over a minute, a WM_TIMER is dispatched and the app re-crashes. Re-entering the exception handler under this situation is bad news.
If I let Windows handle the crash, Windows displays a dialog that appears to function, but stops the messages propagating to the rest of the application, hence the WM_TIMER does not get re-issued.
Does anyone know how I can achieve the same effect?
Thanks
Rich

Perhaps you could launch a separate data collection process using CreateProcess() when you detect an unhandled exception. This separate process would prompt the user to enter information about what they were just doing, while your main application can continue to crash and terminate.
Alternatively, if you don't want to start another process, you could perhaps create another thread with a separate message queue, that blocks your main thread from doing anything at all while the dialog is on the screen. While your main thread is blocked it won't have the opportunity to handle WM_TIMER messages.

Show the dialog in a second thread.
I had more or less the same problem (but had to show a message box rather than a dialog).
Write a class in which you create two events using the Win32 CreateEvent function. One event (trigger) is used to trigger the dialog, one event (ready) is to signal that the dialog was handled.
Add a method 'execute' to the class and start this method in a second thread
Let the 'execute' method wait until the trigger event is set, and if it is set show the dialog
After the dialog has been handled, set the 'ready' event.
If your application crashes in the main thread, prepare some information for the dialog (via setters in the class) and set the 'trigger' event, then wait for the 'ready' event. The set'ting of the trigger event will activate the second thread, and the main thread will block until the second thread has set the 'ready' event

Related

How pump COM messages in STA without pumping WM_PAINT?

I need to pump COM messages while waiting for an event to fix a deadlock. It's better to pump as few messages as possible just to process that COM call. The best candidate for this role is CoWaitForMultipleHandles but starting from Vista it pumps WM_PAINT in addition to COM messages. Pumping WM_PAINT is too dangerous for me from re-entrance perspective and I don't want to install a custom shim database as a solution for this problem.
I'm trying to pump COM messages sent to the hidden message-only window manually.
I have found two ways to get HWND of the hidden window:
((SOleTlsData *) NtCurrentTeb()->ReservedForOle)->hwndSTA using ntinfo.h from .NET Core. This seems to be undocumented and not reliable solution in terms of future changes.
Find window of OleMainThreadWndClass as suggested in this question. The problem is that CoInitialize does not create the window. It is created later on first cross-apartment call which may or may not happen in my application. Running the search loop every time I need HWND is bad from performance perspective but caching HWND seems impossible because I don't know when it's created.
Is there a way to determine if the hidden window is created for the current apartment? I suppose it will be cheaper than the loop and then I could find and cache HWND.
Is there a better way to pump COM messages without pumping WM_PAINT?
Update: you can force the window creation by calling CoMarshalInterThreadInterfaceInStream for any interface. Then call Co­Release­Marshal­Data to release the stream pointer. This is what I end up doing along with the search for OleMainThreadWndClass.
WM_PAINT is generated when there is no other message in the message queue and you execute GetMessage or use PeekMessage.
But WM_PAINT is only sent if you Dispatch it. Also there is no new WM_PAINT message until a window is invalidated again.
So it depends on you if you dispatch a WM_PAINT message or not. But be aware, there are other chances of reentrances like a WM_TIMER message.
The details about this are in the docs for WM_PAINT.
From my point of view the best solution would be to set you application in a "wait" mode, that even can handle WM_PAINT in this undefined waiting state. You know when you are reentered. It is always after a WM_PAINT... or similar messages that arrive like other input messages. So I don't see any problems here. An STA has one thread and you always process messages to an end, until you execute GetMessage, launch a modal dialog or show a MessageBox. When you are inside some message handling, nothing will disturb you.
Maybe an other solution would be to wait inside a second thread for this event. This thread may not have any windows and you can translate the event to anything you need in your application.
So you question may not have enough information how this deadlock really appears. So this answer may not be sufficient.
After writing als this I tend to the opinion that this is an XY problem.

how to access mfc controls using messages?

I would like to access drag slider control of my dialog box from worker thread. I read many warnings regarding accessing main window controls from worker thread. Since they have a high chances of resulting in a dead lock. In this case, how to access the control using messages? I know how to create user defined messages (WM_USER) and write our own handlers. What it would like to know is that is there any system defined message for each controls and if it is there, how to post those messages to access the control?
You can use PostMessage to send a message to the control and the main UI thread will actually dispatch the message to the control, ie the work will happen on the UI thread (assuming the UI thread is pumping messages). Looking at afxcmn.inl you can see what SetPos is doing:
_AFXCMN_INLINE void CSliderCtrl::SetPos(_In_ int nPos)
{ ASSERT(::IsWindow(m_hWnd)); ::SendMessage(m_hWnd, TBM_SETPOS, TRUE, nPos); }
Changing that for PostMessage:
::PostMessage(hSlider, TBM_SETPOS, TRUE, nPos);
If you want something more complicated post a WM_USER message to a the parent window and handle your control managing functionality there because, again, the WM_USER message will be dispatched by the UI thread so you can work with your control safely.

Catch a moment when window message is put into queue

I have a 3rdparty application (target), which creates a window. I embed that window into my own application by setting parent, changing styles, etc.
The problem is that Spy++ shows target receiving WM_DESTROY two times (in case I close my app). Sometimes this leads to crash of the target.
I want to understand, why the message queue contains 2 WM_DESTROY associated with target window (btw, only 1 WM_NCDESTROY).
To do that I was setting breakpoints at DestroyWindow, PostMessage syscalls, but these functions appear not to be called for the main target window (first one is called only for child windows, second one - with different messages, except WM_DESTROY). I did that in context of both my process and the target process.
So the question is, is there any low-level function which puts messages into the thread message queue? I want to put breakpoint at it and catch a moment when the extra WM_DESTROY is put there.
Smth like PostThreadMessageInternal...
Thanks in advance!

Run custom code when MFC app is terminated: d'tor or WM_CLOSE?

I have a dialog-based MFC application which needs to stop Windows Wifi service in order to run correctly, but I want to enable it again when my application exits.
So I thought I'd put the code that restarts the service in the destructor of the main dialog class.
Now it has come to my attention that others put their code which should be run during program termination into a WM_CLOSE message handler.
Both ways seem to work, but I would like to know if there are downsides to either way.
For MFC dialog based application you can place finalization code to application class InitInstance method, immediately after main dialog DoModal call. For other MFC application types (MDI, SDI) finalization code is usually placed to ExitInstance method.
The difference between dialog based application and SDI/MDI applications, is that InitInstance in dialog based applications returns FALSE, and application exits - all action is done in the main dialog DoModal call.
You can prefer to use ExitInstance for all application types, it should work as well.
Edit. If you want to make cleanup code inside of the dialog class, WM_DESTROY (already mentioned by Roger Rowland) is better place than WM_CLOSE. Sometimes we can handle WM_CLOSE message and prevent a dialog to be closed, for example, by asking "Exit the program? Yes - No". In the case you want to use some child windows, they exist in WM_CLOSE and WM_DESTROY message handlers, and don't exist in a dialog destructor. Also, message queue doesn't exist when main dialog destructor is called, so you should not use Windows messaging in this case.
Aim to maintain symmetry: if you are stopping the wifi service in a constructor, then restart it in the same class's destructor. If instead you stop the service in InitInstance, you would restart it in ExitInstance; if as a response to WM_CREATE or some other message, then restart it in WM_CLOSE, etc.
Constructors and destructors have no way of returning an error status, so normally they are better suited for simple tasks such as initialization and memory allocation/deallocation.
InitInstance and ExitInstance, as well as windows messages such as WM_CLOSE, happen at a good spot in the application's lifetime to display error messages if necessary, or to abort in response to error conditions.

Run windows GUI application in synchronized mode?

I am debugging GUI app on windows and I want to find out who is the sender of some message. On linux, I can run app in synchronized mode and find the sender in call stack. Is there any equivalent mode in windows?
AFAIK there's no built-in ability to do this.
But let's first investigate the problem. You want to know who's the sender of the message. You should know however that windows message processing can be classified by the following criterias:
Posted vs Sent messages (PostMessage vs SendMessage).
Messages sent to the window belonging to another thread vs sender thread.
Messages posted to a thread (not bound to a specific window, hence not processed by the window procedure).
You may trace directly the sender only when the message is sent (not posted) to a window, whereas the call to the SendMessage (or similar) was issued in the thread to which the window belongs. In such you will see the sender in the call stack.
In case the message was sent from another thread - you will not see it in the call stack. Simply because the call stack shows the call chain that belongs to the current thread only. When a message is sent from another thread the system performs the following:
Suspends the caller thread.
Puts this message to the queue of the thread that owns the window.
When that thread calls GetMessage (or similar) - the message is dispatched to the window.
Finally the OS resumes the caller thread. The SendMessage returns with the result that was returned by the window procedure.
In such a case you may try to identify the caller indirectly. Interrupt your program with the breakpoint, and try to search for suspended threads, which are blocked in a call to SendMessage or similar.
Finally, messages that are posted are impossible to trace by the above method. You may try to put a conditional breakpoint on a call to PostMessage, but if the caller belongs to another problem - this will be more complex.
valdo is correct. Calls to SendMessage call your applications wndproc directly. Calls to PostMessage posts the message to the message que and your application then recives the message via the message pump (the loop, getmessage, translatemessage, dispatchmessage). So , like he said, if the messages were sent via a SendMessage then the callee of the function will show in the call stack. If it was sent via PostMessage , it will not.