Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial work to allow debugger attaching without performance impact. #1158

Merged
merged 4 commits into from
May 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions mono/metadata/domain-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ struct _MonoJitInfo {
/* Whenever this jit info refers to an interpreter method */
gboolean is_interp:1;

gboolean dbg_ignore : 1;

/* FIXME: Embed this after the structure later*/
gpointer gc_info; /* Currently only used by SGen */

Expand Down
86 changes: 66 additions & 20 deletions mono/mini/debugger-agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,63 @@ mono_debugger_agent_parse_options (char *options)
}
}

static gboolean disable_optimizations = TRUE;

static void
update_mdb_optimizations ()
{
gboolean enable = disable_optimizations;
#ifndef RUNTIME_IL2CPP
mini_get_debug_options ()->gen_sdb_seq_points = enable;
/*
* This is needed because currently we don't handle liveness info.
*/
mini_get_debug_options ()->mdb_optimizations = enable;

#ifndef MONO_ARCH_HAVE_CONTEXT_SET_INT_REG
/* This is needed because we can't set local variables in registers yet */
mono_disable_optimizations (MONO_OPT_LINEARS);
#endif

/*
* The stack walk done from thread_interrupt () needs to be signal safe, but it
* isn't, since it can call into mono_aot_find_jit_info () which is not signal
* safe (#3411). So load AOT info eagerly when the debugger is running as a
* workaround.
*/
mini_get_debug_options ()->load_aot_jit_info_eagerly = enable;
#endif // !RUNTIME_IL2CPP
}

MONO_API void
mono_debugger_set_generate_debug_info (gboolean enable)
{
disable_optimizations = enable;
update_mdb_optimizations ();
}

MONO_API gboolean
mono_debugger_get_generate_debug_info ()
{
return disable_optimizations;
}

MONO_API void
mono_debugger_disconnect ()
{
stop_debugger_thread ();
transport_connect (agent_config.address);
start_debugger_thread ();
}

typedef void (*MonoDebuggerAttachFunc)(gboolean attached);
static MonoDebuggerAttachFunc attach_func;
MONO_API void
mono_debugger_install_attach_detach_callback (MonoDebuggerAttachFunc func)
{
attach_func = func;
}

void
mono_debugger_agent_init (void)
{
Expand Down Expand Up @@ -1117,26 +1174,7 @@ mono_debugger_agent_init (void)
breakpoints_init ();
suspend_init ();

#ifndef RUNTIME_IL2CPP
mini_get_debug_options ()->gen_sdb_seq_points = TRUE;
/*
* This is needed because currently we don't handle liveness info.
*/
mini_get_debug_options ()->mdb_optimizations = TRUE;

#ifndef MONO_ARCH_HAVE_CONTEXT_SET_INT_REG
/* This is needed because we can't set local variables in registers yet */
mono_disable_optimizations (MONO_OPT_LINEARS);
#endif

/*
* The stack walk done from thread_interrupt () needs to be signal safe, but it
* isn't, since it can call into mono_aot_find_jit_info () which is not signal
* safe (#3411). So load AOT info eagerly when the debugger is running as a
* workaround.
*/
mini_get_debug_options ()->load_aot_jit_info_eagerly = TRUE;
#endif // !RUNTIME_IL2CPP
update_mdb_optimizations ();

#ifdef HAVE_SETPGID
if (agent_config.setpgid)
Expand Down Expand Up @@ -4659,6 +4697,8 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo
mini_get_interp_callbacks ()->set_breakpoint (ji, inst->ip);
} else {
#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
if (ji->dbg_ignore)
return;
mono_arch_set_breakpoint (ji, inst->ip);
#else
NOT_IMPLEMENTED;
Expand Down Expand Up @@ -11992,6 +12032,8 @@ debugger_thread (void *arg)
attach_failed = TRUE; // Don't abort process when we can't listen
} else {
mono_set_is_debugger_attached (TRUE);
if (attach_func)
attach_func (TRUE);
/* Send start event to client */
process_profiler_event (EVENT_KIND_VM_START, mono_thread_get_main ());
#ifdef RUNTIME_IL2CPP
Expand All @@ -12008,6 +12050,8 @@ debugger_thread (void *arg)
}
} else {
mono_set_is_debugger_attached (TRUE);
if (attach_func)
attach_func (TRUE);
}

while (!attach_failed) {
Expand Down Expand Up @@ -12142,6 +12186,8 @@ debugger_thread (void *arg)
}

mono_set_is_debugger_attached (FALSE);
if (attach_func)
attach_func (FALSE);

#ifdef RUNTIME_IL2CPP
il2cpp_mono_free_method_signatures();
Expand Down
2 changes: 2 additions & 0 deletions mono/mini/mini.c
Original file line number Diff line number Diff line change
Expand Up @@ -2809,6 +2809,8 @@ create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile)
jinfo->unwind_info = cfg->used_int_regs;
}

jinfo->dbg_ignore = !cfg->gen_sdb_seq_points;

return jinfo;
}

Expand Down