*
* (C) 2002-2003 Ximian, Inc.
* (C) 2003-2006 Novell, Inc.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include <config.h>
#include <mono/metadata/attach.h>
#include "mono/utils/mono-counters.h"
#include "mono/utils/mono-hwcap.h"
+#include "mono/utils/mono-logger-internals.h"
#include "mini.h"
#include "jit.h"
if (mini_stats_fd)
fprintf (mini_stats_fd, "[");
for (i = 0; i < mono_image_get_table_rows (image, MONO_TABLE_METHOD); ++i) {
- MonoMethod *method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL);
- if (!method)
+ MonoError error;
+ MonoMethod *method = mono_get_method_checked (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL, NULL, &error);
+ if (!method) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
continue;
+ }
if (strncmp (method->name, "test_", 5) == 0) {
MonoCompile *cfg;
/* load the metadata */
for (i = 0; i < mono_image_get_table_rows (image, MONO_TABLE_METHOD); ++i) {
- method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL);
- if (!method)
+ MonoError error;
+ method = mono_get_method_checked (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL, NULL, &error);
+ if (!method) {
+ mono_error_cleanup (&error);
continue;
+ }
mono_class_init (method->klass);
if (!strncmp (method->name, "test_", 5) && mini_stats_fd) {
int i, count = 0, fail_count = 0;
for (i = 0; i < mono_image_get_table_rows (image, MONO_TABLE_METHOD); ++i) {
+ MonoError error;
guint32 token = MONO_TOKEN_METHOD_DEF | (i + 1);
MonoMethodSignature *sig;
if (mono_metadata_has_generic_params (image, token))
continue;
- method = mono_get_method (image, token, NULL);
- if (!method)
+ method = mono_get_method_checked (image, token, NULL, NULL, &error);
+ if (!method) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
continue;
+ }
if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
(method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
int
mono_jit_exec (MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[])
{
+ MonoError error;
MonoImage *image = mono_assembly_get_image (assembly);
MonoMethod *method;
guint32 entry = mono_image_get_entry_point (image);
return 1;
}
- method = mono_get_method (image, entry, NULL);
+ method = mono_get_method_checked (image, entry, NULL, NULL, &error);
if (method == NULL){
- g_print ("The entry point method could not be loaded\n");
+ g_print ("The entry point method could not be loaded due to %s\n", mono_error_get_message (&error));
+ mono_error_cleanup (&error);
mono_environment_exitcode_set (1);
return 1;
}
- return mono_runtime_run_main (method, argc, argv, NULL);
+ if (mono_llvm_only) {
+ MonoObject *exc;
+ int res;
+
+ res = mono_runtime_run_main (method, argc, argv, &exc);
+ if (exc) {
+ mono_unhandled_exception (exc);
+ mono_invoke_unhandled_exception_hook (exc);
+ return 1;
+ }
+ return res;
+ } else {
+ return mono_runtime_run_main (method, argc, argv, NULL);
+ }
}
typedef struct
static int
load_agent (MonoDomain *domain, char *desc)
{
+ MonoError error;
char* col = strchr (desc, ':');
char *agent, *args;
MonoAssembly *agent_assembly;
return 1;
}
- method = mono_get_method (image, entry, NULL);
+ 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\n", agent);
+ g_print ("The entry point method of assembly '%s' could not be loaded due to %s\n", agent, &error);
+ mono_error_cleanup (&error);
g_free (agent);
return 1;
}
pa [0] = main_args;
/* Pass NULL as 'exc' so unhandled exceptions abort the runtime */
- mono_runtime_invoke (method, NULL, pa, NULL);
+ mono_runtime_invoke_checked (method, NULL, pa, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return 0;
}
" --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");
#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);
#if TARGET_OSX
darwin_change_default_file_handles ();
#endif
-
+
if (g_getenv ("MONO_NO_SMP"))
mono_set_use_smp (FALSE);
} 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;
}
#endif
+#ifdef DISABLE_HW_TRAPS
+ // Signal handlers not available
+ {
+ MonoDebugOptions *opt = mini_get_debug_options ();
+ opt->explicit_null_checks = TRUE;
+ }
+#endif
+
if (!argv [i]) {
mini_usage ();
return 1;
/* 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_thread_info_set_name (mono_native_thread_id_get (), "Main");
+
+ if (enable_profile) {
mono_profiler_load (profile_options);
+ mono_profiler_thread_name (mono_native_thread_id_get (), "Main");
+ }
mono_attach_parse_options (attach_options);
* (since Mono does not support having more than one mscorlib runtime
* loaded at once).
*
- * The @runtime_version can be one of these strings: "v1.1.4322" for
- * the 1.1 runtime or "v2.0.50727" for the 2.0 runtime.
+ * The @runtime_version can be one of these strings: "v4.0.30319" for
+ * desktop, "mobile" for mobile or "moonlight" for Silverlight compat.
+ * If an unrecognized string is input, the vm will default to desktop.
*
* Returns: the MonoDomain representing the domain where the assembly
* was loaded.
mono_jit_set_aot_mode (MonoAotMode mode)
{
mono_aot_mode = mode;
- if (mono_aot_mode == MONO_AOT_MODE_LLVMONLY)
+ if (mono_aot_mode == MONO_AOT_MODE_LLVMONLY) {
+ mono_aot_only = TRUE;
mono_llvm_only = TRUE;
+ }
}
/**
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);
}
+