Open Groostav opened 4 years ago
I'm sorry I talked to my native-code friend and of course the problem is C. C does not support exceptions! On Windows (and in C) Structured Exception Handling will let JNA capture CPP style exceptions, but isn't going to let you into a cpp v-table to call exception::what
without serious hacks.
But I suspect that error message "Invalid Memory access" comes from the fact that SEH-handler code is hitting the same JNA code path as s SIG_SEGV. This would seem to be an error. If JNA catches a SIG_SEGV, it should report "Invalid Memory access", but if it encounters an SEH exception, could it report "user thrown exception" or something like that?
ahh, but with SEH the std::exception instance does appear recoverable in
(_EXCEPTION_POINTERS *ep)->ExceptionRecord->ExceptionInformation[1]
:
#include <chrono>
#include <stdio.h>
#include <windows.h>
#include <excpt.h>
// this was done at gtests own suggestion.
#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING
namespace EMPOWER_LGO
{
std::exception exception_reserve;
int filter(struct _EXCEPTION_POINTERS *ep)
{
//I dont know what kind of memory we're in.
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r0.pdf
// But you cant access GetExceptionInformation from the __except block, only from the filter, so we'll have ot move it ourselves.
exception_reserve = *(std::exception*)(ep->ExceptionRecord->ExceptionInformation[1]);
return EXCEPTION_EXECUTE_HANDLER;
}
void trapException()
{
__try
{
throw std::exception("kablamo!");
}
__except (filter(GetExceptionInformation()))
{
// i cant make a local var nor can I do anything with ASSERT_STREQ here
// because of C2712:
// https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-2/compiler-error-c2712?view=vs-2019
//anyways, under the debugger the values do appear correct.
auto y = 4;
}
}
TEST(SEHFixture, WhenCallingSehThingsShouldThings)
{
//act
trapException();
//assert
ASSERT_STREQ(exception_reserve.what(), "kablamo!");
}
}
Please keep in mind, that JNA is platform independend and SEH is windows only (to my knowledge). So any solution should keep that in mind. It would also be helpful to get this more structured, this is not QnA or discussion forum, but the issue tracker.
For discussions please come to the mailinglist. As a general rule: feature requests that are not take care by their authors have the tendency to not be worked on, so you should be prepared to get your hands dirty :-)
Please keep in mind, that JNA is platform independend and SEH is windows only (to my knowledge). So any solution should keep that in mind. It would also be helpful to get this more structured, this is not QnA or discussion forum, but the issue tracker.
You are of course correct; SEH is a (not particularly good) exception-handling implementation used by both msvc and msvc++ compilers. It also exposes macros for C callers. As such I would of course have to wrap it in the appropriate IFDEF WIN32.
I'll create a topic on the mailing list.
created a google groups discussion here: https://groups.google.com/forum/#!topic/jna-users/moTydETIf-A
I have some cpp code that I've updated to throw std::exception's that contain valuable data in their
what()
clause. What I was hoping JNA would do is this:expected: java.lang.Error: In native code: message from native code: kablamo! actual: java.lang.Error: Invalid memory access
... on: Windows 10 1903, JNA 4.2.2
My work around: Wrap my code in a
try { } catch { }
, save it to a global variable, and expose a functionGetLastError()
that I then call from the handler. If you combine this with StackWalker you can even get a java--ish native code stack trace in your preconditions/postconditions. From the java side, I add my own InvocationMapper to catch JNA thrownjava.lang.Error
s, callGetLastError()
then throw a new exception with the results.