I know Windows seperatly builds a Structered Exception Handling Chain for each running thread within a process. I was wondering if with veh, the registered exception handler will be called process wide (no matter in what threat the exception occured) or was also registered on a per thread basis?
Yes, vectored exception handlers are process wide.
From MSDN:
An application can register a function to watch or handle all
exceptions for the application. Vectored handlers are not frame-based,
therefore, you can add a handler that will be called regardless of
where you are in a call frame.
New Vectored Exception Handling in Windows XP by Matt Pietrek states:
The handler list is not tied to any thread, and is global to the
process.
Related
TL;DR
(Visual Studio 2019, Windows 10 (so far tested on 1809LTSC, because this is my dev machine)
We have an out-of-process COM server
We set COMGLB_EXCEPTION_DONOT_HANDLE_ANY
"Fatal" SEH exceptions are handled OK.
"Non-Fatal" SEH exceptions, among these C++ excpetions, are randomly swallowed or handled by the COM/RPC runtime stack.
Does COMGLB_EXCEPTION_DONOT_HANDLE _ANY work reliably? Are there any additional settings?
Neccessary Background
When using COM, the RPC layer will catch (and possibly swallow) all Structured SEH Exceptions (which include C++ exceptions). Raymond explains this very well:
Historically, COM placed a giant try/except around your server’s
methods. If your server encountered what would normally be an
unhandled exception, the giant try/except would catch it and turn it
into the error RPC_E_SERVERFAULT. It then marked the exception as
handled, so that the server remained running ... Mind you, this was
actually a disservice
Now there is a supposed solution, namely IGlobalOptions with setting COMGLB_EXCEPTION_DONOT_HANDLE_ANY.
This is supposed to (to quote The Old New):
... then go ahead and let the process crash.” In Windows 7, you can
ask for the even stronger COMGLB_EXCEPTION_DONOT_HANDLE_ANY, which
means “Don’t even try to catch ‘nonfatal’ exceptions.”
You can even find this recommendation in the docs:
It's important for applications that detect crashes and other
exceptions that might be generated while executing inbound COM calls,
... to set COMGLB_EXCEPTION_HANDLING to COMGLB_EXCEPTION_DONOT_HANDLE
to disable COM behavior of catching exceptions.
And the option is explained as:
COMGLB_EXCEPTION_DONOT_HANDLE_ANY:
When set and a fatal exception
occurs in a COM method, this causes the COM runtime to not handle the
exception. (caveat A)
When set and a non-fatal exception occurs in a COM method, this causes
the COM runtime to create a Windows Error Reporting (WER) dump and
terminate the process. Supported in Windows 7 and later. (caveat B)
And here's the thing
Neither of the above two statements is really accurate, but specifically for any non fatal exception, which C++ exceptions are, we get random behavior:
I have set up a simple client / server COM Test Program in VS2019 and intentionally generate an unhandled C++ exception: There are two modes at runtime, seemingly at random:
Server is terminated by the COM/RPC stack and we get an ID 1000 entry in the event log with the exceptioncode 0xe06d7363 (and a WER dump is written). The client gets 0x800706BE HRESULT in this case.
This is the advertised behavior.
Starting the client -> server a second (or third, ...) time, the C++ Exception DOES NOT terminate the server, and the client gets 0xe06d7363 as HRESULT for its server call. No event log entry written!
For those "fatal" SEH exceptions the termination happens reliably; but not for the non-fatal ones.
What is going on here?
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.
In x86 you can simply register your handler with the following 3 instructions.
push addrOfExceptionHandler
push dword [fs:0]
mov [fs:0],esp
But this doesn't work on 64 bit Windows.
I have read the x64 exception handler is table based and Visual C++'s __try and __except blocks are hard wired into the exception directory. Does this mean the Microsoft totally dropped this old method? Is there a way to register handlers programatically from code then?
Windows x64 uses table-based exception handling (unlike x86 where frame-based handling is used).
Every image has a table of RUNTIME_FUNCTION structures associated with it (typically generated by compiler). The structure basically describes a function (or its part) in image and contains information about how to unwind stack in that function. It may also contain information about exception handler that should be called within the function.
When an exception occurs system finds a table that belongs to the image where exception occurred and uses the table to walk/unwind stack until it hits exception handler that could handle the exception.
This means you cannot use [fs:0] for exception handler registration anymore.
Though it is possible to generate RUNTIME_FUNCTION tables for loaded/generated image and then register it via RtlAddFunctionTable or RtlInstallFunctionTableCallback API.
You can find good articles about Windows x64 exception handling at Nynaeve's blog.
Also MSDN contains and article about structures used for Exception Handling (x64).
I want to create a window and show some image display (like animation based on SetTimer()) on window created using CreateWindow() function. But it should be created on separate thread and should remain alive until user closes this. I tried but was unsuccessful.
EDITED
I just googled I found this link How To Create Windows in a Multithreaded Application but one thing i want to know when Window Procedure get invoked. if it is invoked by system then how i can call it from my child thread.
Windows (represented by HWNDs) in Windows have a thread affinity. Their WindowProc is always invoked in the context of the thread they are created with.
As such, they are a convenient way to serialize calls between threads as the PostMessage and SendMessage APIs can be called from any thread in the application, but the WindowProc will get executed in the context of the original creating thread.
Because WM_TIMER messages posted to message queues are the mechanism by which SetTimer works, again you need to be careful when calling SetTimer in a multithreaded app - The timer messages will be processed by the calling thread (if the hwnd parameter is NULL) or the window's thread.
You also, as a result, have to be careful to put a message loop on every thread that might create windows, or want to process timers.
Keep your user-interface on the main Windows thread. Setting a timer using the Windows API doesn't require an additional thread (as your WndProc will get the timer message WM_TIMER).
Even if you have a long running task to perform that might necessitate the use of an additional thread, keep the window on the main thread, do your work in the worker-thread and post back to the main thread with updates.
When running a Delphi application outside the debugger most exceptions that occur seem to be silently ignored (like an access violation). Sometimes however there appears the Windows error reporting dialog (send or not send, you probably know what I mean). What exactly does this mean? What errors trigger this behaviour?
Additional info: I have a global exception handler for my application that should log all unhandled exceptions. So, no exceptions should leave the application unhandled.
Thanks.
Most exceptions are not silently ignored when running outside the debugger. They are normally caught by the event loop in VCL applications, or fall through to the main begin/end in console applications, etc. The default aciton of the VCL event loop is to display a dialog containing the message associated with the exception.
It's if the exception escapes the application, either by reaching the main begin/end without being caught, or not being caught by the event loop, that the Windows error reporting steps in - functionally, it is an exception handler just like any other except at the very base of the stack.
It covers exceptions that are not handled by the application - if an exception propagates outside of the main entry point of the app, then WER will step in. This covers things like AVs, divide by zero, invalid handle access and other out of band or "chip" exceptions. Sometimes your code can attempt to handle those things, but if memory is corrupted too badly or what have you, then your code will die.
You will generally get problems if you have exceptions in threads that are not handled in the Execute method. The program will mostly be killed, but the behaviour is unpredictable and seems to depend on many things (like the number and state of other threads). Often the main window vanishes immediately, and any further exceptions will thus not be handled by the program, and this is probably what causes WER to catch them.
I made it a habit to have an outer exception handler in Execute that logs any unhandled exceptions and allows the thread to terminate cleanly.
Exceptions occurring in initialization and finalization sections would escape your global exception handler and trigger WER.