X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fdebugger-agent.c;h=346f964678147d40d64fb585e940ed35d5065209;hb=e92937676ca1b9a06012f4004da60b7cfef002bb;hp=cffa81f3a878a89c37c08fc57fbae7908b816cec;hpb=86a65282f62f6c254eb84af876ce31988181f251;p=mono.git diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index cffa81f3a87..346f9646781 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -47,11 +47,6 @@ #include #endif #include -#ifdef __GNUC__ -/* cygwin's headers do not seem to define these */ -int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD, - char*,DWORD,int); -#endif #endif #ifdef PLATFORM_ANDROID @@ -263,7 +258,10 @@ typedef struct { * event. This is the same as the ctx at step/breakpoint site, but includes changes * to caller saved registers done by set_var (). */ - MonoContext restore_ctx; + MonoThreadUnwindState restore_state; + /* Frames computed from restore_state */ + int restore_frame_count; + StackFrame **restore_frames; /* The currently unloading appdomain */ MonoDomain *domain_unloading; @@ -285,7 +283,7 @@ typedef struct { #define HEADER_LENGTH 11 #define MAJOR_VERSION 2 -#define MINOR_VERSION 39 +#define MINOR_VERSION 40 typedef enum { CMD_SET_VM = 1, @@ -613,6 +611,12 @@ typedef struct ReplyPacket { #define DEBUG(level,s) do { if (G_UNLIKELY ((level) <= log_level)) { s; fflush (log_file); } } while (0) +#ifdef PLATFORM_ANDROID +#define DEBUG_PRINTF(level, ...) do { if (G_UNLIKELY ((level) <= log_level)) { g_print (__VA_ARGS__); } } while (0) +#else +#define DEBUG_PRINTF(level, ...) do { if (G_UNLIKELY ((level) <= log_level)) { fprintf (log_file, __VA_ARGS__); fflush (log_file); } } while (0) +#endif + #ifdef HOST_WIN32 #define get_last_sock_error() WSAGetLastError() #define MONO_EWOULDBLOCK WSAEWOULDBLOCK @@ -795,7 +799,8 @@ static void ids_cleanup (void); static void suspend_init (void); -static void ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint *sp, MonoSeqPointInfo *info, MonoContext *ctx, DebuggerTlsData *tls, gboolean step_to_catch); +static void ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint *sp, MonoSeqPointInfo *info, MonoContext *ctx, DebuggerTlsData *tls, gboolean step_to_catch, + StackFrame **frames, int nframes); static ErrorCode ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilter filter, EventRequest *req); static void ss_destroy (SingleStepReq *req); @@ -1183,7 +1188,7 @@ socket_transport_accept (int socket_fd) if (conn_fd == -1) { fprintf (stderr, "debugger-agent: Unable to listen on %d\n", socket_fd); } else { - DEBUG (1, fprintf (log_file, "Accepted connection from client, connection fd=%d.\n", conn_fd)); + DEBUG_PRINTF (1, "Accepted connection from client, connection fd=%d.\n", conn_fd); } return conn_fd; @@ -1303,7 +1308,7 @@ socket_transport_connect (const char *address) if (agent_config.defer) return; - DEBUG (1, fprintf (log_file, "Listening on %s:%d (timeout=%d ms)...\n", host, port, agent_config.timeout)); + DEBUG_PRINTF (1, "Listening on %s:%d (timeout=%d ms)...\n", host, port, agent_config.timeout); if (agent_config.timeout) { fd_set readfds; @@ -1324,7 +1329,7 @@ socket_transport_connect (const char *address) if (conn_fd == -1) exit (1); - DEBUG (1, fprintf (log_file, "Accepted connection from client, socket fd=%d.\n", conn_fd)); + DEBUG_PRINTF (1, "Accepted connection from client, socket fd=%d.\n", conn_fd); } else { /* Connect to the specified address */ /* FIXME: Respect the timeout */ @@ -1450,7 +1455,7 @@ static DebuggerTransport *transport; static DebuggerTransport transports [MAX_TRANSPORTS]; static int ntransports; -void +MONO_API void mono_debugger_agent_register_transport (DebuggerTransport *trans); void @@ -1865,7 +1870,7 @@ send_buffered_reply_packets (void) send_reply_packets (nreply_packets, reply_packets); for (i = 0; i < nreply_packets; ++i) buffer_free (reply_packets [i].data); - DEBUG (1, fprintf (log_file, "[dbg] Sent %d buffered reply packets [at=%lx].\n", nreply_packets, (long)mono_100ns_ticks () / 10000)); + DEBUG_PRINTF (1, "[dbg] Sent %d buffered reply packets [at=%lx].\n", nreply_packets, (long)mono_100ns_ticks () / 10000); nreply_packets = 0; } @@ -2304,7 +2309,7 @@ decode_ptr_id (guint8 *buf, guint8 **endbuf, guint8 *limit, IdType type, MonoDom dbg_unlock (); if (res->domain == NULL) { - DEBUG (0, fprintf (log_file, "ERR_UNLOADED, id=%d, type=%d.\n", id, type)); + DEBUG_PRINTF (0, "ERR_UNLOADED, id=%d, type=%d.\n", id, type); *err = ERR_UNLOADED; return NULL; } @@ -2334,7 +2339,7 @@ decode_typeid (guint8 *buf, guint8 **endbuf, guint8 *limit, MonoDomain **domain, char *s; s = mono_type_full_name (&klass->byval_arg); - DEBUG(2, fprintf (log_file, "[dbg] recv class [%s]\n", s)); + DEBUG_PRINTF (2, "[dbg] recv class [%s]\n", s); g_free (s); } return klass; @@ -2362,7 +2367,7 @@ decode_methodid (guint8 *buf, guint8 **endbuf, guint8 *limit, MonoDomain **domai char *s; s = mono_method_full_name (m, TRUE); - DEBUG(2, fprintf (log_file, "[dbg] recv method [%s]\n", s)); + DEBUG_PRINTF (2, "[dbg] recv method [%s]\n", s); g_free (s); } return m; @@ -2395,9 +2400,9 @@ buffer_add_typeid (Buffer *buf, MonoDomain *domain, MonoClass *klass) s = mono_type_full_name (&klass->byval_arg); if (GetCurrentThreadId () == debugger_thread_id) - DEBUG(2, fprintf (log_file, "[dbg] send class [%s]\n", s)); + DEBUG_PRINTF (2, "[dbg] send class [%s]\n", s); else - DEBUG(2, fprintf (log_file, "[%p] send class [%s]\n", (gpointer)GetCurrentThreadId (), s)); + DEBUG_PRINTF (2, "[%p] send class [%s]\n", (gpointer)GetCurrentThreadId (), s); g_free (s); } } @@ -2410,7 +2415,7 @@ buffer_add_methodid (Buffer *buf, MonoDomain *domain, MonoMethod *method) char *s; s = mono_method_full_name (method, 1); - DEBUG(2, fprintf (log_file, "[dbg] send method [%s]\n", s)); + DEBUG_PRINTF (2, "[dbg] send method [%s]\n", s); g_free (s); } } @@ -2422,7 +2427,7 @@ buffer_add_assemblyid (Buffer *buf, MonoDomain *domain, MonoAssembly *assembly) id = buffer_add_ptr_id (buf, domain, ID_ASSEMBLY, assembly); if (G_UNLIKELY (log_level >= 2) && assembly) - DEBUG(2, fprintf (log_file, "[dbg] send assembly [%s][%s][%d]\n", assembly->aname.name, domain->friendly_name, id)); + DEBUG_PRINTF (2, "[dbg] send assembly [%s][%s][%d]\n", assembly->aname.name, domain->friendly_name, id); } static inline void @@ -2567,7 +2572,7 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, void *sigctx, Mono if (sigctx) ip = mono_arch_ip_from_context (sigctx); else if (info) - ip = MONO_CONTEXT_GET_IP (&info->suspend_state.ctx); + ip = MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx); else ip = NULL; @@ -2581,7 +2586,7 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, void *sigctx, Mono if (ji) { /* Running managed code, will be suspended by the single step code */ - DEBUG (1, fprintf (log_file, "[%p] Received interrupt while at %s(%p), continuing.\n", (gpointer)(gsize)tid, jinfo_get_method (ji)->name, ip)); + DEBUG_PRINTF (1, "[%p] Received interrupt while at %s(%p), continuing.\n", (gpointer)(gsize)tid, jinfo_get_method (ji)->name, ip); return TRUE; } else { /* @@ -2597,7 +2602,7 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, void *sigctx, Mono // FIXME: printf is not signal safe, but this is only used during // debugger debugging if (ip) - DEBUG (1, fprintf (log_file, "[%p] Received interrupt while at %p, treating as suspended.\n", (gpointer)(gsize)tid, ip)); + DEBUG_PRINTF (1, "[%p] Received interrupt while at %p, treating as suspended.\n", (gpointer)(gsize)tid, ip); //save_thread_context (&ctx); if (!tls->thread) @@ -2624,7 +2629,7 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, void *sigctx, Mono */ mono_walk_stack_with_ctx (get_last_frame, &ctx, MONO_UNWIND_NONE, &data); } else if (info) { - mono_get_eh_callbacks ()->mono_walk_stack_with_state (get_last_frame, &info->suspend_state, MONO_UNWIND_SIGNAL_SAFE, &data); + mono_get_eh_callbacks ()->mono_walk_stack_with_state (get_last_frame, mono_thread_info_get_suspend_state (info), MONO_UNWIND_SIGNAL_SAFE, &data); } if (data.last_frame_set) { memcpy (&tls->async_last_frame, &data.last_frame, sizeof (StackFrameInfo)); @@ -2665,7 +2670,7 @@ mono_debugger_agent_thread_interrupt (void *sigctx, MonoJitInfo *ji) tls = mono_native_tls_get_value (debugger_tls_id); if (!tls) { - DEBUG (1, fprintf (log_file, "[%p] Received interrupt with no TLS, continuing.\n", (gpointer)GetCurrentThreadId ())); + DEBUG_PRINTF (1, "[%p] Received interrupt with no TLS, continuing.\n", (gpointer)GetCurrentThreadId ()); return FALSE; } @@ -2702,6 +2707,24 @@ reset_native_thread_suspend_state (gpointer key, gpointer value, gpointer user_d } } +typedef struct { + DebuggerTlsData *tls; + gboolean valid_info; +} InterruptData; + +static SuspendThreadResult +debugger_interrupt_critical (MonoThreadInfo *info, gpointer user_data) +{ + InterruptData *data = user_data; + MonoJitInfo *ji; + + data->valid_info = TRUE; + ji = mono_jit_info_table_find (mono_thread_info_get_suspend_state (info)->unwind_data [MONO_UNWIND_DATA_DOMAIN], MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx)); + + thread_interrupt (data->tls, info, NULL, ji); + return MonoResumeThread; +} + /* * notify_thread: * @@ -2720,7 +2743,7 @@ notify_thread (gpointer key, gpointer value, gpointer user_data) if (GetCurrentThreadId () == tid || tls->terminated) return; - DEBUG(1, fprintf (log_file, "[%p] Interrupting %p...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid)); + DEBUG_PRINTF (1, "[%p] Interrupting %p...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid); /* * OSX can (and will) coalesce signals, so sending multiple pthread_kills does not @@ -2742,22 +2765,16 @@ notify_thread (gpointer key, gpointer value, gpointer user_data) /* This is _not_ equivalent to ves_icall_System_Threading_Thread_Abort () */ if (mono_thread_info_new_interrupt_enabled ()) { - MonoThreadInfo *info; - MonoJitInfo *ji; + InterruptData interrupt_data = { 0 }; + interrupt_data.tls = tls; - info = mono_thread_info_safe_suspend_sync ((MonoNativeThreadId)(gpointer)(gsize)thread->tid, FALSE); - if (!info) { - DEBUG(1, fprintf (log_file, "[%p] mono_thread_info_suspend_sync () failed for %p...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid)); + mono_thread_info_safe_suspend_and_run ((MonoNativeThreadId)(gpointer)(gsize)thread->tid, FALSE, debugger_interrupt_critical, &interrupt_data); + if (!interrupt_data.valid_info) { + DEBUG_PRINTF (1, "[%p] mono_thread_info_suspend_sync () failed for %p...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid); /* * Attached thread which died without detaching. */ tls->terminated = TRUE; - } else { - ji = mono_jit_info_table_find (info->suspend_state.unwind_data [MONO_UNWIND_DATA_DOMAIN], MONO_CONTEXT_GET_IP (&info->suspend_state.ctx)); - - thread_interrupt (tls, info, NULL, ji); - - mono_thread_info_finish_suspend_and_resume (info); } } else { #ifdef HOST_WIN32 @@ -2766,7 +2783,7 @@ notify_thread (gpointer key, gpointer value, gpointer user_data) #else res = mono_thread_kill (thread, mono_thread_get_abort_signal ()); if (res) { - DEBUG(1, fprintf (log_file, "[%p] mono_thread_kill () failed for %p: %d...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid, res)); + DEBUG_PRINTF (1, "[%p] mono_thread_kill () failed for %p: %d...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid, res); /* * Attached thread which died without detaching. */ @@ -2799,7 +2816,7 @@ process_suspend (DebuggerTlsData *tls, MonoContext *ctx) if (suspend_count - tls->resume_count > 0) tls->suspending = TRUE; - DEBUG(1, fprintf (log_file, "[%p] Received single step event for suspending.\n", (gpointer)GetCurrentThreadId ())); + DEBUG_PRINTF (1, "[%p] Received single step event for suspending.\n", (gpointer)GetCurrentThreadId ()); if (suspend_count - tls->resume_count == 0) { /* @@ -2807,7 +2824,7 @@ process_suspend (DebuggerTlsData *tls, MonoContext *ctx) * suspending is still active. * FIXME: This slows down single threaded invokes. */ - DEBUG(1, fprintf (log_file, "[%p] Ignored during single threaded invoke.\n", (gpointer)GetCurrentThreadId ())); + DEBUG_PRINTF (1, "[%p] Ignored during single threaded invoke.\n", (gpointer)GetCurrentThreadId ()); return; } @@ -2838,7 +2855,7 @@ suspend_vm (void) suspend_count ++; - DEBUG(1, fprintf (log_file, "[%p] Suspending vm...\n", (gpointer)GetCurrentThreadId ())); + DEBUG_PRINTF (1, "[%p] Suspending vm...\n", (gpointer)GetCurrentThreadId ()); if (suspend_count == 1) { // FIXME: Is it safe to call this inside the lock ? @@ -2877,7 +2894,7 @@ resume_vm (void) g_assert (suspend_count > 0); suspend_count --; - DEBUG(1, fprintf (log_file, "[%p] Resuming vm, suspend count=%d...\n", (gpointer)GetCurrentThreadId (), suspend_count)); + DEBUG_PRINTF (1, "[%p] Resuming vm, suspend count=%d...\n", (gpointer)GetCurrentThreadId (), suspend_count); if (suspend_count == 0) { // FIXME: Is it safe to call this inside the lock ? @@ -2920,7 +2937,7 @@ resume_thread (MonoInternalThread *thread) g_assert (suspend_count > 0); - DEBUG(1, fprintf (log_file, "[sdb] Resuming thread %p...\n", (gpointer)(gssize)thread->tid)); + DEBUG_PRINTF (1, "[sdb] Resuming thread %p...\n", (gpointer)(gssize)thread->tid); tls->resume_count += suspend_count; @@ -2938,22 +2955,32 @@ resume_thread (MonoInternalThread *thread) } static void -invalidate_frames (DebuggerTlsData *tls) +free_frames (StackFrame **frames, int nframes) { int i; + for (i = 0; i < nframes; ++i) { + if (frames [i]->jit) + mono_debug_free_method_jit_info (frames [i]->jit); + g_free (frames [i]); + } + g_free (frames); +} + +static void +invalidate_frames (DebuggerTlsData *tls) +{ if (!tls) tls = mono_native_tls_get_value (debugger_tls_id); g_assert (tls); - for (i = 0; i < tls->frame_count; ++i) { - if (tls->frames [i]->jit) - mono_debug_free_method_jit_info (tls->frames [i]->jit); - g_free (tls->frames [i]); - } - g_free (tls->frames); + free_frames (tls->frames, tls->frame_count); tls->frame_count = 0; tls->frames = NULL; + + free_frames (tls->restore_frames, tls->restore_frame_count); + tls->restore_frame_count = 0; + tls->restore_frames = NULL; } /* @@ -2993,7 +3020,7 @@ suspend_current (void) MONO_SEM_POST (&suspend_sem); } - DEBUG(1, fprintf (log_file, "[%p] Suspended.\n", (gpointer)GetCurrentThreadId ())); + DEBUG_PRINTF (1, "[%p] Suspended.\n", (gpointer)GetCurrentThreadId ()); while (suspend_count - tls->resume_count > 0) { #ifdef HOST_WIN32 @@ -3019,7 +3046,7 @@ suspend_current (void) mono_mutex_unlock (&suspend_mutex); - DEBUG(1, fprintf (log_file, "[%p] Resumed.\n", (gpointer)GetCurrentThreadId ())); + DEBUG_PRINTF (1, "[%p] Resumed.\n", (gpointer)GetCurrentThreadId ()); if (tls->pending_invoke) { /* Save the original context */ @@ -3075,7 +3102,7 @@ wait_for_suspend (void) while (TRUE) { nwait = count_threads_to_wait_for (); if (nwait) { - DEBUG(1, fprintf (log_file, "Waiting for %d(%d) threads to suspend...\n", nwait, nthreads)); + DEBUG_PRINTF (1, "Waiting for %d(%d) threads to suspend...\n", nwait, nthreads); err = MONO_SEM_WAIT (&suspend_sem); g_assert (err == 0); waited = TRUE; @@ -3085,7 +3112,7 @@ wait_for_suspend (void) } if (waited) - DEBUG(1, fprintf (log_file, "%d threads suspended.\n", nthreads)); + DEBUG_PRINTF (1, "%d threads suspended.\n", nthreads); } /* @@ -3154,7 +3181,7 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data) info->il_offset = mono_debug_il_offset_from_address (method, info->domain, info->native_offset); } - DEBUG (1, fprintf (log_file, "\tFrame: %s:%x(%x) %d\n", mono_method_full_name (method, TRUE), info->il_offset, info->native_offset, info->managed)); + DEBUG_PRINTF (1, "\tFrame: %s:%x(%x) %d\n", mono_method_full_name (method, TRUE), info->il_offset, info->native_offset, info->managed); if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) { if (!CHECK_PROTOCOL_VERSION (2, 17)) @@ -3207,6 +3234,35 @@ process_filter_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data return process_frame (info, ctx, user_data); } +/* + * Return a malloc-ed list of StackFrame structures. + */ +static StackFrame** +compute_frame_info_from (MonoInternalThread *thread, DebuggerTlsData *tls, MonoThreadUnwindState *state, int *out_nframes) +{ + ComputeFramesUserData user_data; + MonoUnwindOptions opts = MONO_UNWIND_DEFAULT|MONO_UNWIND_REG_LOCATIONS; + StackFrame **res; + int i, nframes; + GSList *l; + + user_data.tls = tls; + user_data.frames = NULL; + + mono_walk_stack_with_state (process_frame, state, opts, &user_data); + + nframes = g_slist_length (user_data.frames); + res = g_new0 (StackFrame*, nframes); + l = user_data.frames; + for (i = 0; i < nframes; ++i) { + res [i] = l->data; + l = l->next; + } + *out_nframes = nframes; + + return res; +} + static void compute_frame_info (MonoInternalThread *thread, DebuggerTlsData *tls) { @@ -3220,7 +3276,7 @@ compute_frame_info (MonoInternalThread *thread, DebuggerTlsData *tls) if (tls->frames && tls->frames_up_to_date) return; - DEBUG(1, fprintf (log_file, "Frames for %p(tid=%lx):\n", thread, (glong)thread->tid)); + DEBUG_PRINTF (1, "Frames for %p(tid=%lx):\n", thread, (glong)thread->tid); user_data.tls = tls; user_data.frames = NULL; @@ -3342,6 +3398,89 @@ strdup_tolower (char *s) return s2; } +/* + * Same as g_path_get_basename () but handles windows paths as well, + * which can occur in .mdb files created by pdb2mdb. + */ +static char* +dbg_path_get_basename (const char *filename) +{ + char *r; + + if (!filename || strchr (filename, '/') || !strchr (filename, '\\')) + return g_path_get_basename (filename); + + /* From gpath.c */ + + /* No separator -> filename */ + r = strrchr (filename, '\\'); + if (r == NULL) + return g_strdup (filename); + + /* Trailing slash, remove component */ + if (r [1] == 0){ + char *copy = g_strdup (filename); + copy [r-filename] = 0; + r = strrchr (copy, '\\'); + + if (r == NULL){ + g_free (copy); + return g_strdup ("/"); + } + r = g_strdup (&r[1]); + g_free (copy); + return r; + } + + return g_strdup (&r[1]); +} + +static void +init_jit_info_dbg_attrs (MonoJitInfo *ji) +{ + static MonoClass *hidden_klass, *step_through_klass, *non_user_klass; + MonoCustomAttrInfo *ainfo; + + if (ji->dbg_attrs_inited) + return; + + if (!hidden_klass) { + hidden_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerHiddenAttribute"); + g_assert (hidden_klass); + } + if (!step_through_klass) { + step_through_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerStepThroughAttribute"); + g_assert (step_through_klass); + } + if (!non_user_klass) { + non_user_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerNonUserCodeAttribute"); + g_assert (non_user_klass); + } + + ainfo = mono_custom_attrs_from_method (jinfo_get_method (ji)); + if (ainfo) { + if (mono_custom_attrs_has_attr (ainfo, hidden_klass)) + ji->dbg_hidden = TRUE; + if (mono_custom_attrs_has_attr (ainfo, step_through_klass)) + ji->dbg_step_through = TRUE; + if (mono_custom_attrs_has_attr (ainfo, non_user_klass)) + ji->dbg_non_user_code = TRUE; + mono_custom_attrs_free (ainfo); + } + + ainfo = mono_custom_attrs_from_class (jinfo_get_method (ji)->klass); + if (ainfo) { + if (mono_custom_attrs_has_attr (ainfo, step_through_klass)) + ji->dbg_step_through = TRUE; + if (mono_custom_attrs_has_attr (ainfo, non_user_klass)) + ji->dbg_non_user_code = TRUE; + mono_custom_attrs_free (ainfo); + } + + mono_memory_barrier (); + ji->dbg_attrs_inited = TRUE; +} + /* * EVENT HANDLING */ @@ -3436,7 +3575,7 @@ create_event_list (EventKind event, GPtrArray *reqs, MonoJitInfo *ji, EventInfo if (g_hash_table_lookup (mod->data.source_files, s)) found = TRUE; else { - char *s2 = g_path_get_basename (sinfo->source_file); + char *s2 = dbg_path_get_basename (sinfo->source_file); char *s3 = strdup_tolower (s2); if (g_hash_table_lookup (mod->data.source_files, s3)) @@ -3465,74 +3604,17 @@ create_event_list (EventKind event, GPtrArray *reqs, MonoJitInfo *ji, EventInfo (jinfo_get_method (ji) != ((SingleStepReq*)req->info)->start_method)) filtered = TRUE; if ((mod->data.filter & STEP_FILTER_DEBUGGER_HIDDEN) && ji) { - MonoCustomAttrInfo *ainfo; - static MonoClass *klass; - - if (!klass) { - klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerHiddenAttribute"); - g_assert (klass); - } - if (!ji->dbg_hidden_inited) { - ainfo = mono_custom_attrs_from_method (jinfo_get_method (ji)); - if (ainfo) { - if (mono_custom_attrs_has_attr (ainfo, klass)) - ji->dbg_hidden = TRUE; - mono_custom_attrs_free (ainfo); - } - ji->dbg_hidden_inited = TRUE; - } + init_jit_info_dbg_attrs (ji); if (ji->dbg_hidden) filtered = TRUE; } if ((mod->data.filter & STEP_FILTER_DEBUGGER_STEP_THROUGH) && ji) { - MonoCustomAttrInfo *ainfo; - static MonoClass *klass; - - if (!klass) { - klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerStepThroughAttribute"); - g_assert (klass); - } - if (!ji->dbg_step_through_inited) { - ainfo = mono_custom_attrs_from_method (jinfo_get_method (ji)); - if (ainfo) { - if (mono_custom_attrs_has_attr (ainfo, klass)) - ji->dbg_step_through = TRUE; - mono_custom_attrs_free (ainfo); - } - ainfo = mono_custom_attrs_from_class (jinfo_get_method (ji)->klass); - if (ainfo) { - if (mono_custom_attrs_has_attr (ainfo, klass)) - ji->dbg_step_through = TRUE; - mono_custom_attrs_free (ainfo); - } - ji->dbg_step_through_inited = TRUE; - } + init_jit_info_dbg_attrs (ji); if (ji->dbg_step_through) filtered = TRUE; } if ((mod->data.filter & STEP_FILTER_DEBUGGER_NON_USER_CODE) && ji) { - MonoCustomAttrInfo *ainfo; - static MonoClass *klass; - - if (!klass) { - klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerNonUserCodeAttribute"); - g_assert (klass); - } - if (!ji->dbg_non_user_code_inited) { - ainfo = mono_custom_attrs_from_method (jinfo_get_method (ji)); - if (ainfo) { - if (mono_custom_attrs_has_attr (ainfo, klass)) - ji->dbg_non_user_code = TRUE; - mono_custom_attrs_free (ainfo); - } - ainfo = mono_custom_attrs_from_class (jinfo_get_method (ji)->klass); - if (ainfo) { - if (mono_custom_attrs_has_attr (ainfo, klass)) - ji->dbg_non_user_code = TRUE; - mono_custom_attrs_free (ainfo); - } - ji->dbg_non_user_code_inited = TRUE; - } + init_jit_info_dbg_attrs (ji); if (ji->dbg_non_user_code) filtered = TRUE; } @@ -3603,28 +3685,28 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx int nevents; if (!inited) { - DEBUG (2, fprintf (log_file, "Debugger agent not initialized yet: dropping %s\n", event_to_string (event))); + DEBUG_PRINTF (2, "Debugger agent not initialized yet: dropping %s\n", event_to_string (event)); return; } if (!vm_start_event_sent && event != EVENT_KIND_VM_START) { // FIXME: We miss those events - DEBUG (2, fprintf (log_file, "VM start event not sent yet: dropping %s\n", event_to_string (event))); + DEBUG_PRINTF (2, "VM start event not sent yet: dropping %s\n", event_to_string (event)); return; } if (vm_death_event_sent) { - DEBUG (2, fprintf (log_file, "VM death event has been sent: dropping %s\n", event_to_string (event))); + DEBUG_PRINTF (2, "VM death event has been sent: dropping %s\n", event_to_string (event)); return; } if (mono_runtime_is_shutting_down () && event != EVENT_KIND_VM_DEATH) { - DEBUG (2, fprintf (log_file, "Mono runtime is shutting down: dropping %s\n", event_to_string (event))); + DEBUG_PRINTF (2, "Mono runtime is shutting down: dropping %s\n", event_to_string (event)); return; } if (disconnected) { - DEBUG (2, fprintf (log_file, "Debugger client is not connected: dropping %s\n", event_to_string (event))); + DEBUG_PRINTF (2, "Debugger client is not connected: dropping %s\n", event_to_string (event)); return; } @@ -3772,7 +3854,7 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx events = NULL; if (!send_success) { - DEBUG (2, fprintf (log_file, "Sending command %s failed.\n", event_to_string (event))); + DEBUG_PRINTF (2, "Sending command %s failed.\n", event_to_string (event)); return; } @@ -3780,7 +3862,7 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx vm_start_event_sent = TRUE; } - DEBUG (1, fprintf (log_file, "[%p] Sent %d events %s(%d), suspend=%d.\n", (gpointer)GetCurrentThreadId (), nevents, event_to_string (event), ecount, suspend_policy)); + DEBUG_PRINTF (1, "[%p] Sent %d events %s(%d), suspend=%d.\n", (gpointer)GetCurrentThreadId (), nevents, event_to_string (event), ecount, suspend_policy); switch (suspend_policy) { case SUSPEND_POLICY_NONE: @@ -3852,14 +3934,14 @@ thread_startup (MonoProfiler *prof, uintptr_t tid) * For some reason, thread_startup () might be called for the same thread * multiple times (attach ?). */ - DEBUG (1, fprintf (log_file, "[%p] thread_start () called multiple times for %p, ignored.\n", (gpointer)tid, (gpointer)tid)); + DEBUG_PRINTF (1, "[%p] thread_start () called multiple times for %p, ignored.\n", (gpointer)tid, (gpointer)tid); return; } else { /* * thread_end () might not be called for some threads, and the tid could * get reused. */ - DEBUG (1, fprintf (log_file, "[%p] Removing stale data for tid %p.\n", (gpointer)tid, (gpointer)tid)); + DEBUG_PRINTF (1, "[%p] Removing stale data for tid %p.\n", (gpointer)tid, (gpointer)tid); mono_loader_lock (); mono_g_hash_table_remove (thread_to_tls, old_thread); mono_g_hash_table_remove (tid_to_thread, (gpointer)tid); @@ -3876,7 +3958,7 @@ thread_startup (MonoProfiler *prof, uintptr_t tid) tls->thread = thread; mono_native_tls_set_value (debugger_tls_id, tls); - DEBUG (1, fprintf (log_file, "[%p] Thread started, obj=%p, tls=%p.\n", (gpointer)tid, thread, tls)); + DEBUG_PRINTF (1, "[%p] Thread started, obj=%p, tls=%p.\n", (gpointer)tid, thread, tls); mono_loader_lock (); mono_g_hash_table_insert (thread_to_tls, thread, tls); @@ -3915,7 +3997,16 @@ thread_end (MonoProfiler *prof, uintptr_t tid) /* We might be called for threads started before we registered the start callback */ if (thread) { - DEBUG (1, fprintf (log_file, "[%p] Thread terminated, obj=%p, tls=%p.\n", (gpointer)tid, thread, tls)); + DEBUG_PRINTF (1, "[%p] Thread terminated, obj=%p, tls=%p.\n", (gpointer)tid, thread, tls); + + if (GetCurrentThreadId () == tid && !mono_native_tls_get_value (debugger_tls_id)) { + /* + * This can happen on darwin since we deregister threads using pthread dtors. + * process_profiler_event () and the code it calls cannot handle a null TLS value. + */ + return; + } + process_profiler_event (EVENT_KIND_THREAD_DEATH, thread); } } @@ -4225,7 +4316,7 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo seq_point_iterator_init (&it, seq_points); while (seq_point_iterator_next (&it)) - DEBUG (1, fprintf (log_file, "%d\n", it.seq_point.il_offset)); + DEBUG_PRINTF (1, "%d\n", it.seq_point.il_offset); if (error) { mono_error_set_error (error, MONO_ERROR_GENERIC, "%s", s); @@ -4258,7 +4349,7 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo dbg_unlock (); if (it.seq_point.native_offset == SEQ_POINT_NATIVE_OFFSET_DEAD_CODE) { - DEBUG (1, fprintf (log_file, "[dbg] Attempting to insert seq point at dead IL offset %d, ignoring.\n", (int)bp->il_offset)); + DEBUG_PRINTF (1, "[dbg] Attempting to insert seq point at dead IL offset %d, ignoring.\n", (int)bp->il_offset); } else if (count == 0) { #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED mono_arch_set_breakpoint (ji, inst->ip); @@ -4267,7 +4358,7 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo #endif } - DEBUG(1, fprintf (log_file, "[dbg] Inserted breakpoint at %s:0x%x [%p](%d).\n", mono_method_full_name (jinfo_get_method (ji), TRUE), (int)it.seq_point.il_offset, inst->ip, count)); + DEBUG_PRINTF (1, "[dbg] Inserted breakpoint at %s:0x%x [%p](%d).\n", mono_method_full_name (jinfo_get_method (ji), TRUE), (int)it.seq_point.il_offset, inst->ip, count); } static void @@ -4287,7 +4378,7 @@ remove_breakpoint (BreakpointInstance *inst) if (count == 1 && inst->native_offset != SEQ_POINT_NATIVE_OFFSET_DEAD_CODE) { mono_arch_clear_breakpoint (ji, ip); - DEBUG(1, fprintf (log_file, "[dbg] Clear breakpoint at %s [%p].\n", mono_method_full_name (jinfo_get_method (ji), TRUE), ip)); + DEBUG_PRINTF (1, "[dbg] Clear breakpoint at %s [%p].\n", mono_method_full_name (jinfo_get_method (ji), TRUE), ip); } #else NOT_IMPLEMENTED; @@ -4438,7 +4529,7 @@ set_breakpoint (MonoMethod *method, long il_offset, EventRequest *req, MonoError bp->req = req; bp->children = g_ptr_array_new (); - DEBUG(1, fprintf (log_file, "[dbg] Setting %sbreakpoint at %s:0x%x.\n", (req->event_kind == EVENT_KIND_STEP) ? "single step " : "", method ? mono_method_full_name (method, TRUE) : "", (int)il_offset)); + DEBUG_PRINTF (1, "[dbg] Setting %sbreakpoint at %s:0x%x.\n", (req->event_kind == EVENT_KIND_STEP) ? "single step " : "", method ? mono_method_full_name (method, TRUE) : "", (int)il_offset); mono_loader_lock (); @@ -4575,7 +4666,7 @@ ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, DebuggerTlsData *t /* * These seq points are inserted by the JIT after calls, step over needs to skip them. */ - DEBUG (1, fprintf (log_file, "[%p] Seq point at nonempty stack %x while stepping over, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset)); + DEBUG_PRINTF (1, "[%p] Seq point at nonempty stack %x while stepping over, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset); return FALSE; } @@ -4585,7 +4676,7 @@ ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, DebuggerTlsData *t compute_frame_info (tls->thread, tls); if (req->nframes && tls->frame_count && tls->frame_count > req->nframes) { /* Hit the breakpoint in a recursive call */ - DEBUG (1, fprintf (log_file, "[%p] Breakpoint at lower frame while stepping over, continuing single stepping.\n", (gpointer)GetCurrentThreadId ())); + DEBUG_PRINTF (1, "[%p] Breakpoint at lower frame while stepping over, continuing single stepping.\n", (gpointer)GetCurrentThreadId ()); return FALSE; } } @@ -4596,7 +4687,7 @@ ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, DebuggerTlsData *t mono_thread_state_init_from_monoctx (&tls->context, ctx); compute_frame_info (tls->thread, tls); if (ss_req->start_method == method && req->nframes && tls->frame_count == req->nframes) {//Check also frame count(could be recursion) - DEBUG (1, fprintf (log_file, "[%p] Seq point at nonempty stack %x while stepping in, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset)); + DEBUG_PRINTF (1, "[%p] Seq point at nonempty stack %x while stepping in, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset); return FALSE; } } @@ -4611,12 +4702,12 @@ ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, DebuggerTlsData *t if (minfo) loc = mono_debug_symfile_lookup_location (minfo, sp->il_offset); - if (!loc || (loc && method == ss_req->last_method && loc->row == ss_req->last_line)) { - /* Have to continue single stepping */ - if (!loc) - DEBUG(1, fprintf (log_file, "[%p] No line number info for il offset %x, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset)); - else - DEBUG(1, fprintf (log_file, "[%p] Same source line (%d), continuing single stepping.\n", (gpointer)GetCurrentThreadId (), loc->row)); + if (!loc) { + DEBUG_PRINTF (1, "[%p] No line number info for il offset %x, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset); + ss_req->last_method = method; + hit = FALSE; + } else if (loc && method == ss_req->last_method && loc->row == ss_req->last_line) { + DEBUG_PRINTF (1, "[%p] Same source line (%d), continuing single stepping.\n", (gpointer)GetCurrentThreadId (), loc->row); hit = FALSE; } @@ -4647,7 +4738,7 @@ process_breakpoint_inner (DebuggerTlsData *tls) GPtrArray *bp_reqs, *ss_reqs_orig, *ss_reqs; GSList *bp_events = NULL, *ss_events = NULL, *enter_leave_events = NULL; EventKind kind = EVENT_KIND_BREAKPOINT; - MonoContext *ctx = &tls->restore_ctx; + MonoContext *ctx = &tls->restore_state.ctx; MonoMethod *method; MonoSeqPointInfo *info; SeqPoint sp; @@ -4688,7 +4779,7 @@ process_breakpoint_inner (DebuggerTlsData *tls) g_assert (found_sp); - DEBUG(1, fprintf (log_file, "[%p] Breakpoint hit, method=%s, ip=%p, offset=0x%x, sp il offset=0x%x.\n", (gpointer)GetCurrentThreadId (), method->name, ip, native_offset, sp.il_offset)); + DEBUG_PRINTF (1, "[%p] Breakpoint hit, method=%s, ip=%p, offset=0x%x, sp il offset=0x%x.\n", (gpointer)GetCurrentThreadId (), method->name, ip, native_offset, sp.il_offset); bp = NULL; for (i = 0; i < breakpoints->len; ++i) { @@ -4730,7 +4821,7 @@ process_breakpoint_inner (DebuggerTlsData *tls) g_ptr_array_add (ss_reqs, req); /* Start single stepping again from the current sequence point */ - ss_start (ss_req, method, &sp, info, ctx, tls, FALSE); + ss_start (ss_req, method, &sp, info, ctx, tls, FALSE, NULL, 0); } if (ss_reqs->len > 0) @@ -4762,18 +4853,19 @@ static void process_signal_event (void (*func) (DebuggerTlsData*)) { DebuggerTlsData *tls; - MonoContext orig_restore_ctx, ctx; + MonoThreadUnwindState orig_restore_state; + MonoContext ctx; tls = mono_native_tls_get_value (debugger_tls_id); /* Have to save/restore the restore_ctx as we can be called recursively during invokes etc. */ - memcpy (&orig_restore_ctx, &tls->restore_ctx, sizeof (MonoContext)); - memcpy (&tls->restore_ctx, &tls->handler_ctx, sizeof (MonoContext)); + memcpy (&orig_restore_state, &tls->restore_state, sizeof (MonoThreadUnwindState)); + mono_thread_state_init_from_monoctx (&tls->restore_state, &tls->handler_ctx); func (tls); /* This is called when resuming from a signal handler, so it shouldn't return */ - memcpy (&ctx, &tls->restore_ctx, sizeof (MonoContext)); - memcpy (&tls->restore_ctx, &orig_restore_ctx, sizeof (MonoContext)); + memcpy (&ctx, &tls->restore_state.ctx, sizeof (MonoContext)); + memcpy (&tls->restore_state, &orig_restore_state, sizeof (MonoThreadUnwindState)); mono_restore_context (&ctx); g_assert_not_reached (); } @@ -4889,7 +4981,7 @@ process_single_step_inner (DebuggerTlsData *tls) int il_offset, suspend_policy; MonoDomain *domain; GSList *events; - MonoContext *ctx = &tls->restore_ctx; + MonoContext *ctx = &tls->restore_state.ctx; MonoMethod *method; SeqPoint sp; MonoSeqPointInfo *info; @@ -4914,7 +5006,7 @@ process_single_step_inner (DebuggerTlsData *tls) if (log_level > 0) { ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, &domain); - DEBUG (1, fprintf (log_file, "[%p] Single step event (depth=%s) at %s (%p)[0x%x], sp %p, last sp %p\n", (gpointer)GetCurrentThreadId (), ss_depth_to_string (ss_req->depth), mono_method_full_name (jinfo_get_method (ji), TRUE), MONO_CONTEXT_GET_IP (ctx), (int)((guint8*)MONO_CONTEXT_GET_IP (ctx) - (guint8*)ji->code_start), MONO_CONTEXT_GET_SP (ctx), ss_req->last_sp)); + DEBUG_PRINTF (1, "[%p] Single step event (depth=%s) at %s (%p)[0x%x], sp %p, last sp %p\n", (gpointer)GetCurrentThreadId (), ss_depth_to_string (ss_req->depth), mono_method_full_name (jinfo_get_method (ji), TRUE), MONO_CONTEXT_GET_IP (ctx), (int)((guint8*)MONO_CONTEXT_GET_IP (ctx) - (guint8*)ji->code_start), MONO_CONTEXT_GET_SP (ctx), ss_req->last_sp); } ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, &domain); @@ -4946,7 +5038,7 @@ process_single_step_inner (DebuggerTlsData *tls) return; /* Start single stepping again from the current sequence point */ - ss_start (ss_req, method, &sp, info, ctx, tls, FALSE); + ss_start (ss_req, method, &sp, info, ctx, tls, FALSE, NULL, 0); if ((ss_req->filter & STEP_FILTER_STATIC_CTOR) && (method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) && @@ -5011,36 +5103,36 @@ void debugger_agent_single_step_from_context (MonoContext *ctx) { DebuggerTlsData *tls; - MonoContext orig_restore_ctx; + MonoThreadUnwindState orig_restore_state; tls = mono_native_tls_get_value (debugger_tls_id); g_assert (tls); /* Have to save/restore the restore_ctx as we can be called recursively during invokes etc. */ - memcpy (&orig_restore_ctx, &tls->restore_ctx, sizeof (MonoContext)); - memcpy (&tls->restore_ctx, ctx, sizeof (MonoContext)); + memcpy (&orig_restore_state, &tls->restore_state, sizeof (MonoThreadUnwindState)); + mono_thread_state_init_from_monoctx (&tls->restore_state, ctx); process_single_step_inner (tls); - memcpy (ctx, &tls->restore_ctx, sizeof (MonoContext)); - memcpy (&tls->restore_ctx, &orig_restore_ctx, sizeof (MonoContext)); + memcpy (ctx, &tls->restore_state.ctx, sizeof (MonoContext)); + memcpy (&tls->restore_state, &orig_restore_state, sizeof (MonoThreadUnwindState)); } void debugger_agent_breakpoint_from_context (MonoContext *ctx) { DebuggerTlsData *tls; - MonoContext orig_restore_ctx; + MonoThreadUnwindState orig_restore_state; tls = mono_native_tls_get_value (debugger_tls_id); g_assert (tls); - memcpy (&orig_restore_ctx, &tls->restore_ctx, sizeof (MonoContext)); - memcpy (&tls->restore_ctx, ctx, sizeof (MonoContext)); + memcpy (&orig_restore_state, &tls->restore_state, sizeof (MonoContext)); + mono_thread_state_init_from_monoctx (&tls->restore_state, ctx); process_breakpoint_inner (tls); - memcpy (ctx, &tls->restore_ctx, sizeof (MonoContext)); - memcpy (&tls->restore_ctx, &orig_restore_ctx, sizeof (MonoContext)); + memcpy (ctx, &tls->restore_state.ctx, sizeof (MonoContext)); + memcpy (&tls->restore_state, &orig_restore_state, sizeof (MonoThreadUnwindState)); } /* @@ -5118,9 +5210,11 @@ ss_stop (SingleStepReq *ss_req) * Start the single stepping operation given by SS_REQ from the sequence point SP. * If CTX is not set, then this can target any thread. If CTX is set, then TLS should * belong to the same thread as CTX. + * If FRAMES is not-null, use that instead of tls->frames for placing breakpoints etc. */ static void -ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointInfo *info, MonoContext *ctx, DebuggerTlsData *tls, gboolean step_to_catch) +ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointInfo *info, MonoContext *ctx, DebuggerTlsData *tls, + gboolean step_to_catch, StackFrame **frames, int nframes) { int i, j, frame_index; SeqPoint *next_sp, *parent_sp = NULL; @@ -5143,11 +5237,13 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI } else { frame_index = 1; - if (ctx) { + if (ctx && !frames) { /* Need parent frames */ if (!tls->context.valid) mono_thread_state_init_from_monoctx (&tls->context, ctx); compute_frame_info (tls->thread, tls); + frames = tls->frames; + nframes = tls->frame_count; } /* @@ -5156,8 +5252,8 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI */ if (ss_req->depth == STEP_DEPTH_OUT) { /* Ignore seq points in current method */ - while (frame_index < tls->frame_count) { - StackFrame *frame = tls->frames [frame_index]; + while (frame_index < nframes) { + StackFrame *frame = frames [frame_index]; method = frame->method; found_sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp); @@ -5171,8 +5267,8 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI } else { if (sp && sp->next_len == 0) { sp = NULL; - while (frame_index < tls->frame_count) { - StackFrame *frame = tls->frames [frame_index]; + while (frame_index < nframes) { + StackFrame *frame = frames [frame_index]; method = frame->method; found_sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp); @@ -5184,8 +5280,8 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI } } else { /* Have to put a breakpoint into a parent frame since the seq points might not cover all control flow out of the method */ - while (frame_index < tls->frame_count) { - StackFrame *frame = tls->frames [frame_index]; + while (frame_index < nframes) { + StackFrame *frame = frames [frame_index]; parent_sp_method = frame->method; found_sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &parent_info, &local_parent_sp); @@ -5225,11 +5321,11 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI } if (ss_req->nframes == 0) - ss_req->nframes = tls->frame_count; + ss_req->nframes = nframes; if (ss_req->depth == STEP_DEPTH_OVER) { /* Need to stop in catch clauses as well */ - for (i = 0; i < tls->frame_count; ++i) { - StackFrame *frame = tls->frames [i]; + for (i = 0; i < nframes; ++i) { + StackFrame *frame = frames [i]; if (frame->ji) { MonoJitInfo *jinfo = frame->ji; @@ -5261,11 +5357,11 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI } if (enable_global) { - DEBUG (1, fprintf (log_file, "[dbg] Turning on global single stepping.\n")); + DEBUG_PRINTF (1, "[dbg] Turning on global single stepping.\n"); ss_req->global = TRUE; start_single_stepping (); } else if (!ss_req->bps) { - DEBUG (1, fprintf (log_file, "[dbg] Turning on global single stepping.\n")); + DEBUG_PRINTF (1, "[dbg] Turning on global single stepping.\n"); ss_req->global = TRUE; start_single_stepping (); } else { @@ -5287,6 +5383,9 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte MonoMethod *method = NULL; MonoDebugMethodInfo *minfo; gboolean step_to_catch = FALSE; + gboolean set_ip = FALSE; + StackFrame **frames = NULL; + int nframes = 0; if (suspend_count == 0) return ERR_NOT_SUSPENDED; @@ -5295,11 +5394,11 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte // FIXME: Multiple requests if (ss_req) { - DEBUG (0, fprintf (log_file, "Received a single step request while the previous one was still active.\n")); + DEBUG_PRINTF (0, "Received a single step request while the previous one was still active.\n"); return ERR_NOT_IMPLEMENTED; } - DEBUG (1, fprintf (log_file, "[dbg] Starting single step of thread %p (depth=%s).\n", thread, ss_depth_to_string (depth))); + DEBUG_PRINTF (1, "[dbg] Starting single step of thread %p (depth=%s).\n", thread, ss_depth_to_string (depth)); ss_req = g_new0 (SingleStepReq, 1); ss_req->req = req; @@ -5314,6 +5413,15 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte mono_loader_unlock (); g_assert (tls); g_assert (tls->context.valid); + + if (tls->restore_state.valid && MONO_CONTEXT_GET_IP (&tls->context.ctx) != MONO_CONTEXT_GET_IP (&tls->restore_state.ctx)) { + /* + * Need to start single stepping from restore_state and not from the current state + */ + set_ip = TRUE; + frames = compute_frame_info_from (thread, tls, &tls->restore_state, &nframes); + } + ss_req->start_sp = ss_req->last_sp = MONO_CONTEXT_GET_SP (&tls->context.ctx); if (tls->catch_state.valid) { @@ -5348,38 +5456,37 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte ss_req->last_sp = NULL; } - if (!step_to_catch && ss_req->size == STEP_SIZE_LINE) { - StackFrame *frame; + if (!step_to_catch) { + StackFrame *frame = NULL; - /* Compute the initial line info */ - compute_frame_info (thread, tls); + if (set_ip) { + if (frames && nframes) + frame = frames [0]; + } else { + compute_frame_info (thread, tls); - if (tls->frame_count) { - frame = tls->frames [0]; + if (tls->frame_count) + frame = tls->frames [0]; + } - ss_req->last_method = frame->method; - ss_req->last_line = -1; + if (ss_req->size == STEP_SIZE_LINE) { + if (frame) { + ss_req->last_method = frame->method; + ss_req->last_line = -1; - minfo = mono_debug_lookup_method (frame->method); - if (minfo && frame->il_offset != -1) { - MonoDebugSourceLocation *loc = mono_debug_symfile_lookup_location (minfo, frame->il_offset); + minfo = mono_debug_lookup_method (frame->method); + if (minfo && frame->il_offset != -1) { + MonoDebugSourceLocation *loc = mono_debug_symfile_lookup_location (minfo, frame->il_offset); - if (loc) { - ss_req->last_line = loc->row; - g_free (loc); + if (loc) { + ss_req->last_line = loc->row; + g_free (loc); + } } } } - } - - if (!step_to_catch) { - StackFrame *frame; - - compute_frame_info (thread, tls); - - if (tls->frame_count) { - frame = tls->frames [0]; + if (frame) { if (!method && frame->il_offset != -1) { /* FIXME: Sort the table and use a binary search */ found_sp = find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp); @@ -5389,13 +5496,15 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte g_assert (sp); method = frame->method; } - ss_req->start_method = method; } } ss_req->start_method = method; - ss_start (ss_req, method, sp, info, &tls->context.ctx, tls, step_to_catch); + ss_start (ss_req, method, sp, info, set_ip ? &tls->restore_state.ctx : &tls->context.ctx, tls, step_to_catch, frames, nframes); + + if (frames) + free_frames (frames, nframes); return 0; } @@ -5896,7 +6005,7 @@ decode_vtype (MonoType *t, MonoDomain *domain, guint8 *addr, guint8 *buf, guint8 if (t && klass != mono_class_from_mono_type (t)) { char *name = mono_type_full_name (t); char *name2 = mono_type_full_name (&klass->byval_arg); - DEBUG(1, fprintf (log_file, "[%p] Expected value of type %s, got %s.\n", (gpointer)GetCurrentThreadId (), name, name2)); + DEBUG_PRINTF (1, "[%p] Expected value of type %s, got %s.\n", (gpointer)GetCurrentThreadId (), name, name2); g_free (name); g_free (name2); return ERR_INVALID_ARGUMENT; @@ -5931,7 +6040,7 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr, !(t->type == MONO_TYPE_PTR && type == MONO_TYPE_I8) && !(t->type == MONO_TYPE_GENERICINST && type == MONO_TYPE_VALUETYPE)) { char *name = mono_type_full_name (t); - DEBUG(1, fprintf (log_file, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer)GetCurrentThreadId (), name, type)); + DEBUG_PRINTF (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer)GetCurrentThreadId (), name, type); g_free (name); return ERR_INVALID_ARGUMENT; } @@ -6011,7 +6120,7 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr, if (obj) { if (!obj_is_of_type (obj, t)) { - DEBUG (1, fprintf (log_file, "Expected type '%s', got '%s'\n", mono_type_full_name (t), obj->vtable->klass->name)); + DEBUG_PRINTF (1, "Expected type '%s', got '%s'\n", mono_type_full_name (t), obj->vtable->klass->name); return ERR_INVALID_ARGUMENT; } } @@ -6057,7 +6166,7 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr, g_free (vtype_buf); } else { char *name = mono_type_full_name (t); - DEBUG(1, fprintf (log_file, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer)GetCurrentThreadId (), name, type)); + DEBUG_PRINTF (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer)GetCurrentThreadId (), name, type); g_free (name); return ERR_INVALID_ARGUMENT; } @@ -6254,11 +6363,11 @@ set_var (MonoType *t, MonoDebugVarInfo *var, MonoContext *ctx, MonoDomain *domai /* Set value on the stack or in the return ctx */ if (reg_locations [reg]) { /* Saved on the stack */ - DEBUG (1, fprintf (log_file, "[dbg] Setting stack location %p for reg %x to %p.\n", reg_locations [reg], reg, (gpointer)v)); + DEBUG_PRINTF (1, "[dbg] Setting stack location %p for reg %x to %p.\n", reg_locations [reg], reg, (gpointer)v); *(reg_locations [reg]) = v; } else { /* Not saved yet */ - DEBUG (1, fprintf (log_file, "[dbg] Setting context location for reg %x to %p.\n", reg, (gpointer)v)); + DEBUG_PRINTF (1, "[dbg] Setting context location for reg %x to %p.\n", reg, (gpointer)v); mono_arch_context_set_int_reg (restore_ctx, reg, v); } @@ -6469,7 +6578,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 * Invoke this method directly, currently only Environment.Exit () is supported. */ this = NULL; - DEBUG (1, fprintf (log_file, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (invoke->method, TRUE), this ? this->vtable->klass->name : "")); + DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (invoke->method, TRUE), this ? this->vtable->klass->name : ""); mono_runtime_invoke (invoke->method, NULL, invoke->args, &exc); g_assert_not_reached (); } @@ -6487,7 +6596,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 /* Should be null */ int type = decode_byte (p, &p, end); if (type != VALUE_TYPE_ID_NULL) { - DEBUG (1, fprintf (log_file, "[%p] Error: Static vtype method invoked with this argument.\n", (gpointer)GetCurrentThreadId ())); + DEBUG_PRINTF (1, "[%p] Error: Static vtype method invoked with this argument.\n", (gpointer)GetCurrentThreadId ()); return ERR_INVALID_ARGUMENT; } memset (this_buf, 0, mono_class_instance_size (m->klass)); @@ -6504,19 +6613,19 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 if (MONO_CLASS_IS_INTERFACE (m->klass)) { if (!this) { - DEBUG (1, fprintf (log_file, "[%p] Error: Interface method invoked without this argument.\n", (gpointer)GetCurrentThreadId ())); + DEBUG_PRINTF (1, "[%p] Error: Interface method invoked without this argument.\n", (gpointer)GetCurrentThreadId ()); return ERR_INVALID_ARGUMENT; } m = mono_object_get_virtual_method (this, m); - } else if (invoke->flags & INVOKE_FLAG_VIRTUAL) { + } else if ((m->flags & METHOD_ATTRIBUTE_VIRTUAL) && !m->klass->valuetype && invoke->flags & INVOKE_FLAG_VIRTUAL) { if (!this) { - DEBUG (1, fprintf (log_file, "[%p] Error: invoke with INVOKE_FLAG_VIRTUAL flag set without this argument.\n", (gpointer)GetCurrentThreadId ())); + DEBUG_PRINTF (1, "[%p] Error: invoke with INVOKE_FLAG_VIRTUAL flag set without this argument.\n", (gpointer)GetCurrentThreadId ()); return ERR_INVALID_ARGUMENT; } m = mono_object_get_virtual_method (this, m); } - DEBUG (1, fprintf (log_file, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (m, TRUE), this ? this->vtable->klass->name : "")); + DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (m, TRUE), this ? this->vtable->klass->name : ""); if (this && this->vtable->domain != domain) NOT_IMPLEMENTED; @@ -6598,7 +6707,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 else res = mono_runtime_invoke (m, this, args, &exc); mono_stopwatch_stop (&watch); - DEBUG (1, fprintf (log_file, "[%p] Invoke result: %p, exc: %s, time: %ld ms.\n", (gpointer)GetCurrentThreadId (), res, exc ? exc->vtable->klass->name : NULL, (long)mono_stopwatch_elapsed_ms (&watch))); + DEBUG_PRINTF (1, "[%p] Invoke result: %p, exc: %s, time: %ld ms.\n", (gpointer)GetCurrentThreadId (), res, exc ? exc->vtable->klass->name : NULL, (long)mono_stopwatch_elapsed_ms (&watch)); if (exc) { buffer_add_byte (buf, 0); buffer_add_value (buf, &mono_defaults.object_class->byval_arg, &exc, domain); @@ -6737,7 +6846,7 @@ invoke_method (void) tls->resume_count -= invoke->suspend_count; } - DEBUG (1, fprintf (log_file, "[%p] Invoke finished (%d), resume_count = %d.\n", (gpointer)GetCurrentThreadId (), err, tls->resume_count)); + DEBUG_PRINTF (1, "[%p] Invoke finished (%d), resume_count = %d.\n", (gpointer)GetCurrentThreadId (), err, tls->resume_count); /* * Take the loader lock to avoid race conditions with CMD_VM_ABORT_INVOKE: @@ -6832,7 +6941,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) major_version = decode_int (p, &p, end); minor_version = decode_int (p, &p, end); protocol_version_set = TRUE; - DEBUG(1, fprintf (log_file, "[dbg] Protocol version %d.%d, client protocol version %d.%d.\n", MAJOR_VERSION, MINOR_VERSION, major_version, minor_version)); + DEBUG_PRINTF (1, "[dbg] Protocol version %d.%d, client protocol version %d.%d.\n", MAJOR_VERSION, MINOR_VERSION, major_version, minor_version); break; } case CMD_VM_ALL_THREADS: { @@ -6944,12 +7053,12 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) mono_environment_exitcode_set (exit_code); /* Suspend all managed threads since the runtime is going away */ - DEBUG(1, fprintf (log_file, "Suspending all threads...\n")); + DEBUG_PRINTF (1, "Suspending all threads...\n"); mono_thread_suspend_all_other_threads (); - DEBUG(1, fprintf (log_file, "Shutting down the runtime...\n")); + DEBUG_PRINTF (1, "Shutting down the runtime...\n"); mono_runtime_quit (); transport_close2 (); - DEBUG(1, fprintf (log_file, "Exiting...\n")); + DEBUG_PRINTF (1, "Exiting...\n"); exit (exit_code); } @@ -7081,7 +7190,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) fname = decode_string (p, &p, end); ignore_case = decode_byte (p, &p, end); - basename = g_path_get_basename (fname); + basename = dbg_path_get_basename (fname); res_classes = g_ptr_array_new (); res_domains = g_ptr_array_new (); @@ -7100,7 +7209,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) for (i = 0; i < files->len; ++i) { char *s = g_ptr_array_index (files, i); - char *s2 = g_path_get_basename (s); + char *s2 = dbg_path_get_basename (s); char *s3; class_list = g_hash_table_lookup (info->source_file_to_class, s2); @@ -7293,7 +7402,7 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf) req->modifiers [i].subclasses = decode_byte (p, &p, end); else req->modifiers [i].subclasses = TRUE; - DEBUG(1, fprintf (log_file, "[dbg] \tEXCEPTION_ONLY filter (%s%s%s%s).\n", exc_class ? exc_class->name : "all", req->modifiers [i].caught ? ", caught" : "", req->modifiers [i].uncaught ? ", uncaught" : "", req->modifiers [i].subclasses ? ", include-subclasses" : "")); + DEBUG_PRINTF (1, "[dbg] \tEXCEPTION_ONLY filter (%s%s%s%s).\n", exc_class ? exc_class->name : "all", req->modifiers [i].caught ? ", caught" : "", req->modifiers [i].uncaught ? ", uncaught" : "", req->modifiers [i].subclasses ? ", include-subclasses" : ""); if (exc_class) { req->modifiers [i].data.exc_class = exc_class; @@ -7354,7 +7463,7 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf) req->info = set_breakpoint (method, location, req, &error); if (!mono_error_ok (&error)) { g_free (req); - DEBUG(1, fprintf (log_file, "[dbg] Failed to set breakpoint: %s\n", mono_error_get_message (&error))); + DEBUG_PRINTF (1, "[dbg] Failed to set breakpoint: %s\n", mono_error_get_message (&error)); mono_error_cleanup (&error); return ERR_NO_SEQ_POINT_AT_IL_OFFSET; } @@ -7735,7 +7844,7 @@ buffer_add_cattrs (Buffer *buf, MonoDomain *domain, MonoImage *image, MonoClass mono_reflection_create_custom_attr_data_args (image, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &arginfo, &error); if (!mono_error_ok (&error)) { - DEBUG(2, fprintf (log_file, "[dbg] mono_reflection_create_custom_attr_data_args () failed with: '%s'\n", mono_error_get_message (&error))); + DEBUG_PRINTF (2, "[dbg] mono_reflection_create_custom_attr_data_args () failed with: '%s'\n", mono_error_get_message (&error)); mono_error_cleanup (&error); return ERR_LOADER_ERROR; } @@ -8130,7 +8239,7 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint if (command == CMD_TYPE_GET_SOURCE_FILES_2) { buffer_add_string (buf, source_file); } else { - base = g_path_get_basename (source_file); + base = dbg_path_get_basename (source_file); buffer_add_string (buf, base); g_free (base); } @@ -8332,7 +8441,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g buffer_add_string (buf, source_file); } buffer_add_int (buf, n_il_offsets); - DEBUG (10, fprintf (log_file, "Line number table for method %s:\n", mono_method_full_name (method, TRUE))); + DEBUG_PRINTF (10, "Line number table for method %s:\n", mono_method_full_name (method, TRUE)); for (i = 0; i < n_il_offsets; ++i) { const char *srcfile = ""; @@ -8340,7 +8449,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g MonoDebugSourceInfo *sinfo = g_ptr_array_index (source_file_list, source_files [i]); srcfile = sinfo->source_file; } - DEBUG (10, fprintf (log_file, "IL%x -> %s:%d %d %d %d\n", il_offsets [i], srcfile, line_numbers [i], column_numbers ? column_numbers [i] : -1, end_line_numbers ? end_line_numbers [i] : -1, end_column_numbers ? end_column_numbers [i] : -1)); + DEBUG_PRINTF (10, "IL%x -> %s:%d %d %d %d\n", il_offsets [i], srcfile, line_numbers [i], column_numbers ? column_numbers [i] : -1, end_line_numbers ? end_line_numbers [i] : -1, end_column_numbers ? end_column_numbers [i] : -1); buffer_add_int (buf, il_offsets [i]); buffer_add_int (buf, line_numbers [i]); if (CHECK_PROTOCOL_VERSION (2, 13)) @@ -8462,8 +8571,11 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g if (imethod->context.class_inst) { MonoClass *klass = ((MonoMethod *) imethod)->klass; /*Generic methods gets the context of the GTD.*/ - if (mono_class_get_context (klass)) - result = mono_class_inflate_generic_method_full (result, klass, mono_class_get_context (klass)); + if (mono_class_get_context (klass)) { + MonoError error; + result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ + } } } @@ -8574,8 +8686,10 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g break; } } else { - val = mono_ldtoken (method->klass->image, token, &handle_class, NULL); - g_assert (val); + MonoError error; + val = mono_ldtoken_checked (method->klass->image, token, &handle_class, NULL, &error); + if (!val) + g_error ("Could not load token due to %s", mono_error_get_message (&error)); } if (handle_class == mono_defaults.typehandle_class) { @@ -8622,6 +8736,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g break; } case CMD_METHOD_MAKE_GENERIC_METHOD: { + MonoError error; MonoType **type_argv; int i, type_argc; MonoDomain *d; @@ -8649,7 +8764,8 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g tmp_context.class_inst = method->klass->generic_class ? method->klass->generic_class->context.class_inst : NULL; tmp_context.method_inst = ginst; - inflated = mono_class_inflate_generic_method (method, &tmp_context); + inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, &error); + g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */ if (!mono_verifier_is_method_valid_generic_instantiation (inflated)) return ERR_INVALID_ARGUMENT; buffer_add_methodid (buf, domain, inflated); @@ -8813,8 +8929,8 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf) // FIXME: Check that the ip change is safe - DEBUG (1, fprintf (log_file, "[dbg] Setting IP to %s:0x%0x(0x%0x)\n", tls->frames [0]->actual_method->name, (int)sp.il_offset, (int)sp.native_offset)); - MONO_CONTEXT_SET_IP (&tls->restore_ctx, (guint8*)tls->frames [0]->ji->code_start + sp.native_offset); + DEBUG_PRINTF (1, "[dbg] Setting IP to %s:0x%0x(0x%0x)\n", tls->frames [0]->actual_method->name, (int)sp.il_offset, (int)sp.native_offset); + MONO_CONTEXT_SET_IP (&tls->restore_state.ctx, (guint8*)tls->frames [0]->ji->code_start + sp.native_offset); break; } default: @@ -8835,7 +8951,6 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) DebuggerTlsData *tls; StackFrame *frame; MonoDebugMethodJitInfo *jit; - MonoDebugVarInfo *var; MonoMethodSignature *sig; gssize id; MonoMethodHeader *header; @@ -8883,7 +8998,7 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) /* This could happen for aot images with no jit debug info */ s = mono_method_full_name (frame->api_method, TRUE); - DEBUG (1, fprintf (log_file, "[dbg] No debug information found for '%s'.\n", s)); + DEBUG_PRINTF (1, "[dbg] No debug information found for '%s'.\n", s); g_free (s); return ERR_ABSENT_INFORMATION; } @@ -8911,14 +9026,10 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) g_assert (pos >= 0 && pos < jit->num_params); - var = &jit->params [pos]; - add_var (buf, jit, sig->params [pos], &jit->params [pos], &frame->ctx, frame->domain, FALSE); } else { g_assert (pos >= 0 && pos < jit->num_locals); - var = &jit->locals [pos]; - add_var (buf, jit, header->locals [pos], &jit->locals [pos], &frame->ctx, frame->domain, FALSE); } } @@ -8976,7 +9087,7 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) if (err) return err; - set_var (t, var, &frame->ctx, frame->domain, val_buf, frame->reg_locations, &tls->restore_ctx); + set_var (t, var, &frame->ctx, frame->domain, val_buf, frame->reg_locations, &tls->restore_state.ctx); } mono_metadata_free_mh (header); break; @@ -9457,15 +9568,15 @@ wait_for_attach (void) { #ifndef DISABLE_SOCKET_TRANSPORT if (listen_fd == -1) { - DEBUG (1, fprintf (log_file, "[dbg] Invalid listening socket\n")); + DEBUG_PRINTF (1, "[dbg] Invalid listening socket\n"); return FALSE; } /* Block and wait for client connection */ conn_fd = socket_transport_accept (listen_fd); - DEBUG (1, fprintf (log_file, "Accepted connection on %d\n", conn_fd)); + DEBUG_PRINTF (1, "Accepted connection on %d\n", conn_fd); if (conn_fd == -1) { - DEBUG (1, fprintf (log_file, "[dbg] Bad client connection\n")); + DEBUG_PRINTF (1, "[dbg] Bad client connection\n"); return FALSE; } #else @@ -9475,7 +9586,7 @@ wait_for_attach (void) /* Handshake */ disconnected = !transport_handshake (); if (disconnected) { - DEBUG (1, fprintf (log_file, "Transport handshake failed!\n")); + DEBUG_PRINTF (1, "Transport handshake failed!\n"); return FALSE; } @@ -9499,7 +9610,7 @@ debugger_thread (void *arg) gboolean no_reply; gboolean attach_failed = FALSE; - DEBUG (1, fprintf (log_file, "[dbg] Agent thread started, pid=%p\n", (gpointer)GetCurrentThreadId ())); + DEBUG_PRINTF (1, "[dbg] Agent thread started, pid=%p\n", (gpointer)GetCurrentThreadId ()); debugger_thread_id = GetCurrentThreadId (); @@ -9511,7 +9622,7 @@ debugger_thread (void *arg) if (agent_config.defer) { if (!wait_for_attach ()) { - DEBUG (1, fprintf (log_file, "[dbg] Can't attach, aborting debugger thread.\n")); + DEBUG_PRINTF (1, "[dbg] Can't attach, aborting debugger thread.\n"); attach_failed = TRUE; // Don't abort process when we can't listen } else { /* Send start event to client */ @@ -9524,7 +9635,7 @@ debugger_thread (void *arg) /* This will break if the socket is closed during shutdown too */ if (res != HEADER_LENGTH) { - DEBUG (1, fprintf (log_file, "[dbg] transport_recv () returned %d, expected %d.\n", res, HEADER_LENGTH)); + DEBUG_PRINTF (1, "[dbg] transport_recv () returned %d, expected %d.\n", res, HEADER_LENGTH); break; } @@ -9549,7 +9660,7 @@ debugger_thread (void *arg) cmd_str = cmd_num; } - DEBUG (1, fprintf (log_file, "[dbg] Command %s(%s) [%d][at=%lx].\n", command_set_to_string (command_set), cmd_str, id, (long)mono_100ns_ticks () / 10000)); + DEBUG_PRINTF (1, "[dbg] Command %s(%s) [%d][at=%lx].\n", command_set_to_string (command_set), cmd_str, id, (long)mono_100ns_ticks () / 10000); } data = g_malloc (len - HEADER_LENGTH); @@ -9557,7 +9668,7 @@ debugger_thread (void *arg) { res = transport_recv (data, len - HEADER_LENGTH); if (res != len - HEADER_LENGTH) { - DEBUG (1, fprintf (log_file, "[dbg] transport_recv () returned %d, expected %d.\n", res, len - HEADER_LENGTH)); + DEBUG_PRINTF (1, "[dbg] transport_recv () returned %d, expected %d.\n", res, len - HEADER_LENGTH); break; } } @@ -9627,7 +9738,7 @@ debugger_thread (void *arg) buffer_reply_packet (id, err, &buf); } else { send_reply_packet (id, err, &buf); - //DEBUG (1, fprintf (log_file, "[dbg] Sent reply to %d [at=%lx].\n", id, (long)mono_100ns_ticks () / 10000)); + //DEBUG_PRINTF (1, "[dbg] Sent reply to %d [at=%lx].\n", id, (long)mono_100ns_ticks () / 10000); } } @@ -9650,10 +9761,10 @@ debugger_thread (void *arg) mono_cond_signal (&debugger_thread_exited_cond); mono_mutex_unlock (&debugger_thread_exited_mutex); - DEBUG (1, fprintf (log_file, "[dbg] Debugger thread exited.\n")); + DEBUG_PRINTF (1, "[dbg] Debugger thread exited.\n"); if (!attach_failed && command_set == CMD_SET_VM && command == CMD_VM_DISPOSE && !(vm_death_event_sent || mono_runtime_is_shutting_down ())) { - DEBUG (2, fprintf (log_file, "[dbg] Detached - restarting clean debugger thread.\n")); + DEBUG_PRINTF (2, "[dbg] Detached - restarting clean debugger thread.\n"); start_debugger_thread (); }