*** empty log message ***
[mono.git] / mono / jit / exception.c
index 73aa049705349cc6eb3c69754ea4194a7462335b..d23a4cfce5213796eb24674ea7899493057aa63f 100644 (file)
@@ -237,7 +237,7 @@ x86_unwind_native_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, struct sig
 
        frame = MONO_CONTEXT_GET_BP (ctx);
 
-       max_stack = lmf ? lmf : jit_tls->end_of_stack;
+       max_stack = lmf && lmf->method ? lmf : jit_tls->end_of_stack;
 
        *new_ctx = *ctx;
 
@@ -293,9 +293,9 @@ x86_unwind_native_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, struct sig
                        MONO_CONTEXT_SET_IP (new_ctx, frame->return_address);
                        frame = frame->next;
                        MONO_CONTEXT_SET_BP (new_ctx, frame);
-
-                       /* stop if we detect an unexpected managed frame */
-                       if (mono_jit_info_table_find (domain, frame->return_address)) {
+                       
+                       /* stop if !frame or when we detect an unexpected managed frame */
+                       if (!frame || mono_jit_info_table_find (domain, frame->return_address)) {
                                if (trace) {
                                        g_free (*trace);
                                        *trace = NULL;
@@ -305,9 +305,9 @@ x86_unwind_native_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, struct sig
                }
        }
 
-       if (!lmf)
-               g_assert_not_reached ();
-
+       //if (!lmf)
+       //g_assert_not_reached ();
+               
        if (trace) {
                g_free (*trace);
                *trace = NULL;
@@ -562,7 +562,8 @@ glist_to_array (GList *list)
  */
 static MonoJitInfo *
 mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoContext *ctx, 
-                        MonoContext *new_ctx, char **trace, MonoLMF **lmf, int *native_offset)
+                        MonoContext *new_ctx, char **trace, MonoLMF **lmf, int *native_offset,
+                        gboolean *managed)
 {
        MonoJitInfo *ji;
        gpointer ip = MONO_CONTEXT_GET_IP (ctx);
@@ -575,6 +576,9 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoContex
        if (native_offset)
                *native_offset = -1;
 
+       if (managed)
+               *managed = FALSE;
+
        if (ji != NULL) {
                char *source_location, *tmpaddr, *fname;
                gint32 address, iloffset;
@@ -592,6 +596,10 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoContex
                if (native_offset)
                        *native_offset = address;
 
+               if (managed)
+                       if (!ji->method->wrapper_type)
+                               *managed = TRUE;
+
                if (trace) {
                        if (mono_debug_format != MONO_DEBUG_FORMAT_NONE)
                                mono_debug_make_symbols ();
@@ -644,6 +652,9 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoContex
                
                *new_ctx = *ctx;
 
+               if (!(*lmf)->method)
+                       return (gpointer)-1;
+
                if (trace)
                        *trace = g_strdup_printf ("in (unmanaged) %s", mono_method_full_name ((*lmf)->method, TRUE));
                
@@ -675,6 +686,11 @@ ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info
        MonoArray *res;
        MonoArray *ta = exc->trace_ips;
        int i, len;
+
+       if (ta == NULL) {
+               /* Exception is not thrown yet */
+               return mono_array_new (domain, mono_defaults.stack_frame_class, 0);
+       }
        
        len = mono_array_length (ta);
 
@@ -686,6 +702,12 @@ ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info
                gpointer ip = mono_array_get (ta, gpointer, i);
 
                ji = mono_jit_info_table_find (domain, ip);
+               if (ji == NULL) {
+                       /* Unmanaged frame */
+                       mono_array_set (res, gpointer, i, sf);
+                       continue;
+               }
+
                g_assert (ji != NULL);
 
                sf->method = mono_method_get_object (domain, ji->method, NULL);
@@ -716,6 +738,7 @@ mono_jit_walk_stack (MonoStackWalk func, gpointer user_data) {
        MonoLMF *lmf = jit_tls->lmf;
        MonoJitInfo *ji;
        gint native_offset, il_offset;
+       gboolean managed;
 
        MonoContext ctx, new_ctx;
 
@@ -724,12 +747,15 @@ mono_jit_walk_stack (MonoStackWalk func, gpointer user_data) {
 
        while (MONO_CONTEXT_GET_BP (&ctx) < jit_tls->end_of_stack) {
                
-               ji = mono_arch_find_jit_info (domain, jit_tls, &ctx, &new_ctx, NULL, &lmf, &native_offset);
+               ji = mono_arch_find_jit_info (domain, jit_tls, &ctx, &new_ctx, NULL, &lmf, &native_offset, &managed);
                g_assert (ji);
-               
+
+               if (ji == (gpointer)-1)
+                       return;
+
                il_offset = mono_debug_il_offset_from_address (ji->method, native_offset);
 
-               if (func (ji->method, native_offset, il_offset, user_data))
+               if (func (ji->method, native_offset, il_offset, managed, user_data))
                        return;
                
                ctx = new_ctx;
@@ -751,16 +777,21 @@ ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
        MONO_CONTEXT_SET_IP (&ctx, ves_icall_get_frame_info);
        MONO_CONTEXT_SET_BP (&ctx, __builtin_frame_address (0));
 
-       do {
-               ji = mono_arch_find_jit_info (domain, jit_tls, &ctx, &new_ctx, NULL, &lmf, native_offset);
-               g_assert (ji);
+       skip++;
 
+       do {
+               ji = mono_arch_find_jit_info (domain, jit_tls, &ctx, &new_ctx, NULL, &lmf, native_offset, NULL);
                ctx = new_ctx;
                
-               if (MONO_CONTEXT_GET_BP (&ctx) >= jit_tls->end_of_stack)
+               if (!ji || ji == (gpointer)-1 || MONO_CONTEXT_GET_BP (&ctx) >= jit_tls->end_of_stack)
                        return FALSE;
 
-       } while (skip-- > 0);
+               if (ji->method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE)
+                       continue;
+               
+               skip--;
+
+       } while (skip >= 0);
 
        *method = mono_method_get_object (domain, ji->method, NULL);
        *iloffset = mono_debug_il_offset_from_address (ji->method, *native_offset);
@@ -830,15 +861,15 @@ arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
                char *trace = NULL;
                
                ji = mono_arch_find_jit_info (domain, jit_tls, ctx, &new_ctx, 
-                                             test_only ? &trace : NULL, &lmf, NULL);
+                                             test_only ? &trace : NULL, &lmf, NULL, NULL);
+
                if (!ji) {
-                       g_warning ("Exception insinde function without unwind info");
+                       g_warning ("Exception inside function without unwind info");
                        g_assert_not_reached ();
                }
 
-               if (ji->method != mono_start_method) {
-                       
-                       if (test_only) {
+               if (ji != (gpointer)-1) {
+                       if (test_only && ji->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE) {
                                char *tmp, *strace;
 
                                trace_ips = g_list_append (trace_ips, MONO_CONTEXT_GET_IP (ctx));
@@ -847,7 +878,7 @@ arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
                                        strace = g_strdup ("");
                                else
                                        strace = mono_string_to_utf8 (((MonoException*)obj)->stack_trace);
-
+                       
                                tmp = g_strdup_printf ("%s%s\n", strace, trace);
                                g_free (strace);
 
@@ -903,7 +934,7 @@ arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
                        
                *ctx = new_ctx;
 
-               if (ji->method == mono_start_method || MONO_CONTEXT_GET_BP (ctx) >= jit_tls->end_of_stack) {
+               if ((ji == (gpointer)-1) || MONO_CONTEXT_GET_BP (ctx) >= jit_tls->end_of_stack) {
                        if (!test_only) {
                                jit_tls->lmf = lmf;
                                jit_tls->abort_func (obj);
@@ -919,3 +950,4 @@ arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
        g_assert_not_reached ();
 }
 
+