[aot] Better report errors when loading methods.
authorRodrigo Kumpera <kumpera@gmail.com>
Mon, 2 Feb 2015 16:04:37 +0000 (11:04 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Thu, 12 Mar 2015 18:09:48 +0000 (14:09 -0400)
mono/mini/aot-compiler.c

index 514c756e9d2dd602c7de0a5352013e40676dc0b6..a182ca5a39e31bc5fff851f84d9f8126d73e776a 100644 (file)
@@ -335,6 +335,28 @@ aot_printerrf (MonoAotCompile *acfg, const gchar *format, ...)
        va_end (args);
 }
 
+static void
+report_loader_error (MonoAotCompile *acfg, MonoError *error, const char *format, ...)
+{
+       FILE *output;
+       va_list args;
+
+       if (mono_error_ok (error))
+               return;
+
+       if (acfg->logfile)
+               output = acfg->logfile;
+       else
+               output = stderr;
+
+       va_start (args, format);
+       vfprintf (output, format, args);
+       va_end (args);
+       mono_error_cleanup (error);
+
+       g_error ("FullAOT cannot continue if there are loader errors");
+}
+
 /* Wrappers around the image writer functions */
 
 static inline void
@@ -3389,11 +3411,13 @@ add_wrappers (MonoAotCompile *acfg)
         * callers.
         */
        for (i = 0; i < acfg->image->tables [MONO_TABLE_METHOD].rows; ++i) {
+               MonoError error;
                MonoMethod *method;
                guint32 token = MONO_TOKEN_METHOD_DEF | (i + 1);
                gboolean skip = FALSE;
 
-               method = mono_get_method (acfg->image, token, NULL);
+               method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error);
+               report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error));
 
                if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
                        (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
@@ -3692,8 +3716,10 @@ add_wrappers (MonoAotCompile *acfg)
 
        /* Synchronized wrappers */
        for (i = 0; i < acfg->image->tables [MONO_TABLE_METHOD].rows; ++i) {
+               MonoError error;
                token = MONO_TOKEN_METHOD_DEF | (i + 1);
-               method = mono_get_method (acfg->image, token, NULL);
+               method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error);
+               report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error));
 
                if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) {
                        if (method->is_generic) {
@@ -3721,10 +3747,12 @@ add_wrappers (MonoAotCompile *acfg)
 
        /* pinvoke wrappers */
        for (i = 0; i < acfg->image->tables [MONO_TABLE_METHOD].rows; ++i) {
+               MonoError error;
                MonoMethod *method;
                guint32 token = MONO_TOKEN_METHOD_DEF | (i + 1);
 
-               method = mono_get_method (acfg->image, token, NULL);
+               method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error);
+               report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error));
 
                if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
                        (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) {
@@ -3734,12 +3762,14 @@ add_wrappers (MonoAotCompile *acfg)
  
        /* native-to-managed wrappers */
        for (i = 0; i < acfg->image->tables [MONO_TABLE_METHOD].rows; ++i) {
+               MonoError error;
                MonoMethod *method;
                guint32 token = MONO_TOKEN_METHOD_DEF | (i + 1);
                MonoCustomAttrInfo *cattr;
                int j;
 
-               method = mono_get_method (acfg->image, token, NULL);
+               method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error);
+               report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error));
 
                /* 
                 * Only generate native-to-managed wrappers for methods which have an
@@ -4207,11 +4237,16 @@ add_generic_instances (MonoAotCompile *acfg)
                return;
 
        for (i = 0; i < acfg->image->tables [MONO_TABLE_METHODSPEC].rows; ++i) {
+               MonoError error;
                token = MONO_TOKEN_METHOD_SPEC | (i + 1);
-               method = mono_get_method (acfg->image, token, NULL);
+               method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error);
 
-               if (!method)
+               if (!method) {
+                       aot_printerrf (acfg, "Failed to load methodspec 0x%x due to %s.\n", token, mono_error_get_message (&error));
+                       aot_printerrf (acfg, "Run with MONO_LOG_LEVEL=debug for more information.\n");
+                       mono_error_cleanup (&error);
                        continue;
+               }
 
                if (method->klass->image != acfg->image)
                        continue;
@@ -8514,14 +8549,16 @@ collect_methods (MonoAotCompile *acfg)
 
        /* Collect methods */
        for (i = 0; i < image->tables [MONO_TABLE_METHOD].rows; ++i) {
+               MonoError error;
                MonoMethod *method;
                guint32 token = MONO_TOKEN_METHOD_DEF | (i + 1);
 
-               method = mono_get_method (acfg->image, token, NULL);
+               method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error);
 
                if (!method) {
-                       aot_printerrf (acfg, "Failed to load method 0x%x from '%s'.\n", token, image->name);
+                       aot_printerrf (acfg, "Failed to load method 0x%x from '%s' due to %s.\n", token, image->name, mono_error_get_message (&error));
                        aot_printerrf (acfg, "Run with MONO_LOG_LEVEL=debug for more information.\n");
+                       mono_error_cleanup (&error);
                        return FALSE;
                }
                        
@@ -8557,15 +8594,16 @@ collect_methods (MonoAotCompile *acfg)
 
        /* gsharedvt methods */
        for (mindex = 0; mindex < image->tables [MONO_TABLE_METHOD].rows; ++mindex) {
+               MonoError error;
                MonoMethod *method;
                guint32 token = MONO_TOKEN_METHOD_DEF | (mindex + 1);
 
                if (!(acfg->opts & MONO_OPT_GSHAREDVT))
                        continue;
 
-               method = mono_get_method (acfg->image, token, NULL);
-               if (!method)
-                       continue;
+               method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error);
+               report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error));
+
                /*
                if (strcmp (method->name, "gshared2"))
                        continue;