

![]() | Start a set with this search |
![]() | Include this search in one of my sets |
![]() | Exclude this search from one of my sets |
![]() | Permalink to these results Paste this link in email or IM: |
| Atom feed for tracking future search results Paste this URL into your reader: |
4 messages in net.java.dev.jna.usersUsing setProtected under win32| From | Sent On | Attachments |
|---|---|---|
| Jonathan Newell | Jan 8, 2008 6:50 pm | |
| Jonathan Newell | Jan 9, 2008 5:50 am | |
| Timothy Wall | Jan 12, 2008 11:29 am | |
| Timothy Wall | Jan 21, 2008 1:45 am |

![]() | Permalink for this message Paste this link in email or IM: |
![]() | Permalink for this thread Paste this link in email or IM: |
| Atom feed for this thread Paste this URL into your reader: |
| Subject: | Using setProtected under win32 | Actions... |
|---|---|---|
| From: | Jonathan Newell (jona...@markit.com) | |
| Date: | Jan 8, 2008 6:50:01 pm | |
| List: | net.java.dev.jna.users | |
I'm using JNA to talk to a legacy windows dll that I have to use, but that I don't really trust. Another developer spent a couple of months putting together a JNI wrapper to the dll, but this is clunky and a bit flakey, so I was delighted when I was able replicate the whole thing in JNA inside a day. Unfortunately the external dll seems to have several bugs which can cause it to throw Exception Access Violations under various repeatable but unavoidable situations, and I don't have any way to fix the underlying code. Seeing my java program disappear in a heap of dust because the external dll has a bug is quite upsetting, so I was keen to use the protected mode (it is an analytics package that I am using where each call through JNA may result in a second or more of computation time so the protection overhead is more than acceptable).
The basic scenario I'm running is that the dll has various (1000s) plugins, some of which work and some of which don't - I want to be able to detect those that don't via an exception in java and drive on (logging the fact that a specific plugin was bad).
I've checked out and built trunk (revision 439), but after calling Native.setProtected(true) the vm still crashes when making the call through to the external dll. Looking at the code, this seems to be in the dispatch method:
(in dispatch.c) PSTART(); ffi_call(&cif, FFI_FN(func), resP, ffi_values); PEND(); if (preserve_last_error) { update_last_error(env, GET_LAST_ERROR()); }
The win32 specific protection code is very different to the other protection code, and I wonder why this is the case. In particular I'm not convinced that the atempt to unwind the stack is very useful, if I'm reading it right it will only go back one frame which means that if the exception occurs more than one frame down from where the exception handler is installed then it will restart too deep in the stack. I've reworked the code to use setjmp/longjmp (as with the other exception handling) and it seems to work better:
(in protect.h) #ifdef _WIN32 #include <excpt.h> #include <setjmp.h>
static jmp_buf context;
static EXCEPTION_DISPOSITION __cdecl exc_handler(struct _EXCEPTION_RECORD* exception_record, void *establisher_frame, struct _CONTEXT *context_record, void* dispatcher_context) { longjmp(context, exception_record->ExceptionCode); }
#define PROTECTED_START() \ EXCEPTION_REGISTRATION ex_reg; \ int _error = 0; \ if (PROTECT) { \ ex_reg.handler = exc_handler; \ asm volatile ("movl %%fs:0, %0" : "=r" (ex_reg.prev)); \ asm volatile ("movl %0, %%fs:0" : : "r" (&ex_reg)); \ if ((_error = setjmp(context) != 0)) { \ goto _exc_caught; \ } \ }
#define PROTECTED_END(ONERR) do { \ if (!_error) \ goto _remove_handler; \ _exc_caught: \ ONERR; \ _remove_handler: \ if (PROTECT) { asm volatile ("movl %0, %%fs:0" : : "r" (ex_reg.prev)); } \ } while(0)
#else...
This still uses the windows structured exception handling. The only issue I find is that I have to call Native.setPreserveLastError(false) if I want to actually receive the error raised in ONERR, otherwise the error preserving after the ffi_call actually wipes out the error (it is not a safe post-exception JNI operation).
I'd love some comments on the above, specifically whether people think it is a safe approach. I'm not a C programmer (in fact I've basically had to learn C from scratch over the past 24 hours to do this), so I might be missing something obvious or doing something really stupid, apologies in advance if this is the case (I specifically apologize if I've misunderstood the existing stack unwinding code, it was well beyond me and I may be doing it a disservice!).
Thanks,
Jonathan
The content of this e-mail is confidential and may be privileged. It may be
read, copied and used only by the intended recipient and may not be disclosed,
copied or distributed. If you received this email in error, please contact the
sender immediately by return e-mail or by telephoning +44 20 7260 2000, delete
it and do not disclose its contents to any person. You should take full
responsibility for checking this email for viruses. Markit reserves the right to
monitor all e-mail communications through its network.
Markit and its affiliated companies make no warranty as to the accuracy or
completeness of any information contained in this message and hereby exclude any
liability of any kind for the information contained herein. Any opinions
expressed in this message are those of the author and do not necessarily reflect
the opinions of Markit.
For full details about Markit, its offerings and legal terms and conditions,
please see Markit's website at http://www.markit.com <http://www.markit.com/> .







