[threads] Rename mono_thread_info_set_name () to mono_native_thread_set_name ().
[mono.git] / mono / mini / driver.c
index a84cd2f6ab049bf3bde009f94c6c947ece646446..3c4b3c65a1fc37b6182b013e80fa4bd7868cb8ab 100644 (file)
@@ -851,6 +851,7 @@ small_id_thread_func (gpointer arg)
 static void
 jit_info_table_test (MonoDomain *domain)
 {
+       MonoError error;
        int i;
 
        g_print ("testing jit_info_table\n");
@@ -879,8 +880,10 @@ jit_info_table_test (MonoDomain *domain)
        sleep (2);
        */
 
-       for (i = 0; i < num_threads; ++i)
-               mono_thread_create (domain, test_thread_func, &thread_datas [i]);
+       for (i = 0; i < num_threads; ++i) {
+               mono_thread_create_checked (domain, test_thread_func, &thread_datas [i], &error);
+               mono_error_assert_ok (&error);
+       }
 }
 #endif
 
@@ -973,6 +976,7 @@ compile_all_methods_thread_main (CompileAllThreadArgs *args)
 static void
 compile_all_methods (MonoAssembly *ass, int verbose, guint32 opts, guint32 recompilation_times)
 {
+       MonoError error;
        CompileAllThreadArgs args;
 
        args.ass = ass;
@@ -984,7 +988,8 @@ compile_all_methods (MonoAssembly *ass, int verbose, guint32 opts, guint32 recom
         * Need to create a mono thread since compilation might trigger
         * running of managed code.
         */
-       mono_thread_create (mono_domain_get (), compile_all_methods_thread_main, &args);
+       mono_thread_create_checked (mono_domain_get (), compile_all_methods_thread_main, &args, &error);
+       mono_error_assert_ok (&error);
 
        mono_thread_manage ();
 }
@@ -1140,7 +1145,7 @@ load_agent (MonoDomain *domain, char *desc)
 
        method = mono_get_method_checked (image, entry, NULL, NULL, &error);
        if (method == NULL){
-               g_print ("The entry point method of assembly '%s' could not be loaded due to %s\n", agent, &error);
+               g_print ("The entry point method of assembly '%s' could not be loaded due to %s\n", agent, mono_error_get_message (&error));
                mono_error_cleanup (&error);
                g_free (agent);
                return 1;
@@ -1149,12 +1154,19 @@ load_agent (MonoDomain *domain, char *desc)
        mono_thread_set_main (mono_thread_current ());
 
        if (args) {
-               main_args = (MonoArray*)mono_array_new (domain, mono_defaults.string_class, 1);
-               mono_array_set (main_args, MonoString*, 0, mono_string_new (domain, args));
+               main_args = (MonoArray*)mono_array_new_checked (domain, mono_defaults.string_class, 1, &error);
+               if (main_args)
+                       mono_array_set (main_args, MonoString*, 0, mono_string_new (domain, args));
        } else {
-               main_args = (MonoArray*)mono_array_new (domain, mono_defaults.string_class, 0);
+               main_args = (MonoArray*)mono_array_new_checked (domain, mono_defaults.string_class, 0, &error);
        }
-
+       if (!main_args) {
+               g_print ("Could not allocate array for main args of assembly '%s' due to %s\n", agent, mono_error_get_message (&error));
+               mono_error_cleanup (&error);
+               g_free (agent);
+               return 1;
+       }
+       
        g_free (agent);
 
        pa [0] = main_args;
@@ -1191,6 +1203,8 @@ mini_usage_jitdeveloper (void)
                 "    --agent=ASSEMBLY[:ARG] Loads the specific agent assembly and executes its Main method with the given argument before loading the main assembly.\n"
                 "    --no-x86-stack-align   Don't align stack on x86\n"
                 "\n"
+                "The options supported by MONO_DEBUG can also be passed on the command line.\n"
+                "\n"
                 "Other options:\n" 
                 "    --graph[=TYPE] METHOD  Draws a graph of the specified method:\n");
        
@@ -1440,6 +1454,7 @@ mono_jit_parse_options (int argc, char * argv[])
 #else
                        mono_use_llvm = TRUE;
 #endif
+               } else if (argv [i][0] == '-' && argv [i][1] == '-' && mini_parse_debug_option (argv [i] + 2)) {
                } else {
                        fprintf (stderr, "Unsupported command line option: '%s'\n", argv [i]);
                        exit (1);
@@ -1634,19 +1649,6 @@ mono_main (int argc, char* argv[])
                        gc_descr = mono_gc_get_description ();
                        g_print ("\tGC:            %s\n", gc_descr);
                        g_free (gc_descr);
-                       if (mini_verbose) {
-                               const char *cerror;
-                               const char *clibpath;
-                               mono_init ("mono");
-                               cerror = mono_check_corlib_version ();
-                               clibpath = mono_defaults.corlib? mono_image_get_filename (mono_defaults.corlib): "unknown";
-                               if (cerror) {
-                                       g_print ("The currently installed mscorlib doesn't match this runtime version.\n");
-                                       g_print ("The error is: %s\n", cerror);
-                                       g_print ("mscorlib.dll loaded at: %s\n", clibpath);
-                                       return 1;
-                               }
-                       }
                        return 0;
                } else if (strcmp (argv [i], "--help") == 0 || strcmp (argv [i], "-h") == 0) {
                        mini_usage ();
@@ -1912,6 +1914,7 @@ mono_main (int argc, char* argv[])
                } else if (strcmp (argv [i], "--nacl-null-checks-off") == 0){
                        nacl_null_checks_off = TRUE;
 #endif
+               } else if (argv [i][0] == '-' && argv [i][1] == '-' && mini_parse_debug_option (argv [i] + 2)) {
                } else {
                        fprintf (stderr, "Unknown command line option: '%s'\n", argv [i]);
                        return 1;
@@ -1929,7 +1932,7 @@ mono_main (int argc, char* argv[])
        }
 #endif
 
-#ifdef DISABLE_HW_TRAPS
+#if defined(DISABLE_HW_TRAPS) || defined(MONO_ARCH_DISABLE_HW_TRAPS)
        // Signal handlers not available
        {
                MonoDebugOptions *opt = mini_get_debug_options ();
@@ -1983,8 +1986,16 @@ mono_main (int argc, char* argv[])
        /* Set rootdir before loading config */
        mono_set_rootdir ();
 
-       if (enable_profile)
+       /*
+        * We only set the native name of the thread since MS.NET leaves the
+        * managed thread name for the main thread as null.
+        */
+       mono_native_thread_set_name (mono_native_thread_id_get (), "Main");
+
+       if (enable_profile) {
                mono_profiler_load (profile_options);
+               mono_profiler_thread_name (MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ()), "Main");
+       }
 
        mono_attach_parse_options (attach_options);
 
@@ -2365,83 +2376,154 @@ mono_set_crash_chaining (gboolean chain_crashes)
        mono_do_crash_chaining = chain_crashes;
 }
 
-void
-mono_parse_env_options (int *ref_argc, char **ref_argv [])
+/**
+ * mono_parse_options_from:
+ * @options: string containing strings 
+ * @ref_argc: pointer to the argc variable that might be updated 
+ * @ref_argv: pointer to the argv string vector variable that might be updated
+ *
+ * This function parses the contents of the `MONO_ENV_OPTIONS`
+ * environment variable as if they were parsed by a command shell
+ * splitting the contents by spaces into different elements of the
+ * @argv vector.  This method supports quoting with both the " and '
+ * characters.  Inside quoting, spaces and tabs are significant,
+ * otherwise, they are considered argument separators.
+ *
+ * The \ character can be used to escape the next character which will
+ * be added to the current element verbatim.  Typically this is used
+ * inside quotes.   If the quotes are not balanced, this method 
+ *
+ * If the environment variable is empty, no changes are made
+ * to the values pointed by @ref_argc and @ref_argv.
+ *
+ * Otherwise the @ref_argv is modified to point to a new array that contains
+ * all the previous elements contained in the vector, plus the values parsed.
+ * The @argc is updated to match the new number of parameters.
+ *
+ * Returns: The value NULL is returned on success, otherwise a g_strdup allocated
+ * string is returned (this is an alias to malloc under normal circumstances) that
+ * contains the error message that happened during parsing.
+ */
+char *
+mono_parse_options_from (const char *options, int *ref_argc, char **ref_argv [])
 {
        int argc = *ref_argc;
        char **argv = *ref_argv;
-
-       const char *env_options = g_getenv ("MONO_ENV_OPTIONS");
-       if (env_options != NULL){
-               GPtrArray *array = g_ptr_array_new ();
-               GString *buffer = g_string_new ("");
-               const char *p;
-               unsigned i;
-               gboolean in_quotes = FALSE;
-               char quote_char = '\0';
-
-               for (p = env_options; *p; p++){
-                       switch (*p){
-                       case ' ': case '\t':
-                               if (!in_quotes) {
-                                       if (buffer->len != 0){
-                                               g_ptr_array_add (array, g_strdup (buffer->str));
-                                               g_string_truncate (buffer, 0);
-                                       }
-                               } else {
-                                       g_string_append_c (buffer, *p);
-                               }
-                               break;
-                       case '\\':
-                               if (p [1]){
-                                       g_string_append_c (buffer, p [1]);
-                                       p++;
-                               }
-                               break;
-                       case '\'':
-                       case '"':
-                               if (in_quotes) {
-                                       if (quote_char == *p)
-                                               in_quotes = FALSE;
-                                       else
-                                               g_string_append_c (buffer, *p);
-                               } else {
-                                       in_quotes = TRUE;
-                                       quote_char = *p;
+       GPtrArray *array = g_ptr_array_new ();
+       GString *buffer = g_string_new ("");
+       const char *p;
+       unsigned i;
+       gboolean in_quotes = FALSE;
+       char quote_char = '\0';
+
+       if (options == NULL)
+               return NULL;
+       
+       for (p = options; *p; p++){
+               switch (*p){
+               case ' ': case '\t':
+                       if (!in_quotes) {
+                               if (buffer->len != 0){
+                                       g_ptr_array_add (array, g_strdup (buffer->str));
+                                       g_string_truncate (buffer, 0);
                                }
-                               break;
-                       default:
+                       } else {
                                g_string_append_c (buffer, *p);
-                               break;
                        }
+                       break;
+               case '\\':
+                       if (p [1]){
+                               g_string_append_c (buffer, p [1]);
+                               p++;
+                       }
+                       break;
+               case '\'':
+               case '"':
+                       if (in_quotes) {
+                               if (quote_char == *p)
+                                       in_quotes = FALSE;
+                               else
+                                       g_string_append_c (buffer, *p);
+                       } else {
+                               in_quotes = TRUE;
+                               quote_char = *p;
+                       }
+                       break;
+               default:
+                       g_string_append_c (buffer, *p);
+                       break;
                }
-               if (in_quotes) {
-                       fprintf (stderr, "Unmatched quotes in value of MONO_ENV_OPTIONS: [%s]\n", env_options);
-                       exit (1);
-               }
-                       
-               if (buffer->len != 0)
-                       g_ptr_array_add (array, g_strdup (buffer->str));
-               g_string_free (buffer, TRUE);
+       }
+       if (in_quotes) 
+               return g_strdup_printf ("Unmatched quotes in value: [%s]\n", options);
+               
+       if (buffer->len != 0)
+               g_ptr_array_add (array, g_strdup (buffer->str));
+       g_string_free (buffer, TRUE);
 
-               if (array->len > 0){
-                       int new_argc = array->len + argc;
-                       char **new_argv = g_new (char *, new_argc + 1);
-                       int j;
+       if (array->len > 0){
+               int new_argc = array->len + argc;
+               char **new_argv = g_new (char *, new_argc + 1);
+               int j;
 
-                       new_argv [0] = argv [0];
-                       
-                       /* First the environment variable settings, to allow the command line options to override */
-                       for (i = 0; i < array->len; i++)
-                               new_argv [i+1] = (char *)g_ptr_array_index (array, i);
-                       i++;
-                       for (j = 1; j < argc; j++)
-                               new_argv [i++] = argv [j];
-                       new_argv [i] = NULL;
-
-                       *ref_argc = new_argc;
-                       *ref_argv = new_argv;
-               }
-               g_ptr_array_free (array, TRUE);
+               new_argv [0] = argv [0];
+               
+               /* First the environment variable settings, to allow the command line options to override */
+               for (i = 0; i < array->len; i++)
+                       new_argv [i+1] = (char *)g_ptr_array_index (array, i);
+               i++;
+               for (j = 1; j < argc; j++)
+                       new_argv [i++] = argv [j];
+               new_argv [i] = NULL;
+
+               *ref_argc = new_argc;
+               *ref_argv = new_argv;
        }
+       g_ptr_array_free (array, TRUE);
+       return NULL;
 }
+
+/**
+ * mono_parse_env_options:
+ * @ref_argc: pointer to the argc variable that might be updated 
+ * @ref_argv: pointer to the argv string vector variable that might be updated
+ *
+ * This function parses the contents of the `MONO_ENV_OPTIONS`
+ * environment variable as if they were parsed by a command shell
+ * splitting the contents by spaces into different elements of the
+ * @argv vector.  This method supports quoting with both the " and '
+ * characters.  Inside quoting, spaces and tabs are significant,
+ * otherwise, they are considered argument separators.
+ *
+ * The \ character can be used to escape the next character which will
+ * be added to the current element verbatim.  Typically this is used
+ * inside quotes.   If the quotes are not balanced, this method 
+ *
+ * If the environment variable is empty, no changes are made
+ * to the values pointed by @ref_argc and @ref_argv.
+ *
+ * Otherwise the @ref_argv is modified to point to a new array that contains
+ * all the previous elements contained in the vector, plus the values parsed.
+ * The @argc is updated to match the new number of parameters.
+ *
+ * If there is an error parsing, this method will terminate the process by
+ * calling exit(1).
+ *
+ * An alternative to this method that allows an arbitrary string to be parsed
+ * and does not exit on error is the `api:mono_parse_options_from`.
+ */
+void
+mono_parse_env_options (int *ref_argc, char **ref_argv [])
+{
+       char *ret;
+       
+       const char *env_options = g_getenv ("MONO_ENV_OPTIONS");
+       if (env_options == NULL)
+               return;
+       ret = mono_parse_options_from (env_options, ref_argc, ref_argv);
+       if (ret == NULL)
+               return;
+       fprintf (stderr, "%s", ret);
+       exit (1);
+}
+