Emiting code with Exception support - winapi

I need to generate code at runtime that do the following:
auto v_cleanup = std::shared_ptr<void>(nullptr, [](void *){ cleanup(); });
//...
do_some_danger_thing();
//...
or C equivalent:
__try {
//...
do_some_danger_thing();
//...
} __finally {
cleanup();
}
The cleanup() function is guaranteed to be exception free, however do_some_danger_thing() may throw exception. This runtime code MUST not use stack, which means when calling do_some_danger_thing() the stack must in the same status as when we enter the runtime code, except that the return address set to the runtime code (the original value was saved to a "jmp" target, in order to return to the caller).
Because we are using dynamic machine code, the target platform is fixed to WIN32 on x86 CPU, the x64 CPU is not currently in focus.
To do this we have to process any exceptions. In WIN32 C++ exception is SEH based, so we have to due with it. The trouble is that we cannot find a way to do this and make it compatible with other code. We have tried a couple of solutions but none of them works, sometimes the user-installed exception handler was never called, sometimes the outer exception handlers was bypassed and we received an "unhandled exception" error.
UPDATE:
It seems to be the case that SEH exception handler chain supports code within the EXE image only. If the exception handler pointed to my generated code it will never been called. What I have to do is to create a static exception handler function stub, and then let it call the generated handler.

I am now have an implementation that is slightly different with the above. Actually, the pseudo code looks like (in C++11):
std::exception_ptr ex;
try {
//...
do_some_danger_things();
//...
} catch (...) {
ex = std::current_exception();
}
cleanup();
if(ex)rethrow_exception(ex);
This is not 100% the same as the above C equivalent because the call of cleanup() occurs before stack unwinding, usually this is not a problem, but the exact exception context could be lost.
I implemented an internal exception handler as the helper function, like the following:
_declspec(thread) void *real_handler = nullptr;
void **get_real_handler_addr(){
return &real_handler;
}
__declspec(naked) int exception_handler(...){
__asm {
call get_real_handler_addr;
mov eax, [eax];
jmp eax;
}
}
The trick here is that this handler must not be generated at runtime, so the stub has to find out where the "real" handler is. We use a thread local storage to do this.
Now the generated code will get the exception handler chain from FS:[0]. However, the chain must be stack based so I use the following code to replace the handler:
void **exception_chain;
__asm {
mov eax, fs:[0]
mov exception_chain, eax
}
//...
void *saved_handler = exception_chain[1];
exception_chain[1] = exception_handler;
*get_real_handler_addr() = generated_code->get_exception_handler();
The generated exception handler can then do the cleanup. However, in case that any current exception handler returns EXCEPTION_CONTINUE_SEARCH, the handler will be called twice. My strategy is just restore the original exception handler within the first call.

Related

How to print stacktrace once an exception is thrown before the catch block (stack unwinding)

Let's say we have the following code:
#include <exception>
void funcA() {
funcB();
}
void funcB() {
funcC();
}
void funcC() {
funcD();
}
void funcD() {
throw std::runtime_error("Exception!!"); //3
}
void funcE() {
int * p;
delete p; //4
}
int main (int argc, char **argv) {
try {
funcA(); //1
} catch (std::exception exc) {
std::cerr << exc.what() << endl; //2
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
I want to print the stack trace with the line number of the thrown exception in a multi-threaded efficient way.
I've been checking the last couple of days the solutions and approaches people are doing but unfortunately nothing was useful in my case. I can use for example the boost library boost::stacktrace::stacktrace() in //2 or any other library but the problem here is I have to catch the exception to do this and this approach is not efficient if your code has hundreds of nested functions. You can't just go over all of them and wrap each one with try-catch and handle them separately.
So basically what I need to do is if an exception is thrown at //3 I should be able to print the stack trace of the exception in `//2
I'm aware of the stack unwinding and how it works, but as far as I understand whenever your code reaches the catch block this means that the exception stack has been unwinded and you can't get it. Please correct me if I'm wrong!
Is there a way at least to add something similar to middleware before unwinding the exception stack? Or do I have to do it manually?
Edit:
Also, what would happen when I can funcE() is a memory access exception but this exception is never caught. Is there a way to catch such kind of exceptions or at least print its stack trace before the crash?
Note:
I'm running my code on Linux and macOS, C++11 with Silicon web framework.
It's a big system so I'm trying to achieve some logging mechanism that can be used across the system.
I'm posting this in case anyone came across the same question and wanted a quick useful answer.
I've ended up overriding the main C++ throw exception behavior using this gist
I've changed a few things in the __cxa_throw function to tackle my own issue and used boost::stacktrace to get a more human-readable stack trace.

exit() method entered without exit command

I have Processing 3 code that is exhibiting some odd behavior. I have a void exit() method defined that is being executed at random times without the user actually telling the code to exit. Here is the method:
void exit()
{
println("clearing buffer and closing file");
if (output != null) {
print("output is not null");
try {
output.close();
}
catch (IOException e) {
println("Error while closing the writer");
}
}
super.exit();
}
As you can see, the only thing that it does is attempt to close a buffered writer called output. Flushing this writer is not critical, so for now I am just removing it from my sketch. But long term, I am curious how this can be happening. Nowhere else in my code is the exit method explicitly called. IE, the code cannot decide to exit. It is only when the user closes the problem using the X.
Note: I cannot upload the entire code this method is attached too because it is too long. I think perhaps a better way to phrase my questions would be something like:
"Hi, I am a noob that doesn't know anything about the exit method. Is there anyway that this method could somehow get called without me explicitly calling it or hitting the exit button?"
Add this at the beginning of your exit() method.
new Exception().printStackTrace();
The resulting stacktrace should allow you to figure out what is calling your exit() method.
Or if you can't tweak the code, you can run the application using a debugger and set a breakpoint at the start of the exit() method.
To answer your question about whether it is possible, the answer depends on what you mean by "without me explicitly calling". There are various ways to call a method, some of which are quite obscure; e.g.
You can use reflection to get the Method object for the exit method from the declaring class, and then call invoke(...) on it.
You can call a Java method from native code via the JNI or JNA apis.
You can generate Java source code that contains an exit() call, compile it, load it, and run it.
You can insert an exit() call into an "innocent" method using BCEL or similar.
And ...
If there is a debug agent attached to the JVM, the debugger can call exit() on some thread in the JVM.
In short, the answer to your question is Yes.
Your method could be found and invoked dynamically using reflection by any class in the same classloader or any other that is below in the hierarchy.
Also, it has a default access. So it could be invoked statically by any class in the same package.
+1 for #Andres, reflection is one possibility.
Have you tried using a breakpoint on the method and looking at the thread's stacktrace?
Personally I don't use breakpoints (just my style) and would try and look at the thread programmatically. Maybe some of the following code can help you look at the thread and get an idea of what's going on:
public class ThreadUtil {
/** Blocked constructor **/
private ThreadUtil() {
}
/**
* Get the stackstrace of the current {#link Thread}.
* The stacktrace will be returned in the form of a string.
*/
public static String getStackTrace() {
return getStackTrace(Thread.currentThread());
}
/**
* Get the stackstrace of a {#link Thread}.
* The stacktrace will be returned in the form of a string.
*/
public static String getStackTrace(Thread thread) {
StringBuilder sb = new StringBuilder();
StackTraceElement[] currThreadStackTraceElementList = thread.getStackTrace();
appendStackTrace(sb, currThreadStackTraceElementList);
return sb.toString();
}
public static String getAllStackTraces() {
StringBuilder sb = new StringBuilder();
Map<Thread, StackTraceElement[]> threadList = Thread.getAllStackTraces();
for (StackTraceElement[] currThreadStackTraceElementList : threadList.values()) {
appendStackTrace(sb, currThreadStackTraceElementList);
}
return sb.toString();
}
private static void appendStackTrace(StringBuilder sb,
StackTraceElement[] currThreadStackTraceElementList) {
sb.append("Thread stack trace: \n");
for (StackTraceElement currThreadStackTraceElement : currThreadStackTraceElementList) {
sb.append("\t" + currThreadStackTraceElement + "\n");
}
sb.append("\n");
}
}
It's a Processing-specific thing.
void exit() is a method already defined by processing in PApplet.java
As explained in the reference:
Rather than terminating immediately, exit() will cause the sketch to
exit after draw() has completed (or after setup() completes if called
during the setup() function).
For Java programmers, this is not the same as System.exit(). Further,
System.exit() should not be used because closing out an application
while draw() is running may cause a crash (particularly with P3D).
exit() it is expected to be used something like this:
void draw() {
line(mouseX, mouseY, 50, 50);
}
void mousePressed() {
exit();
}
It is called within PApplet.java in a few places, notably in handleKeyEvent to close the sketch when ESC is pressed, or when ⌘w is pressed.
Just rename your method to something other than exit()

How does exception dispatching change with an unhandled exception handler?

In short, MSDN describes exception dispatching for user mode application like this:
the debugger gets notified of the first chance exception (if attached)
an exception handler aka. try/catch is invoked (if available)
the debugger gets notified of the second chance exception (if attached)
the system cares about the unhandled exception (typically: terminate the process)
This sequence does not consider the presence of an unhandled exception handler. How does exception dispatching change when an unhandled exception handler is present?
The unhandled exception handlers insert at position 3. The sequence is:
the debugger gets notified of the first chance exception (if attached)
an exception handler aka. try/catch is invoked (if available)
the unhandled exception handlers (note the plural) are called (if available)
the debugger gets notified of the second chance exception (if attached)
the system cares about the unhandled exception (typically: terminate the process)
The following C# program demonstrates it. Depending on the .NET version, you'll a message of another unhandled exception handler, which is the .NET framework printing the exception and the call stack.
using System;
namespace UnhandledException
{
static class Program
{
static void Main()
{
Console.WriteLine("Please attach the debugger now and press Enter.");
Console.ReadLine();
AppDomain.CurrentDomain.UnhandledException += (sender, e) => Unhandled1();
AppDomain.CurrentDomain.UnhandledException += (sender, e) => Unhandled2();
try
{
Console.WriteLine("Throwing now.");
// Will cause a first chance, because in try/catch
throw new Exception("Any exception will do");
}
catch (Exception)
{
// Will cause first chance and second chance, because in NOT try/catch
Console.WriteLine("In catch block.");
throw;
}
}
static void Unhandled1() => Console.WriteLine("In unhandled exception handler 1");
static void Unhandled2() => Console.WriteLine("In unhandled exception handler 2");
}
}
Commands required in the debugger (WinDbg):
.symfix
.reload
sxe clr
g; *** for the breakpoint due to attaching the debugger
g; *** first chance in try/catch
g; *** first chance outside try/catch
g; *** second chance

How to get the benefits of /EHa with /EHsc, on a particular function?

If I know that a particular extern "C" function in my program (say, RaiseException) is the only function that raises SEH exceptions, and I want them converted to C++ exceptions, is there any way for me to "selectively enable" /EHa for that function, so that the exceptions get converted to CStructured_Exception without bloating or slowing down the rest of the program as normally caused by /EHa?
There's obviously no compiler option to do that. Maybe:
void RaiseException() {
__try {
// do something that might throw here...
}
__except(EXCEPTION_EXECUTE_HANDLER) {
throw std::exception("structured exception");
}
}

Getting an Unhandled Exception in VS2010 debugger even though the exception IS handled

I have an issue with VS2010 where the debugger stops with an Unhandled Exception. However, the exception is definitely handled. In fact, if I put code in the catch block, I'll hit it when I press F5. In Debug -> Exceptions, I definitely do not have the "Thrown" checkbox checked, so IMO there is absolutely no reason for the unhandled exception dialog to pop up...
I can't post the exact code, but will work on a sample soon. The basic idea behind the offending code section is that I have a thread that talks to hardware, and if I have an error talking to it, then I throw a HardwareException. The thread is launched with BeginInvoke, and the exception is caught in the callback handler when I call EndInvoke.
When the exception is thrown in the debugger, I get a messagebox that says 'HardwareException not handled by user code". But it is!!!
EDIT -- Well, this is driving me crazy. I've got sample code that is representative of the code I have in my application, and it looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;
using System.Threading;
namespace ConsoleApplication1
{
public class HardwareException : ApplicationException
{
public HardwareException( string message) : base(message) {}
}
class Program
{
delegate void HardwareTestDelegate();
static void Main(string[] args)
{
HardwareTestDelegate d = new HardwareTestDelegate( HardwareTestThread);
d.BeginInvoke( HardwareTestComplete, null);
while( true);
}
static void HardwareTestThread()
{
throw new HardwareException( "this is a test");
}
static void HardwareTestComplete( IAsyncResult iar)
{
try {
AsyncResult ar = (AsyncResult)iar;
HardwareTestDelegate caller = (HardwareTestDelegate)ar.AsyncDelegate;
caller.EndInvoke( iar);
} catch( Exception ex) {
Console.WriteLine( "Should see this line without getting an unhandled exception message in the IDE");
}
}
}
}
I throw my HardwareException from the thread, and then handle the exception when EndInvoke is called. I guess Murphy was right, because when I run this sample code, it does what I expect -- i.e. no unhandled exception error message pops up in the IDE!
Here is the response from Microsoft, case 111053102422121. Allen Weng writes the following:
Analysis:
For your information, CLR will re-throw the exception inside the callback when you call EndInvoke(). Below is a simplified version of EndInvoke():
public object EndInvoke(IAsyncResult asyncResult)
{
using (new MultithreadSafeCallScope())
{
ThreadMethodEntry entry = asyncResult as ThreadMethodEntry;
............
if (entry.exception != null)
{
throw entry.exception;
}
}
}
The exception will be handled in the call back function or in the asynchronous method if an exception handler is provided. This is how it works without a debugger attached.
When you run it in VS.NET, the debugger seems checking only the presence of the exception handler in the asynchronous method. If there is no such handler, the debugger would think the exception is not handled and pop up an error message notifying you of this.
Suggestion:
The application should work as expected when you run it stand alone. If the error message is annoying in debugging for you, you can disable it by unchecking “User unhandled” for “Common Language Runtime Exceptions”in the Exception dialog box (Debug|Exceptions or press CTRL+ATL+E). Or you can add try/catch in the asynchronous method. In the latter case, the exception is set to null and won’t be re-thrown in EndInvoke().
I'm having this same problem, so I'll post this possible workaround for posterity's sake:
In your code that throws an exception into the .NET code (HardwareTestThread() in the example above,) catch the exception that's being thrown and wrap it in some esoteric .NET exception type for which you can disable the "user-unhandled" option in the Debug>Exceptions dialog. For my case, I needed to allow an IOException to propagate through some .NET code back to my code, so I just caught the IOException and wrapped in an AppDomainUnloadedException before letting it propagate through the .NET code back to my catch block. I chose AppDomainUnloadedException because user-unhandled is unchecked for it by default and it's in the System.dll assembly, so it was already being imported in my project, though any exception should work, so long as you disable the "user-unhandled" option for it and you don't care that the debugger won't break on that type of exception in the future.
Here's my code that wraps the IOException I was needing to propagate:
public override int Read(byte[] buffer, int offset, int count)
{
try { return innerStream.Read(buffer, offset, count); }
catch (IOException ex) { throw new AppDomainUnloadedException("Exception from innerStream: " + ex.Message, ex); }
}
And here's my code where I'm catching it on the other side of the .NET code it needed to propagate through:
try { bytesRead = sslStream.Read(buffer, offset, count); }
catch (Exception ex) { /* ex handled here. */ }

Resources