How to properly call rtlunwind from within an x86_64 windows exception handler - c

I'm trying to implement a win64 exception personality and can't find much documentation on the subject.
I've already got a working win32 version but the win64 one crashes on rtlunwind (access violation) in the "catch" part of a win64 exception handler, to unwind to the catch handler frame and continuation:
int ExceptionHandler(EXCEPTION_RECORD arec, uint64_t EstablisherFrame, PCONTEXT context, PDISPATCHER_CONTEXT dispatcher)
{
if (0 == (arec->ExceptionFlags & ( rtl.EXCEPTION_UNWINDING | rtl.EXCEPTION_EXIT_UNWIND)))
{
// check if this is a catch supported
rtl.RtlUnwindEx(EstablisherFrame, NULL, arec, NULL, context, dispatcher->HistoryTable);
// call catch & jump to continuation
}
}
Basically, I'm trying to find the parameters to RtlUnwind/RtlUnwindEx for a given catch.
Can anyone point me to information on what I can try or a sample implementation of seh for win64?

turns out this can be done by passing a new exception object to rtlUnwind with a CallCatch method as first info parameter, with STATUS_UNWIND_CONSOLIDATE as code. This will unwind the whole thing (retriggering the personality for any cleanup/finally)
EXCEPTION_RECORD EH;
EH.ExceptionCode = STATUS_UNWIND_CONSOLIDATE;
EH.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
EH.NumberParameters = 4;
EH.ExceptionInformation[0] = (ULONG)CallCatch;
EH.ExceptionInformation[1] = EstFrame;
EH.ExceptionInformation[2] = dispatcher->ImageBase + aHandler->Handler;
EH.ExceptionInformation[3] = aCatch->TryLow;
rtl.RtlUnwindEx(estFrame, dispatcher->ControlPc, #EH, NULL, Context, dispatcher->HistoryTable);
Call catch should take a function with EXCEPTION_RECORD* as parameter, call the actual catch and returning the continuation address for this catch.

Related

How to interrupt JoinPoint execution in AOP

Is it possible to interrupt invoking the actual method from within the aspect execution?
For example:
public class CheckPermissionAspect {
#Around("#annotation(CheckPermission)")
public Object methodLogging( ProceedingJoinPoint joinPoint) throws Throwable {
// before method execution
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
log.info("Enter ==> " + signature.getMethod().getName());
if ( getPermission( principal.getName()) == false ) {
// break the execution of actual method
Object result = null; // ???
log.info("Break ==> " + signature.getMethod().getName());
} else {
// invoke the actual method
Object result = joinPoint.proceed();
// after method execution
log.debug("Result: " + result);
log.info("Leave ==> " + signature.getMethod().getName());
}
return result;
}
}
To set Object result = null; does not work.
Thank you for any help.
From Spring Reference documentation : Around Advice
Within the body of the advice method, you must invoke proceed() on the
ProceedingJoinPoint in order for the underlying method to run
If joinPoint.proceed() is removed from the code or an exception is thrown before joinPoint.proceed() statement or a return is issued before joinPoint.proceed() statement , the execution of the underlying method would get interrupted.
Update : to answer the comment
Spring AOP is proxy based. To understand this concept better , do read through : Understanding AOP proxies
An advice is placed between the calling method and the target. All calls to the target method gets intercepted and advised.
You could throw an exception upon validation ( Do note that the exception type thrown should match the exception type of the target method . Go through this Q&A).
The exception/return value from the advise would reach back the calling method .

Is it possible to selectively ignore service exception in Hystrix?

I have client API jar which internally makes external calls and throws single generic Service exception in case of issues. I have written hystrix wrapper over the API calls. There are cases like "user not found" returning exception. Though the call was successful and service responded with valid response, the hystrix is treating it as a failure. I know that we can ignore the exception in Hystrix; but it will whitelist the only exception thrown by service calls. Is there a way to selectively ignore exception thrown by the service calls based on message in exception or http status code or something?
If the external service throw different exceptions in different cases, then you can probably ignore those exceptions like this
#HystrixCommand(ignoreExceptions = {SomeException.class})
But if you have to ignore exceptions bases on error message then the best way to tackle this is put a try catch around your external call. And in the catch block check if it is one of those exceptions which needs to be ignored. If so don't do anything. If not rethrow this exception. Something like this will do. More info about HystrixBadRequestException
#HystrixCommand(fallbackMethod = "fallBackMethod", groupKey = "CircuitBreaker", commandKey = "somekey", threadPoolKey = "somekey",
commandProperties = {
#HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "10000"),
#HystrixProperty(name = "execution.timeout.enabled", value = "false"),
#HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),
#HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "1200000"),
},
threadPoolProperties = {
#HystrixProperty(name = "coreSize", value = "30"),
#HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "180000")
})
public void someMethod(....){
try {
// Call external service
} catch(Exception e) {
if(exception to be ignored)
throw new HystrixBadRequestException("Some message", e);
else
throw e
}
}

Golang flock filelocking throwing panic: runtime error: invalid memory address or nil pointer dereference

I have a go program that modifies my configuration file. I am trying to create a filelock from within the main() function, but it is throwing a panic: runtime error: invalid memory address or nil pointer dereference error. Without the lock, the program is working fine as expected. The piece of code that throws exception is
lockProgram, err := os.Create("/var/.daemon.lock")
defer lockProgram.Close()
CheckForError(err)
GetLock(lockProgram, syscall.LOCK_EX)
defer UngetLock(lockProgram)
//This is in a separate package
func CheckForError(e error) {
if e != nil {
Error.Println(e)
panic(e)
}
}
func GetLock(file *os.File, locktype int ) {
fmt.Println("Acquiring lock on ", file.Name())
syscall.Flock(int(file.Fd()), locktype)
fmt.Println("Acquired filelock on ", file.Name())
}
func UngetLock(file *os.File) {
syscall.Flock(int(file.Fd()), syscall.LOCK_UN);
}
This same flock is working when I call it on my configuration file, but from a different package, not main package, but throws the same error when I try to put lock from within the main package. Please help me in finding out what am I doing wrong here.
When an error occurs while creating the lock, lockProgram will be nil. This will cause the subsequent (deferred) call to lockProgram.Close() to fail.
Note that when you're panicking (like in your CheckForError function), deferred method calls will still be executed. This is explained in detail in this blog article (emphasis mine):
Panic is a built-in function that stops the ordinary flow of control and begins panicking. When the function F calls panic, execution of F stops, any deferred functions in F are executed normally, and then F returns to its caller. To the caller, F then behaves like a call to panic. The process continues up the stack until all functions in the current goroutine have returned, at which point the program crashes.
Solution: Check for errors first, and then defer the Close() call:
lockProgram, err := os.Create("/var/.daemon.lock")
CheckForError(err)
defer lockProgram.Close()

Is it safe to abort this file-searching thread?

First, the code:
lblFileNbr.Text = "?/?";
lblFileNbr.ToolTipText = "Searching for files...";
lock(_fileLock)
{
_dirFiles = new string[0];
_fileIndex = 0;
}
if(_fileThread != null && _fileThread.IsAlive)
{
_fileThread.Abort();
}
_fileThread = new Thread(() =>
{
string dir = Path.GetDirectoryName(fileName) ?? ".";
lock (_fileLock)
{
_dirFiles = GetImageFileExtensions().SelectMany(f => Directory.GetFiles(dir, f, _searchOption)).OrderBy(f => f).ToArray();
_fileIndex = Array.IndexOf(_dirFiles, fileName);
}
int totalFileCount = Directory.GetFiles(dir, "*.*", _searchOption).Length;
Invoke((MethodInvoker)delegate
{
lblFileNbr.Text = string.Format("{0}/{1}", NumberFormat(_fileIndex + 1), NumberFormat(_dirFiles.Length));
lblFileNbr.ToolTipText = string.Format("{0} ({1} files ignored)", dir, NumberFormat(totalFileCount - _dirFiles.Length));
});
});
_fileThread.Start();
I'm building a little image-viewing program. When you open an image, it lists the number of files in the same directory. I noticed when I open an image in a directory with a lot of other files (say 150K), it takes several seconds to build the file list. Thus, I'm delegating this task to another thread.
If, however, you open another image before it finishes searching for the files, that old count is no longer relevant, so I'm aborting the thread.
I'm locking _dirFiles and _fileIndex because I want to add some Left and Right key functionality to switch between photos, so I'll have to access those somewhere else (but in the UI thread).
Is this safe? There seems to be dozens of methods of dealing with threads in C# now, I just wanted something simple.
fileName is a local variable (which means it will be "copied" into the anonymous function, right?), and _searchOption is readonly, so I imagine those 2 are safe to access.
> Is it safe to abort this file-searching thread?
The short answer is NO!
It is almost never safe to abort a thread, and this advice applies even more when you might be executing native code.
If you can't cooperatively exit fast enough ( because it is your call to Directory.GetFiles that takes time ), your best bet is to abandon the thread: let it finish cleanly but ignore its results.
As always, I recommend reading Joe Albahari's free ebook
It isn't safe to abort the thread using Thread.Abort(). But you could instead implement your own abort which could allow you to safely bring the thread to a close in a controlled fashion.
If you use EnumerateFiles instead of GetFiles, you can loop through each file as you increment a counter to get the total number of files while checking a flag to see if the thread needs to abort.
Calling something such as this in place of your current GetFiles().Length:
private bool AbortSearch = false;
private int NumberOfFiles(string dir, string searchPattern, SearchOption searchOption)
{
var files = Directory.EnumerateFiles(dir, searchPattern, searchOption);
int numberOfFiles = 0;
foreach (var file in files)
{
numberOfFiles++;
if (AbortSearch)
{
break;
}
}
return numberOfFiles;
}
You could then replace
_fileThread.Abort();
with
AbortSearch=true;
_fileThread.Join();
You'll achieve what you are with the current Thread.Abort(), but you will allow all threads to end cleanly when you want them to.

System.ArgumentException when calling MediaLibrary.SavePicture()

My code looks like this:
String filename = Utils.GetNextFilename();
MediaLibrary library = new MediaLibrary();
library.SavePicture(filename, corrected_image);
And in the SavePicture() call, I get the following:
An unhandled exception of type
'System.ArgumentException' occurred in
Microsoft.Xna.Framework.dll
Additional information: Value does not
fall within the expected range.
But I'm not sure why.
Okay, I figured it out. I must reset the stream:
String filename = Utils.GetNextFilename();
MediaLibrary library = new MediaLibrary();
corrected_image.Seek(0, 0); // <-- The fix.
library.SavePicture(filename, corrected_image);

Resources