When JNI method linking fails an instance of
java.lang.UnsatisfiedLinkError is thrown from JNI trampoline
(jit_native_trampoline()). When stack trace is created for this
exception, stack walker is trying to use the
method->compilation_unit->native_ptr to get the JNI method's address,
but this pointer is not valid because linking failed. To solve this
problem we add a new field to struct stack_trace_elem to hold a
pointer to compilation unit. For JNI stack trace elements this field
is used and no jit_lookup_cu() is performed on ->addr. This also makes
stack traversal faster.

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 include/vm/stack-trace.h |    3 +++
 jit/trampoline.c         |    6 ++++++
 vm/stack-trace.c         |   21 +++++++++++----------
 3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/include/vm/stack-trace.h b/include/vm/stack-trace.h
index 4bde292..f6db886 100644
--- a/include/vm/stack-trace.h
+++ b/include/vm/stack-trace.h
@@ -124,6 +124,8 @@ struct stack_trace_elem {
         * is undefined.
         */
        void *frame;
+
+       struct compilation_unit *cu;
 };
 
 void init_stack_trace_printing(void);
@@ -131,6 +133,7 @@ int init_stack_trace_elem(struct stack_trace_elem *elem);
 int get_prev_stack_trace_elem(struct stack_trace_elem *elem);
 int skip_frames_from_class(struct stack_trace_elem *elem, struct vm_class 
*class);
 int get_stack_trace_depth(struct stack_trace_elem *elem);
+struct compilation_unit *stack_trace_elem_get_cu(struct stack_trace_elem 
*elem);
 struct vm_object *get_stack_trace(void);
 struct vm_object *get_stack_trace_from_ctx(void *ctx);
 struct vm_object *native_vmthrowable_fill_in_stack_trace(struct vm_object *);
diff --git a/jit/trampoline.c b/jit/trampoline.c
index 415d4d5..369da6d 100644
--- a/jit/trampoline.c
+++ b/jit/trampoline.c
@@ -81,6 +81,12 @@ static void *jit_native_trampoline(struct compilation_unit 
*cu)
        signal_new_exception(vm_java_lang_UnsatisfiedLinkError, msg->value);
        free_str(msg);
 
+       /* We must remove the jni_stack_entry from call stack here
+        * because we're not returning after call site - exception
+        * will be caught by trampoline code.
+        */
+       vm_leave_jni();
+
        return NULL;
 }
 
diff --git a/vm/stack-trace.c b/vm/stack-trace.c
index 45ad794..76f4a50 100644
--- a/vm/stack-trace.c
+++ b/vm/stack-trace.c
@@ -221,14 +221,7 @@ static int get_caller_stack_trace_elem(struct 
stack_trace_elem *elem)
                        elem->type = STACK_TRACE_ELEM_TYPE_JNI;
                        elem->is_native = false;
 
-                       /*
-                        * We don't need to lock the compilation_unit
-                        * because when JNI method is present in stack
-                        * trace it means that it has been resolved
-                        * and ->native_ptr can not change after that.
-                        */
-                       elem->addr = (unsigned long)
-                               tr->method->compilation_unit->native_ptr;
+                       elem->cu = tr->method->compilation_unit;
                        elem->frame = NULL;
                        return 0;
                }
@@ -335,6 +328,14 @@ int init_stack_trace_elem(struct stack_trace_elem *elem)
        return get_prev_stack_trace_elem(elem);
 }
 
+struct compilation_unit *stack_trace_elem_get_cu(struct stack_trace_elem *elem)
+{
+       if (elem->type == STACK_TRACE_ELEM_TYPE_JNI)
+               return elem->cu;
+
+       return jit_lookup_cu(elem->addr);
+}
+
 /**
  * skip_frames_from_class - makes @elem to point to the nearest stack
  *     trace element which does not belong to any method of class
@@ -349,7 +350,7 @@ int skip_frames_from_class(struct stack_trace_elem *elem,
        struct compilation_unit *cu;
 
        do {
-               cu = jit_lookup_cu(elem->addr);
+               cu = stack_trace_elem_get_cu(elem);
                if (cu == NULL) {
                        fprintf(stderr,
                                "%s: no compilation unit mapping for %p\n",
@@ -420,7 +421,7 @@ static struct vm_object *get_intermediate_stack_trace(void)
        do {
                unsigned long bc_offset;
 
-               cu = jit_lookup_cu(st_elem.addr);
+               cu = stack_trace_elem_get_cu(&st_elem);
                if (!cu) {
                        fprintf(stderr,
                                "%s: no compilation unit mapping for %p\n",
-- 
1.6.0.6


------------------------------------------------------------------------------
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to