Ejemplo n.º 1
0
Archivo: xdebug.c Proyecto: ANahr/mono
/*
 * mono_save_xdebug_info:
 *
 *   Emit debugging info for METHOD into an assembly file which can be assembled
 * and loaded into gdb to provide debugging info for JITted code.
 * LOCKING: Acquires the loader lock.
 */
void
mono_save_xdebug_info (MonoCompile *cfg)
{
	MonoDebugMethodJitInfo *dmji;

	if (use_gdb_interface) {
		mono_loader_lock ();

		if (!xdebug_syms)
			xdebug_syms = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

		/*
		 * gdb is not designed to handle 1000s of symbol files (one per method). So we
		 * group them into groups of 100.
		 */
		if ((xdebug_method_count % 100) == 0)
			mono_xdebug_flush ();

		xdebug_method_count ++;

		dmji = mono_debug_find_method (cfg->jit_info->method, mono_domain_get ());;
		mono_dwarf_writer_emit_method (xdebug_writer, cfg, cfg->jit_info->method, NULL, NULL, cfg->jit_info->code_start, cfg->jit_info->code_size, cfg->args, cfg->locals, cfg->unwind_ops, dmji);
		mono_debug_free_method_jit_info (dmji);

#if 0
		/* 
		 * Emit a symbol for the code by emitting it at the beginning of the text 
		 * segment, and setting the text segment to have an absolute address.
		 * This symbol can be used to set breakpoints in gdb.
		 * FIXME: This doesn't work when multiple methods are emitted into the same file.
		 */
		sym = get_debug_sym (cfg->jit_info->method, "", xdebug_syms);
		img_writer_emit_section_change (w, ".text", 0);
		if (!xdebug_text_addr) {
			xdebug_text_addr = cfg->jit_info->code_start;
			img_writer_set_section_addr (w, (gssize)xdebug_text_addr);
		}
		img_writer_emit_global_with_size (w, sym, cfg->jit_info->code_size, TRUE);
		img_writer_emit_label (w, sym);
		img_writer_emit_bytes (w, cfg->jit_info->code_start, cfg->jit_info->code_size);
		g_free (sym);
#endif
		
		mono_loader_unlock ();
	} else {
		if (!xdebug_writer)
			return;

		mono_loader_lock ();
		dmji = mono_debug_find_method (cfg->jit_info->method, mono_domain_get ());;
		mono_dwarf_writer_emit_method (xdebug_writer, cfg, cfg->jit_info->method, NULL, NULL, cfg->jit_info->code_start, cfg->jit_info->code_size, cfg->args, cfg->locals, cfg->unwind_ops, dmji);
		mono_debug_free_method_jit_info (dmji);
		fflush (xdebug_fp);
		mono_loader_unlock ();
	}

}
Ejemplo n.º 2
0
void
mono_debug_close_method (MonoCompile *cfg)
{
	MiniDebugMethodInfo *info;
	MonoDebugMethodJitInfo *jit;
	MonoMethodHeader *header;
	MonoMethodSignature *sig;
	MonoDebugMethodAddress *debug_info;
	MonoMethod *method;
	int i;

	info = (MiniDebugMethodInfo *) cfg->debug_info;
	if (!info || !info->jit) {
		if (info)
			g_free (info);
		return;
	}

	method = cfg->method;
	header = mono_method_get_header (method);
	sig = mono_method_signature (method);

	jit = info->jit;
	jit->code_start = cfg->native_code;
	jit->epilogue_begin = cfg->epilog_begin;
	jit->code_size = cfg->code_len;

	if (jit->epilogue_begin)
		   record_line_number (info, jit->epilogue_begin, header->code_size);

	jit->num_params = sig->param_count;
	jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);

	for (i = 0; i < jit->num_locals; i++)
		write_variable (cfg->locals [i], &jit->locals [i]);

	if (sig->hasthis) {
		jit->this_var = g_new0 (MonoDebugVarInfo, 1);
		write_variable (cfg->args [0], jit->this_var);
	}

	for (i = 0; i < jit->num_params; i++)
		write_variable (cfg->args [i + sig->hasthis], &jit->params [i]);

	jit->num_line_numbers = info->line_numbers->len;
	jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);

	for (i = 0; i < jit->num_line_numbers; i++)
		jit->line_numbers [i] = g_array_index (info->line_numbers, MonoDebugLineNumberEntry, i);

	debug_info = mono_debug_add_method (cfg->method_to_register, jit, cfg->domain);

	mono_debug_add_vg_method (method, jit);

	mono_debugger_check_breakpoints (method, debug_info);

	mono_debug_free_method_jit_info (jit);
	g_array_free (info->line_numbers, TRUE);
	g_free (info);
}
Ejemplo n.º 3
0
static void
method_jit_result (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo, int result) {
	if (result == MONO_PROFILE_OK) {
		int i;
		MonoDebugSourceLocation *sourceLoc;
		MonoDebugMethodJitInfo *dmji;
		MonoClass *klass = mono_method_get_class (method);
		char *signature = mono_signature_get_desc (mono_method_signature (method), TRUE);
		char *name = g_strdup_printf ("%s(%s)", mono_method_get_name (method), signature);
		char *classname = g_strdup_printf ("%s%s%s", mono_class_get_namespace (klass), mono_class_get_namespace (klass)[0] != 0 ? "::" : "", mono_class_get_name (klass));
		gpointer code_start = mono_jit_info_get_code_start (jinfo);
		int code_size = mono_jit_info_get_code_size (jinfo);
		
		iJIT_Method_Load vtuneMethod;
		memset(&vtuneMethod, 0, sizeof(vtuneMethod));
		vtuneMethod.method_id = iJIT_GetNewMethodID();
		vtuneMethod.method_name = name;
		vtuneMethod.method_load_address = code_start;
		vtuneMethod.method_size = code_size;
		vtuneMethod.class_file_name = classname;

		dmji = mono_debug_find_method (method, mono_domain_get());

		if (dmji != NULL)
		{
			vtuneMethod.line_number_size = dmji->num_line_numbers;
			vtuneMethod.line_number_table = (vtuneMethod.line_number_size != 0) ?
				(LineNumberInfo*)malloc(sizeof(LineNumberInfo) * vtuneMethod.line_number_size) : NULL;

			for (i = 0; i < dmji->num_line_numbers; ++i)
			{
				sourceLoc = mono_debug_lookup_source_location (method, dmji->line_numbers[i].native_offset, mono_domain_get());
				if (sourceLoc == NULL)
				{
					g_free (vtuneMethod.line_number_table);
					vtuneMethod.line_number_table = NULL;
					vtuneMethod.line_number_size = 0;
					break;
				}
				if (i == 0)
					vtuneMethod.source_file_name = strdup(sourceLoc->source_file);
				vtuneMethod.line_number_table[i].Offset = dmji->line_numbers[i].native_offset;
				vtuneMethod.line_number_table[i].LineNumber = sourceLoc->row;
				mono_debug_free_source_location (sourceLoc);
			}
			mono_debug_free_method_jit_info (dmji);
		}

		iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &vtuneMethod);

		if (vtuneMethod.source_file_name != NULL)
			g_free (vtuneMethod.source_file_name);
		if (vtuneMethod.line_number_table != NULL)
			g_free (vtuneMethod.line_number_table);
	
		g_free (signature);
		g_free (name);
		g_free (classname);
	}
}
Ejemplo n.º 4
0
static gint32
il_offset_from_address (MonoMethod *method, MonoDomain *domain, guint32 native_offset)
{
	MonoDebugMethodJitInfo *jit;
	int i;

	jit = find_method (method, domain);
	if (!jit || !jit->line_numbers)
		goto cleanup_and_fail;

	for (i = jit->num_line_numbers - 1; i >= 0; i--) {
		MonoDebugLineNumberEntry lne = jit->line_numbers [i];

		if (lne.native_offset <= native_offset) {
			mono_debug_free_method_jit_info (jit);
			return lne.il_offset;
		}
	}

cleanup_and_fail:
	mono_debug_free_method_jit_info (jit);
	return -1;
}
Ejemplo n.º 5
0
void
mono_debug_close_method (MonoCompile *cfg)
{
	MiniDebugMethodInfo *info;
	MonoDebugMethodJitInfo *jit;
	MonoMethodHeader *header;
	MonoMethodSignature *sig;
	MonoMethod *method;
	int i;

	info = (MiniDebugMethodInfo *) cfg->debug_info;
	if (!info || !info->jit) {
		if (info)
			g_free (info);
		return;
	}

	method = cfg->method;
	header = cfg->header;
	sig = mono_method_signature (method);

	jit = info->jit;
	jit->code_start = cfg->native_code;
	jit->epilogue_begin = cfg->epilog_begin;
	jit->code_size = cfg->code_len;
	jit->has_var_info = mini_debug_options.mdb_optimizations || MONO_CFG_PROFILE_CALL_CONTEXT (cfg);

	if (jit->epilogue_begin)
		   record_line_number (info, jit->epilogue_begin, header->code_size);

	if (jit->has_var_info) {
		jit->num_params = sig->param_count;
		jit->params = g_new0 (MonoDebugVarInfo, jit->num_params);

		for (i = 0; i < jit->num_locals; i++)
			write_variable (cfg->locals [i], &jit->locals [i]);

		if (sig->hasthis) {
			jit->this_var = g_new0 (MonoDebugVarInfo, 1);
			write_variable (cfg->args [0], jit->this_var);
		}

		for (i = 0; i < jit->num_params; i++)
			write_variable (cfg->args [i + sig->hasthis], &jit->params [i]);

		if (cfg->gsharedvt_info_var) {
			jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
			jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
			write_variable (cfg->gsharedvt_info_var, jit->gsharedvt_info_var);
			write_variable (cfg->gsharedvt_locals_var, jit->gsharedvt_locals_var);
		}
	}

	jit->num_line_numbers = info->line_numbers->len;
	jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers);

	for (i = 0; i < jit->num_line_numbers; i++)
		jit->line_numbers [i] = g_array_index (info->line_numbers, MonoDebugLineNumberEntry, i);

	mono_debug_add_method (cfg->method_to_register, jit, cfg->domain);

	mono_debug_add_vg_method (method, jit);

	mono_debug_free_method_jit_info (jit);
	mono_debug_free_method (cfg);
}