What happens to an ActiveX control (COleControl) after the call to OnDestroy()? - c++

I have an ActiveX control written in C++ that runs in Internet Explorer 8. Most of the time (approx 90%) when the tab or browser containing the control is closed, there is an access violation like this:
The thread 'Win32 Thread' (0x1bf0) has exited with code 0 (0x0).
Unhandled exception at 0x77b3b9fd in iexplore.exe: 0xC0000005: Access violation reading location 0x65007408.
The access violation occurs after the call to OnDestroy() but before the call to the control's destructor.
The debug output says:
No symbols are loaded for any call stack frame. The source code cannot be displayed.
None of my code is present in the stacktrace, although perhaps the heap was corrupted at some earlier point during execution.
What lifecycle events does an ActiveX control receive between the call to OnDestroy() and the control's destructor?

As I understand, there is no strictly event lifecycle for an ActiveX, it depends on host side. If your control is used with some AJAX framework, for example, after OnDestroy() can be called OnCreate() without calling destructor. So, make sure you don’t have uninitialize actions inside OnDestroy() handler.
You can load control in ActiveX Control Test Container and play with Activate/Deactivate, maybe it will be helpful.
Enable Application Verifier from debugging tools for windows and make sure your debugger downloads OS debug symbols. In this case stack trace will be more informative.

Related

What could be the cause of a program crashing without notice?

I have a C++ application that suddenly stops working when I do a certain action (clicking at a button in gtk). I tried debugging it, creating Signal Handlers for SIGTERM, SIGABORT, SIGILL, etc to write a backtrace with the gcc functions, tried to attach a debugger, etc. Nothing. I just do not get any output from anything, the program just vanishes from the memory.
Are there any techniques I have not tried yet? I dont know how to debug this problem.
I forgot to mention: This happens on a Linux system (tried debian and ubuntu). Both with X11 (not wayland)
It could be:
A signal. By default, gdb stops on error signals, so no custom handler is needed.
exit() function and any other function from exit family (like _exit, _Exit , etc.). Use b exit to set a breakpoint.
Since it's c++, and exception could be thrown. Use catch throw to stop when an exception is thrown.
The last thread exit. b pthread_exit.
Thread cancellation. b pthread_cancel.
main function normally reached its end. Use disassembly to set a breakpoint on address.
If all of this doesn't help, attach to your application before the button is pressed, pause it with Ctrl+c in gdb. Then, press the button (while the window is unresponsive). A gtk application should normally dispatch the event from X11 queue even if it was paused. Do step by step assembly debugging with ni and si.

Untidy program exit: MFC C++

I have an MFC C++ program that occasionally crashes on an error exit for no apparent reason. My specific query is in the following:
In my overload of InitInstance() there are various checks, as well as setting up resources like events and semaphores. When a normal exit is requested by the user, there is an OnDestroy() message handler that closes everything out, including freeing resources, etc. That bit works fine.
The problem occurs when one of the checks in InitInstance() fails, and the function returns value 0 (causing a program exit). My question is this: In that event, is OnDestroy() automatically called to clean things up, or do I need to run it myself before exiting InitInstance?
If a main window window already exists you should destroy it before, using DestroyWindow. And no, it is not automatically destroyed when InitInstance is exited with FALSE. ExitInstance is executed, but existing windows will closed when the application exits.
Anyhow normales resources like files and memory are freed when the application exists.

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.

CFileDialog delayed crashing

I have added an "Open file" dialog to my dialog-based MFC application. Now, exactly one minute(!) after an open file dialog is closed by pushing either Open or Cancel button my application crashes. While it crashes, the following things are happening in the output:
1) a bunch of Windows threads are exiting;
2) a bunch of COM exceptions (of 0x80010108 "the object invoked has disconnected from its clients" and 0x800401FD "Object is not connected to server" variety) are being thrown;
3) finally, an unhandled exception occurs: 0xC0000005: Access violation reading location 0xfeeefeee, with call stack pointing to ole32.dll.
To say that I am bewildered is quite an understatement. The code for invoking the dialog is as follows:
CFileDialog fileDlg( TRUE, _T(".txt"), NULL, OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,
_T("Text file (*.txt)|*.txt||"), this);
INT_PTR res = fileDlg.DoModal();
What could cause such a thing?
How do I even debug it?
I had this exact issue in Windows 7 x64, and by enabling breakpoints on all Win32 exceptions not already chosen (in the VS2015 exceptions tab), I was able to narrow it down to a known issue with fundisc.dll that was resolved with an optional Hotfix from Microsoft: https://support.microsoft.com/en-us/kb/2494427
It also resolved issues on my PC of File Explorer windows crashing at seemingly random times. All were caused by some deadlock in the networking COM objects that is fixed by that hotfix.

Windows messages serviced whilst assert dialog is being displayed?

I have an MFC application that spawns a number of different worker threads and is compiled with VS2003.
When calling CTreeCtrl::GetItemState() I'm occasionally getting a debug assertion dialog popup. I'm assuming that this is because I've passed in a handle to an invalid item but this isn't my immediate concern.
My concern is: From my logs, it looks as though the MFC thread continues to service a number of windows messages whilst the assert dialog is being displayed. I thought the assert dialog was modal so I was wondering if this was even possible?
The message box that shows the assertion failure has a message pump for its own purposes. But it'll dispatch all messages that come in, not just those for the message box (otherwise things could get blocked).
With a normal modal dialog, this isn't a problem because the parent window is typically disabled for the duration of the dialog.
The code that launches the assertion dialog must've failed to figure out the parent window, and thus it wasn't disabled. This can happen if your main window isn't the active window at the time of the assertion. Other things can go wrong as well.
You can change how Visual Studio's C run-time library reports assertion failures with _CrtSetReportMode. You can make it stop in the debugger and/or log to the output window instead of trying to show the dialog.
Dialogs (even a messagebox) need to pump the message queue, even if they're modal. Otherwise how would they know you clicked on the "OK" button?
If you need to stop everything when an assert triggers it's usually not too difficult to write your own implementation of assert() (or ASSERT() or whatever) that will break into the debugger instead of displaying a messagebox that asks if you want to break into the debugger (maybe only if it determines that the debugger is attached).