Merge pull request #1936 from esdrubal/DotNetRelativeOrAbsolute
[mono.git] / mono / mini / debugger-agent.c
1 /*
2  * debugger-agent.c: Soft Debugger back-end module
3  *
4  * Author:
5  *   Zoltan Varga (vargaz@gmail.com)
6  *
7  * Copyright 2009-2010 Novell, Inc.
8  * Copyright 2011 Xamarin Inc.
9  */
10
11 #include <config.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #ifdef HAVE_SYS_TYPES_H
16 #include <sys/types.h>
17 #endif
18 #ifdef HAVE_SYS_SELECT_H
19 #include <sys/select.h>
20 #endif
21 #ifdef HAVE_SYS_SOCKET_H
22 #include <sys/socket.h>
23 #endif
24 #ifdef HAVE_NETINET_TCP_H
25 #include <netinet/tcp.h>
26 #endif
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
29 #endif
30 #ifdef HAVE_UNISTD_H
31 #include <unistd.h>
32 #endif
33 #include <errno.h>
34 #include <glib.h>
35
36 #ifdef HAVE_PTHREAD_H
37 #include <pthread.h>
38 #endif
39
40 #ifdef HOST_WIN32
41 #ifdef _MSC_VER
42 #include <winsock2.h>
43 #include <process.h>
44 #endif
45 #include <ws2tcpip.h>
46 #endif
47
48 #ifdef PLATFORM_ANDROID
49 #include <linux/in.h>
50 #include <linux/tcp.h>
51 #include <sys/endian.h>
52 #endif
53
54 #include <mono/metadata/mono-debug.h>
55 #include <mono/metadata/mono-debug-debugger.h>
56 #include <mono/metadata/debug-mono-symfile.h>
57 #include <mono/metadata/gc-internal.h>
58 #include <mono/metadata/environment.h>
59 #include <mono/metadata/threads-types.h>
60 #include <mono/metadata/threadpool-ms.h>
61 #include <mono/metadata/socket-io.h>
62 #include <mono/metadata/assembly.h>
63 #include <mono/metadata/runtime.h>
64 #include <mono/metadata/verify-internals.h>
65 #include <mono/utils/mono-semaphore.h>
66 #include <mono/utils/mono-error-internals.h>
67 #include <mono/utils/mono-stack-unwinding.h>
68 #include <mono/utils/mono-time.h>
69 #include <mono/utils/mono-threads.h>
70 #include <mono/utils/networking.h>
71 #include "debugger-agent.h"
72 #include "mini.h"
73 #include "seq-points.h"
74
75 /*
76  * On iOS we can't use System.Environment.Exit () as it will do the wrong
77  * shutdown sequence.
78 */
79 #if !defined (TARGET_IOS)
80 #define TRY_MANAGED_SYSTEM_ENVIRONMENT_EXIT
81 #endif
82
83
84 #ifndef MONO_ARCH_SOFT_DEBUG_SUPPORTED
85 #define DISABLE_DEBUGGER_AGENT 1
86 #endif
87
88 #ifdef DISABLE_SOFT_DEBUG
89 #define DISABLE_DEBUGGER_AGENT 1
90 #endif
91
92 #ifndef DISABLE_DEBUGGER_AGENT
93
94 #include <mono/utils/mono-mutex.h>
95
96 #define THREAD_TO_INTERNAL(thread) (thread)->internal_thread
97
98 typedef struct {
99         gboolean enabled;
100         char *transport;
101         char *address;
102         int log_level;
103         char *log_file;
104         gboolean suspend;
105         gboolean server;
106         gboolean onuncaught;
107         GSList *onthrow;
108         int timeout;
109         char *launch;
110         gboolean embedding;
111         gboolean defer;
112         int keepalive;
113         gboolean setpgid;
114 } AgentConfig;
115
116 typedef struct
117 {
118         int id;
119         guint32 il_offset, native_offset;
120         MonoDomain *domain;
121         MonoMethod *method;
122         /*
123          * If method is gshared, this is the actual instance, otherwise this is equal to
124          * method.
125          */
126         MonoMethod *actual_method;
127         /*
128          * This is the method which is visible to debugger clients. Same as method,
129          * except for native-to-managed wrappers.
130          */
131         MonoMethod *api_method;
132         MonoContext ctx;
133         MonoDebugMethodJitInfo *jit;
134         MonoJitInfo *ji;
135         int flags;
136         mgreg_t *reg_locations [MONO_MAX_IREGS];
137         /*
138          * Whenever ctx is set. This is FALSE for the last frame of running threads, since
139          * the frame can become invalid.
140          */
141         gboolean has_ctx;
142 } StackFrame;
143
144 typedef struct _InvokeData InvokeData;
145
146 struct _InvokeData
147 {
148         int id;
149         int flags;
150         guint8 *p;
151         guint8 *endp;
152         /* This is the context which needs to be restored after the invoke */
153         MonoContext ctx;
154         gboolean has_ctx;
155         /*
156          * If this is set, invoke this method with the arguments given by ARGS.
157          */
158         MonoMethod *method;
159         gpointer *args;
160         guint32 suspend_count;
161         int nmethods;
162
163         InvokeData *last_invoke;
164 };
165
166 typedef struct {
167         MonoThreadUnwindState context;
168
169         /* This is computed on demand when it is requested using the wire protocol */
170         /* It is freed up when the thread is resumed */
171         int frame_count;
172         StackFrame **frames;
173         /* 
174          * Whenever the frame info is up-to-date. If not, compute_frame_info () will need to
175          * re-compute it.
176          */
177         gboolean frames_up_to_date;
178         /* 
179          * Points to data about a pending invoke which needs to be executed after the thread
180          * resumes.
181          */
182         InvokeData *pending_invoke;
183         /*
184          * Set to TRUE if this thread is suspended in suspend_current () or it is executing
185          * native code.
186          */
187         gboolean suspended;
188         /*
189          * Signals whenever the thread is in the process of suspending, i.e. it will suspend
190          * within a finite amount of time.
191          */
192         gboolean suspending;
193         /*
194          * Set to TRUE if this thread is suspended in suspend_current ().
195          */
196         gboolean really_suspended;
197         /* Used to pass the context to the breakpoint/single step handler */
198         MonoContext handler_ctx;
199         /* Whenever thread_stop () was called for this thread */
200         gboolean terminated;
201
202         /* Whenever to disable breakpoints (used during invokes) */
203         gboolean disable_breakpoints;
204
205         /*
206          * Number of times this thread has been resumed using resume_thread ().
207          */
208         guint32 resume_count;
209
210         MonoInternalThread *thread;
211
212         /*
213          * Information about the frame which transitioned to native code for running
214          * threads.
215          */
216         StackFrameInfo async_last_frame;
217
218         /*
219          * The context where the stack walk can be started for running threads.
220          */
221         MonoThreadUnwindState async_state;
222
223         /*
224      * The context used for filter clauses
225      */
226         MonoThreadUnwindState filter_state;
227
228         gboolean abort_requested;
229
230         /*
231          * The current mono_runtime_invoke invocation.
232          */
233         InvokeData *invoke;
234
235         /*
236          * The context where single stepping should resume while the thread is suspended because
237          * of an EXCEPTION event.
238          */
239         MonoThreadUnwindState catch_state;
240
241         /*
242          * The context which needs to be restored after handling a single step/breakpoint
243          * event. This is the same as the ctx at step/breakpoint site, but includes changes
244          * to caller saved registers done by set_var ().
245          */
246         MonoThreadUnwindState restore_state;
247         /* Frames computed from restore_state */
248         int restore_frame_count;
249         StackFrame **restore_frames;
250
251         /* The currently unloading appdomain */
252         MonoDomain *domain_unloading;
253 } DebuggerTlsData;
254
255 typedef struct {
256         const char *name;
257         void (*connect) (const char *address);
258         void (*close1) (void);
259         void (*close2) (void);
260         gboolean (*send) (void *buf, int len);
261         int (*recv) (void *buf, int len);
262 } DebuggerTransport;
263
264 /* 
265  * Wire Protocol definitions
266  */
267
268 #define HEADER_LENGTH 11
269
270 #define MAJOR_VERSION 2
271 #define MINOR_VERSION 41
272
273 typedef enum {
274         CMD_SET_VM = 1,
275         CMD_SET_OBJECT_REF = 9,
276         CMD_SET_STRING_REF = 10,
277         CMD_SET_THREAD = 11,
278         CMD_SET_ARRAY_REF = 13,
279         CMD_SET_EVENT_REQUEST = 15,
280         CMD_SET_STACK_FRAME = 16,
281         CMD_SET_APPDOMAIN = 20,
282         CMD_SET_ASSEMBLY = 21,
283         CMD_SET_METHOD = 22,
284         CMD_SET_TYPE = 23,
285         CMD_SET_MODULE = 24,
286         CMD_SET_FIELD = 25,
287         CMD_SET_EVENT = 64
288 } CommandSet;
289
290 typedef enum {
291         EVENT_KIND_VM_START = 0,
292         EVENT_KIND_VM_DEATH = 1,
293         EVENT_KIND_THREAD_START = 2,
294         EVENT_KIND_THREAD_DEATH = 3,
295         EVENT_KIND_APPDOMAIN_CREATE = 4,
296         EVENT_KIND_APPDOMAIN_UNLOAD = 5,
297         EVENT_KIND_METHOD_ENTRY = 6,
298         EVENT_KIND_METHOD_EXIT = 7,
299         EVENT_KIND_ASSEMBLY_LOAD = 8,
300         EVENT_KIND_ASSEMBLY_UNLOAD = 9,
301         EVENT_KIND_BREAKPOINT = 10,
302         EVENT_KIND_STEP = 11,
303         EVENT_KIND_TYPE_LOAD = 12,
304         EVENT_KIND_EXCEPTION = 13,
305         EVENT_KIND_KEEPALIVE = 14,
306         EVENT_KIND_USER_BREAK = 15,
307         EVENT_KIND_USER_LOG = 16
308 } EventKind;
309
310 typedef enum {
311         SUSPEND_POLICY_NONE = 0,
312         SUSPEND_POLICY_EVENT_THREAD = 1,
313         SUSPEND_POLICY_ALL = 2
314 } SuspendPolicy;
315
316 typedef enum {
317         ERR_NONE = 0,
318         ERR_INVALID_OBJECT = 20,
319         ERR_INVALID_FIELDID = 25,
320         ERR_INVALID_FRAMEID = 30,
321         ERR_NOT_IMPLEMENTED = 100,
322         ERR_NOT_SUSPENDED = 101,
323         ERR_INVALID_ARGUMENT = 102,
324         ERR_UNLOADED = 103,
325         ERR_NO_INVOCATION = 104,
326         ERR_ABSENT_INFORMATION = 105,
327         ERR_NO_SEQ_POINT_AT_IL_OFFSET = 106,
328         ERR_LOADER_ERROR = 200, /*XXX extend the protocol to pass this information down the pipe */
329 } ErrorCode;
330
331 typedef enum {
332         MOD_KIND_COUNT = 1,
333         MOD_KIND_THREAD_ONLY = 3,
334         MOD_KIND_LOCATION_ONLY = 7,
335         MOD_KIND_EXCEPTION_ONLY = 8,
336         MOD_KIND_STEP = 10,
337         MOD_KIND_ASSEMBLY_ONLY = 11,
338         MOD_KIND_SOURCE_FILE_ONLY = 12,
339         MOD_KIND_TYPE_NAME_ONLY = 13,
340         MOD_KIND_NONE = 14
341 } ModifierKind;
342
343 typedef enum {
344         STEP_DEPTH_INTO = 0,
345         STEP_DEPTH_OVER = 1,
346         STEP_DEPTH_OUT = 2
347 } StepDepth;
348
349 typedef enum {
350         STEP_SIZE_MIN = 0,
351         STEP_SIZE_LINE = 1
352 } StepSize;
353
354 typedef enum {
355         STEP_FILTER_NONE = 0,
356         STEP_FILTER_STATIC_CTOR = 1,
357         STEP_FILTER_DEBUGGER_HIDDEN = 2,
358         STEP_FILTER_DEBUGGER_STEP_THROUGH = 4,
359         STEP_FILTER_DEBUGGER_NON_USER_CODE = 8
360 } StepFilter;
361
362 typedef enum {
363         TOKEN_TYPE_STRING = 0,
364         TOKEN_TYPE_TYPE = 1,
365         TOKEN_TYPE_FIELD = 2,
366         TOKEN_TYPE_METHOD = 3,
367         TOKEN_TYPE_UNKNOWN = 4
368 } DebuggerTokenType;
369
370 typedef enum {
371         VALUE_TYPE_ID_NULL = 0xf0,
372         VALUE_TYPE_ID_TYPE = 0xf1,
373         VALUE_TYPE_ID_PARENT_VTYPE = 0xf2
374 } ValueTypeId;
375
376 typedef enum {
377         FRAME_FLAG_DEBUGGER_INVOKE = 1,
378         FRAME_FLAG_NATIVE_TRANSITION = 2
379 } StackFrameFlags;
380
381 typedef enum {
382         INVOKE_FLAG_DISABLE_BREAKPOINTS = 1,
383         INVOKE_FLAG_SINGLE_THREADED = 2,
384         INVOKE_FLAG_RETURN_OUT_THIS = 4,
385         INVOKE_FLAG_RETURN_OUT_ARGS = 8,
386         INVOKE_FLAG_VIRTUAL = 16
387 } InvokeFlags;
388
389 typedef enum {
390         BINDING_FLAGS_IGNORE_CASE = 0x70000000,
391 } BindingFlagsExtensions;
392
393 typedef enum {
394         CMD_VM_VERSION = 1,
395         CMD_VM_ALL_THREADS = 2,
396         CMD_VM_SUSPEND = 3,
397         CMD_VM_RESUME = 4,
398         CMD_VM_EXIT = 5,
399         CMD_VM_DISPOSE = 6,
400         CMD_VM_INVOKE_METHOD = 7,
401         CMD_VM_SET_PROTOCOL_VERSION = 8,
402         CMD_VM_ABORT_INVOKE = 9,
403         CMD_VM_SET_KEEPALIVE = 10,
404         CMD_VM_GET_TYPES_FOR_SOURCE_FILE = 11,
405         CMD_VM_GET_TYPES = 12,
406         CMD_VM_INVOKE_METHODS = 13,
407         CMD_VM_START_BUFFERING = 14,
408         CMD_VM_STOP_BUFFERING = 15
409 } CmdVM;
410
411 typedef enum {
412         CMD_THREAD_GET_FRAME_INFO = 1,
413         CMD_THREAD_GET_NAME = 2,
414         CMD_THREAD_GET_STATE = 3,
415         CMD_THREAD_GET_INFO = 4,
416         CMD_THREAD_GET_ID = 5,
417         CMD_THREAD_GET_TID = 6,
418         CMD_THREAD_SET_IP = 7
419 } CmdThread;
420
421 typedef enum {
422         CMD_EVENT_REQUEST_SET = 1,
423         CMD_EVENT_REQUEST_CLEAR = 2,
424         CMD_EVENT_REQUEST_CLEAR_ALL_BREAKPOINTS = 3
425 } CmdEvent;
426
427 typedef enum {
428         CMD_COMPOSITE = 100
429 } CmdComposite;
430
431 typedef enum {
432         CMD_APPDOMAIN_GET_ROOT_DOMAIN = 1,
433         CMD_APPDOMAIN_GET_FRIENDLY_NAME = 2,
434         CMD_APPDOMAIN_GET_ASSEMBLIES = 3,
435         CMD_APPDOMAIN_GET_ENTRY_ASSEMBLY = 4,
436         CMD_APPDOMAIN_CREATE_STRING = 5,
437         CMD_APPDOMAIN_GET_CORLIB = 6,
438         CMD_APPDOMAIN_CREATE_BOXED_VALUE = 7
439 } CmdAppDomain;
440
441 typedef enum {
442         CMD_ASSEMBLY_GET_LOCATION = 1,
443         CMD_ASSEMBLY_GET_ENTRY_POINT = 2,
444         CMD_ASSEMBLY_GET_MANIFEST_MODULE = 3,
445         CMD_ASSEMBLY_GET_OBJECT = 4,
446         CMD_ASSEMBLY_GET_TYPE = 5,
447         CMD_ASSEMBLY_GET_NAME = 6
448 } CmdAssembly;
449
450 typedef enum {
451         CMD_MODULE_GET_INFO = 1,
452 } CmdModule;
453
454 typedef enum {
455         CMD_FIELD_GET_INFO = 1,
456 } CmdField;
457
458 typedef enum {
459         CMD_METHOD_GET_NAME = 1,
460         CMD_METHOD_GET_DECLARING_TYPE = 2,
461         CMD_METHOD_GET_DEBUG_INFO = 3,
462         CMD_METHOD_GET_PARAM_INFO = 4,
463         CMD_METHOD_GET_LOCALS_INFO = 5,
464         CMD_METHOD_GET_INFO = 6,
465         CMD_METHOD_GET_BODY = 7,
466         CMD_METHOD_RESOLVE_TOKEN = 8,
467         CMD_METHOD_GET_CATTRS = 9,
468         CMD_METHOD_MAKE_GENERIC_METHOD = 10
469 } CmdMethod;
470
471 typedef enum {
472         CMD_TYPE_GET_INFO = 1,
473         CMD_TYPE_GET_METHODS = 2,
474         CMD_TYPE_GET_FIELDS = 3,
475         CMD_TYPE_GET_VALUES = 4,
476         CMD_TYPE_GET_OBJECT = 5,
477         CMD_TYPE_GET_SOURCE_FILES = 6,
478         CMD_TYPE_SET_VALUES = 7,
479         CMD_TYPE_IS_ASSIGNABLE_FROM = 8,
480         CMD_TYPE_GET_PROPERTIES = 9,
481         CMD_TYPE_GET_CATTRS = 10,
482         CMD_TYPE_GET_FIELD_CATTRS = 11,
483         CMD_TYPE_GET_PROPERTY_CATTRS = 12,
484         CMD_TYPE_GET_SOURCE_FILES_2 = 13,
485         CMD_TYPE_GET_VALUES_2 = 14,
486         CMD_TYPE_GET_METHODS_BY_NAME_FLAGS = 15,
487         CMD_TYPE_GET_INTERFACES = 16,
488         CMD_TYPE_GET_INTERFACE_MAP = 17,
489         CMD_TYPE_IS_INITIALIZED = 18,
490         CMD_TYPE_CREATE_INSTANCE = 19
491 } CmdType;
492
493 typedef enum {
494         CMD_STACK_FRAME_GET_VALUES = 1,
495         CMD_STACK_FRAME_GET_THIS = 2,
496         CMD_STACK_FRAME_SET_VALUES = 3,
497         CMD_STACK_FRAME_GET_DOMAIN = 4,
498 } CmdStackFrame;
499
500 typedef enum {
501         CMD_ARRAY_REF_GET_LENGTH = 1,
502         CMD_ARRAY_REF_GET_VALUES = 2,
503         CMD_ARRAY_REF_SET_VALUES = 3,
504 } CmdArray;
505
506 typedef enum {
507         CMD_STRING_REF_GET_VALUE = 1,
508         CMD_STRING_REF_GET_LENGTH = 2,
509         CMD_STRING_REF_GET_CHARS = 3
510 } CmdString;
511
512 typedef enum {
513         CMD_OBJECT_REF_GET_TYPE = 1,
514         CMD_OBJECT_REF_GET_VALUES = 2,
515         CMD_OBJECT_REF_IS_COLLECTED = 3,
516         CMD_OBJECT_REF_GET_ADDRESS = 4,
517         CMD_OBJECT_REF_GET_DOMAIN = 5,
518         CMD_OBJECT_REF_SET_VALUES = 6,
519         CMD_OBJECT_REF_GET_INFO = 7,
520 } CmdObject;
521
522 typedef struct {
523         ModifierKind kind;
524         union {
525                 int count; /* For kind == MOD_KIND_COUNT */
526                 MonoInternalThread *thread; /* For kind == MOD_KIND_THREAD_ONLY */
527                 MonoClass *exc_class; /* For kind == MONO_KIND_EXCEPTION_ONLY */
528                 MonoAssembly **assemblies; /* For kind == MONO_KIND_ASSEMBLY_ONLY */
529                 GHashTable *source_files; /* For kind == MONO_KIND_SOURCE_FILE_ONLY */
530                 GHashTable *type_names; /* For kind == MONO_KIND_TYPE_NAME_ONLY */
531                 StepFilter filter; /* For kind == MOD_KIND_STEP */
532         } data;
533         gboolean caught, uncaught, subclasses; /* For kind == MOD_KIND_EXCEPTION_ONLY */
534 } Modifier;
535
536 typedef struct{
537         int id;
538         int event_kind;
539         int suspend_policy;
540         int nmodifiers;
541         gpointer info;
542         Modifier modifiers [MONO_ZERO_LEN_ARRAY];
543 } EventRequest;
544
545 /*
546  * Describes a single step request.
547  */
548 typedef struct {
549         EventRequest *req;
550         MonoInternalThread *thread;
551         StepDepth depth;
552         StepSize size;
553         StepFilter filter;
554         gpointer last_sp;
555         gpointer start_sp;
556         MonoMethod *start_method;
557         MonoMethod *last_method;
558         int last_line;
559         /* Whenever single stepping is performed using start/stop_single_stepping () */
560         gboolean global;
561         /* The list of breakpoints used to implement step-over */
562         GSList *bps;
563         /* The number of frames at the start of a step-over */
564         int nframes;
565 } SingleStepReq;
566
567 /*
568  * Contains additional information for an event
569  */
570 typedef struct {
571         /* For EVENT_KIND_EXCEPTION */
572         MonoObject *exc;
573         MonoContext catch_ctx;
574         gboolean caught;
575         /* For EVENT_KIND_USER_LOG */
576         int level;
577         char *category, *message;
578         /* For EVENT_KIND_TYPE_LOAD */
579         MonoClass *klass;
580 } EventInfo;
581
582 /* Dummy structure used for the profiler callbacks */
583 typedef struct {
584         void* dummy;
585 } DebuggerProfiler;
586
587 typedef struct {
588         guint8 *buf, *p, *end;
589 } Buffer;
590
591 typedef struct ReplyPacket {
592         int id;
593         int error;
594         Buffer *data;
595 } ReplyPacket;
596
597 #define DEBUG(level,s) do { if (G_UNLIKELY ((level) <= log_level)) { s; fflush (log_file); } } while (0)
598
599 #ifdef PLATFORM_ANDROID
600 #define DEBUG_PRINTF(level, ...) do { if (G_UNLIKELY ((level) <= log_level)) { g_print (__VA_ARGS__); } } while (0)
601 #else
602 #define DEBUG_PRINTF(level, ...) do { if (G_UNLIKELY ((level) <= log_level)) { fprintf (log_file, __VA_ARGS__); fflush (log_file); } } while (0)
603 #endif
604
605 #ifdef HOST_WIN32
606 #define get_last_sock_error() WSAGetLastError()
607 #define MONO_EWOULDBLOCK WSAEWOULDBLOCK
608 #define MONO_EINTR WSAEINTR
609 #else
610 #define get_last_sock_error() errno
611 #define MONO_EWOULDBLOCK EWOULDBLOCK
612 #define MONO_EINTR EINTR
613 #endif
614
615 #define CHECK_PROTOCOL_VERSION(major,minor) \
616         (protocol_version_set && (major_version > (major) || (major_version == (major) && minor_version >= (minor))))
617
618 /*
619  * Globals
620  */
621
622 static AgentConfig agent_config;
623
624 /* 
625  * Whenever the agent is fully initialized.
626  * When using the onuncaught or onthrow options, only some parts of the agent are
627  * initialized on startup, and the full initialization which includes connection
628  * establishment and the startup of the agent thread is only done in response to
629  * an event.
630  */
631 static gint32 inited;
632
633 #ifndef DISABLE_SOCKET_TRANSPORT
634 static int conn_fd;
635 static int listen_fd;
636 #endif
637
638 static int packet_id = 0;
639
640 static int objref_id = 0;
641
642 static int event_request_id = 0;
643
644 static int frame_id = 0;
645
646 static GPtrArray *event_requests;
647
648 static MonoNativeTlsKey debugger_tls_id;
649
650 static gboolean vm_start_event_sent, vm_death_event_sent, disconnected;
651
652 /* Maps MonoInternalThread -> DebuggerTlsData */
653 /* Protected by the loader lock */
654 static MonoGHashTable *thread_to_tls;
655
656 /* Maps tid -> MonoInternalThread */
657 /* Protected by the loader lock */
658 static MonoGHashTable *tid_to_thread;
659
660 /* Maps tid -> MonoThread (not MonoInternalThread) */
661 /* Protected by the loader lock */
662 static MonoGHashTable *tid_to_thread_obj;
663
664 static gsize debugger_thread_id;
665
666 static HANDLE debugger_thread_handle;
667
668 static int log_level;
669
670 static gboolean embedding;
671
672 static FILE *log_file;
673
674 /* Assemblies whose assembly load event has no been sent yet */
675 /* Protected by the dbg lock */
676 static GPtrArray *pending_assembly_loads;
677
678 /* Whenever the debugger thread has exited */
679 static gboolean debugger_thread_exited;
680
681 /* Cond variable used to wait for debugger_thread_exited becoming true */
682 static mono_cond_t debugger_thread_exited_cond;
683
684 /* Mutex for the cond var above */
685 static mono_mutex_t debugger_thread_exited_mutex;
686
687 static DebuggerProfiler debugger_profiler;
688
689 /* The single step request instance */
690 static SingleStepReq *ss_req;
691
692 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
693 /* Number of single stepping operations in progress */
694 static int ss_count;
695 #endif
696
697 /* The protocol version of the client */
698 static int major_version, minor_version;
699
700 /* Whenever the variables above are set by the client */
701 static gboolean protocol_version_set;
702
703 /* A hash table containing all active domains */
704 /* Protected by the loader lock */
705 static GHashTable *domains;
706
707 /* The number of times the runtime is suspended */
708 static gint32 suspend_count;
709
710 /* Whenever to buffer reply messages and send them together */
711 static gboolean buffer_replies;
712
713 /* Buffered reply packets */
714 static ReplyPacket reply_packets [128];
715 int nreply_packets;
716
717 #define dbg_lock() do { \
718         MONO_TRY_BLOCKING;                      \
719         mono_mutex_lock (&debug_mutex); \
720         MONO_FINISH_TRY_BLOCKING;               \
721 } while (0)
722
723 #define dbg_unlock() mono_mutex_unlock (&debug_mutex)
724 static mono_mutex_t debug_mutex;
725
726 static void transport_init (void);
727 static void transport_connect (const char *address);
728 static gboolean transport_handshake (void);
729 static void register_transport (DebuggerTransport *trans);
730
731 static guint32 WINAPI debugger_thread (void *arg);
732
733 static void runtime_initialized (MonoProfiler *prof);
734
735 static void runtime_shutdown (MonoProfiler *prof);
736
737 static void thread_startup (MonoProfiler *prof, uintptr_t tid);
738
739 static void thread_end (MonoProfiler *prof, uintptr_t tid);
740
741 static void appdomain_load (MonoProfiler *prof, MonoDomain *domain, int result);
742
743 static void appdomain_start_unload (MonoProfiler *prof, MonoDomain *domain);
744
745 static void appdomain_unload (MonoProfiler *prof, MonoDomain *domain);
746
747 static void emit_appdomain_load (gpointer key, gpointer value, gpointer user_data);
748
749 static void emit_thread_start (gpointer key, gpointer value, gpointer user_data);
750
751 static void invalidate_each_thread (gpointer key, gpointer value, gpointer user_data);
752
753 static void assembly_load (MonoProfiler *prof, MonoAssembly *assembly, int result);
754
755 static void assembly_unload (MonoProfiler *prof, MonoAssembly *assembly);
756
757 static void emit_assembly_load (gpointer assembly, gpointer user_data);
758
759 static void emit_type_load (gpointer key, gpointer type, gpointer user_data);
760
761 static void jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result);
762
763 static void add_pending_breakpoints (MonoMethod *method, MonoJitInfo *jinfo);
764
765 static void start_single_stepping (void);
766
767 static void stop_single_stepping (void);
768
769 static void suspend_current (void);
770
771 static void clear_event_requests_for_assembly (MonoAssembly *assembly);
772
773 static void clear_types_for_assembly (MonoAssembly *assembly);
774
775 static void clear_breakpoints_for_domain (MonoDomain *domain);
776
777 static void process_profiler_event (EventKind event, gpointer arg);
778
779 /* Submodule init/cleanup */
780 static void breakpoints_init (void);
781 static void breakpoints_cleanup (void);
782
783 static void objrefs_init (void);
784 static void objrefs_cleanup (void);
785
786 static void ids_init (void);
787 static void ids_cleanup (void);
788
789 static void suspend_init (void);
790
791 static void ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint *sp, MonoSeqPointInfo *info, MonoContext *ctx, DebuggerTlsData *tls, gboolean step_to_catch,
792                                           StackFrame **frames, int nframes);
793 static ErrorCode ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilter filter, EventRequest *req);
794 static void ss_destroy (SingleStepReq *req);
795
796 static void start_debugger_thread (void);
797 static void stop_debugger_thread (void);
798
799 static void finish_agent_init (gboolean on_startup);
800
801 static void process_profiler_event (EventKind event, gpointer arg);
802
803 static void invalidate_frames (DebuggerTlsData *tls);
804
805 #ifndef DISABLE_SOCKET_TRANSPORT
806 static void
807 register_socket_transport (void);
808 #endif
809
810 static inline gboolean
811 is_debugger_thread (void)
812 {
813         return GetCurrentThreadId () == debugger_thread_id;
814 }
815
816 static int
817 parse_address (char *address, char **host, int *port)
818 {
819         char *pos = strchr (address, ':');
820
821         if (pos == NULL || pos == address)
822                 return 1;
823
824         *host = g_malloc (pos - address + 1);
825         strncpy (*host, address, pos - address);
826         (*host) [pos - address] = '\0';
827
828         *port = atoi (pos + 1);
829
830         return 0;
831 }
832
833 static void
834 print_usage (void)
835 {
836         fprintf (stderr, "Usage: mono --debugger-agent=[<option>=<value>,...] ...\n");
837         fprintf (stderr, "Available options:\n");
838         fprintf (stderr, "  transport=<transport>\t\tTransport to use for connecting to the debugger (mandatory, possible values: 'dt_socket')\n");
839         fprintf (stderr, "  address=<hostname>:<port>\tAddress to connect to (mandatory)\n");
840         fprintf (stderr, "  loglevel=<n>\t\t\tLog level (defaults to 0)\n");
841         fprintf (stderr, "  logfile=<file>\t\tFile to log to (defaults to stdout)\n");
842         fprintf (stderr, "  suspend=y/n\t\t\tWhether to suspend after startup.\n");
843         fprintf (stderr, "  timeout=<n>\t\t\tTimeout for connecting in milliseconds.\n");
844         fprintf (stderr, "  server=y/n\t\t\tWhether to listen for a client connection.\n");
845         fprintf (stderr, "  keepalive=<n>\t\t\tSend keepalive events every n milliseconds.\n");
846         fprintf (stderr, "  setpgid=y/n\t\t\tWhether to call setpid(0, 0) after startup.\n");
847         fprintf (stderr, "  help\t\t\t\tPrint this help.\n");
848 }
849
850 static gboolean
851 parse_flag (const char *option, char *flag)
852 {
853         if (!strcmp (flag, "y"))
854                 return TRUE;
855         else if (!strcmp (flag, "n"))
856                 return FALSE;
857         else {
858                 fprintf (stderr, "debugger-agent: The valid values for the '%s' option are 'y' and 'n'.\n", option);
859                 exit (1);
860                 return FALSE;
861         }
862 }
863
864 void
865 mono_debugger_agent_parse_options (char *options)
866 {
867         char **args, **ptr;
868         char *host;
869         int port;
870         const char *extra;
871
872 #ifndef MONO_ARCH_SOFT_DEBUG_SUPPORTED
873         fprintf (stderr, "--debugger-agent is not supported on this platform.\n");
874         exit (1);
875 #endif
876
877         extra = g_getenv ("MONO_SDB_ENV_OPTIONS");
878         if (extra)
879                 options = g_strdup_printf ("%s,%s", options, extra);
880
881         agent_config.enabled = TRUE;
882         agent_config.suspend = TRUE;
883         agent_config.server = FALSE;
884         agent_config.defer = FALSE;
885         agent_config.address = NULL;
886
887         //agent_config.log_level = 10;
888
889         args = g_strsplit (options, ",", -1);
890         for (ptr = args; ptr && *ptr; ptr ++) {
891                 char *arg = *ptr;
892
893                 if (strncmp (arg, "transport=", 10) == 0) {
894                         agent_config.transport = g_strdup (arg + 10);
895                 } else if (strncmp (arg, "address=", 8) == 0) {
896                         agent_config.address = g_strdup (arg + 8);
897                 } else if (strncmp (arg, "loglevel=", 9) == 0) {
898                         agent_config.log_level = atoi (arg + 9);
899                 } else if (strncmp (arg, "logfile=", 8) == 0) {
900                         agent_config.log_file = g_strdup (arg + 8);
901                 } else if (strncmp (arg, "suspend=", 8) == 0) {
902                         agent_config.suspend = parse_flag ("suspend", arg + 8);
903                 } else if (strncmp (arg, "server=", 7) == 0) {
904                         agent_config.server = parse_flag ("server", arg + 7);
905                 } else if (strncmp (arg, "onuncaught=", 11) == 0) {
906                         agent_config.onuncaught = parse_flag ("onuncaught", arg + 11);
907                 } else if (strncmp (arg, "onthrow=", 8) == 0) {
908                         /* We support multiple onthrow= options */
909                         agent_config.onthrow = g_slist_append (agent_config.onthrow, g_strdup (arg + 8));
910                 } else if (strncmp (arg, "onthrow", 7) == 0) {
911                         agent_config.onthrow = g_slist_append (agent_config.onthrow, g_strdup (""));
912                 } else if (strncmp (arg, "help", 4) == 0) {
913                         print_usage ();
914                         exit (0);
915                 } else if (strncmp (arg, "timeout=", 8) == 0) {
916                         agent_config.timeout = atoi (arg + 8);
917                 } else if (strncmp (arg, "launch=", 7) == 0) {
918                         agent_config.launch = g_strdup (arg + 7);
919                 } else if (strncmp (arg, "embedding=", 10) == 0) {
920                         agent_config.embedding = atoi (arg + 10) == 1;
921                 } else if (strncmp (arg, "keepalive=", 10) == 0) {
922                         agent_config.keepalive = atoi (arg + 10);
923                 } else if (strncmp (arg, "setpgid=", 8) == 0) {
924                         agent_config.setpgid = parse_flag ("setpgid", arg + 8);
925                 } else {
926                         print_usage ();
927                         exit (1);
928                 }
929         }
930
931         if (agent_config.server && !agent_config.suspend) {
932                 /* Waiting for deferred attachment */
933                 agent_config.defer = TRUE;
934                 if (agent_config.address == NULL) {
935                         agent_config.address = g_strdup_printf ("0.0.0.0:%u", 56000 + (getpid () % 1000));
936                 }
937         }
938
939         //agent_config.log_level = 0;
940
941         if (agent_config.transport == NULL) {
942                 fprintf (stderr, "debugger-agent: The 'transport' option is mandatory.\n");
943                 exit (1);
944         }
945
946         if (agent_config.address == NULL && !agent_config.server) {
947                 fprintf (stderr, "debugger-agent: The 'address' option is mandatory.\n");
948                 exit (1);
949         }
950
951         // FIXME:
952         if (!strcmp (agent_config.transport, "dt_socket")) {
953                 if (agent_config.address && parse_address (agent_config.address, &host, &port)) {
954                         fprintf (stderr, "debugger-agent: The format of the 'address' options is '<host>:<port>'\n");
955                         exit (1);
956                 }
957         }
958 }
959
960 void
961 mono_debugger_agent_init (void)
962 {
963         mono_mutex_init_recursive (&debug_mutex);
964
965         if (!agent_config.enabled)
966                 return;
967
968         transport_init ();
969
970         /* Need to know whenever a thread has acquired the loader mutex */
971         mono_loader_lock_track_ownership (TRUE);
972
973         event_requests = g_ptr_array_new ();
974
975         mono_mutex_init (&debugger_thread_exited_mutex);
976         mono_cond_init (&debugger_thread_exited_cond, NULL);
977
978         mono_profiler_install ((MonoProfiler*)&debugger_profiler, runtime_shutdown);
979         mono_profiler_set_events (MONO_PROFILE_APPDOMAIN_EVENTS | MONO_PROFILE_THREADS | MONO_PROFILE_ASSEMBLY_EVENTS | MONO_PROFILE_JIT_COMPILATION | MONO_PROFILE_METHOD_EVENTS);
980         mono_profiler_install_runtime_initialized (runtime_initialized);
981         mono_profiler_install_appdomain (NULL, appdomain_load, appdomain_start_unload, appdomain_unload);
982         mono_profiler_install_thread (thread_startup, thread_end);
983         mono_profiler_install_assembly (NULL, assembly_load, assembly_unload, NULL);
984         mono_profiler_install_jit_end (jit_end);
985
986         mono_native_tls_alloc (&debugger_tls_id, NULL);
987
988         /* Needed by the hash_table_new_type () call below */
989         mono_gc_base_init ();
990
991         thread_to_tls = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
992         MONO_GC_REGISTER_ROOT_FIXED (thread_to_tls);
993
994         tid_to_thread = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
995         MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread);
996
997         tid_to_thread_obj = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
998         MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread_obj);
999
1000         pending_assembly_loads = g_ptr_array_new ();
1001         domains = g_hash_table_new (mono_aligned_addr_hash, NULL);
1002
1003         log_level = agent_config.log_level;
1004
1005         embedding = agent_config.embedding;
1006         disconnected = TRUE;
1007
1008         if (agent_config.log_file) {
1009                 log_file = fopen (agent_config.log_file, "w+");
1010                 if (!log_file) {
1011                         fprintf (stderr, "Unable to create log file '%s': %s.\n", agent_config.log_file, strerror (errno));
1012                         exit (1);
1013                 }
1014         } else {
1015                 log_file = stdout;
1016         }
1017
1018         ids_init ();
1019         objrefs_init ();
1020         breakpoints_init ();
1021         suspend_init ();
1022
1023         mini_get_debug_options ()->gen_sdb_seq_points = TRUE;
1024         /* 
1025          * This is needed because currently we don't handle liveness info.
1026          */
1027         mini_get_debug_options ()->mdb_optimizations = TRUE;
1028
1029 #ifndef MONO_ARCH_HAVE_CONTEXT_SET_INT_REG
1030         /* This is needed because we can't set local variables in registers yet */
1031         mono_disable_optimizations (MONO_OPT_LINEARS);
1032 #endif
1033
1034         /*
1035          * The stack walk done from thread_interrupt () needs to be signal safe, but it
1036          * isn't, since it can call into mono_aot_find_jit_info () which is not signal
1037          * safe (#3411). So load AOT info eagerly when the debugger is running as a
1038          * workaround.
1039          */
1040         mini_get_debug_options ()->load_aot_jit_info_eagerly = TRUE;
1041
1042 #ifdef HAVE_SETPGID
1043         if (agent_config.setpgid)
1044                 setpgid (0, 0);
1045 #endif
1046
1047         if (!agent_config.onuncaught && !agent_config.onthrow)
1048                 finish_agent_init (TRUE);
1049 }
1050
1051 /*
1052  * finish_agent_init:
1053  *
1054  *   Finish the initialization of the agent. This involves connecting the transport
1055  * and starting the agent thread. This is either done at startup, or
1056  * in response to some event like an unhandled exception.
1057  */
1058 static void
1059 finish_agent_init (gboolean on_startup)
1060 {
1061         int res;
1062
1063         if (InterlockedCompareExchange (&inited, 1, 0) == 1)
1064                 return;
1065
1066         if (agent_config.launch) {
1067                 char *argv [16];
1068
1069                 // FIXME: Generated address
1070                 // FIXME: Races with transport_connect ()
1071
1072                 argv [0] = agent_config.launch;
1073                 argv [1] = agent_config.transport;
1074                 argv [2] = agent_config.address;
1075                 argv [3] = NULL;
1076
1077                 res = g_spawn_async_with_pipes (NULL, argv, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1078                 if (!res) {
1079                         fprintf (stderr, "Failed to execute '%s'.\n", agent_config.launch);
1080                         exit (1);
1081                 }
1082         }
1083
1084         MONO_PREPARE_BLOCKING;
1085         transport_connect (agent_config.address);
1086         MONO_FINISH_BLOCKING;
1087
1088         if (!on_startup) {
1089                 /* Do some which is usually done after sending the VMStart () event */
1090                 vm_start_event_sent = TRUE;
1091                 start_debugger_thread ();
1092         }
1093 }
1094
1095 static void
1096 mono_debugger_agent_cleanup (void)
1097 {
1098         if (!inited)
1099                 return;
1100
1101         stop_debugger_thread ();
1102
1103         breakpoints_cleanup ();
1104         objrefs_cleanup ();
1105         ids_cleanup ();
1106         
1107         mono_mutex_destroy (&debugger_thread_exited_mutex);
1108         mono_cond_destroy (&debugger_thread_exited_cond);
1109 }
1110
1111 /*
1112  * SOCKET TRANSPORT
1113  */
1114
1115 #ifndef DISABLE_SOCKET_TRANSPORT
1116
1117 /*
1118  * recv_length:
1119  *
1120  * recv() + handle incomplete reads and EINTR
1121  */
1122 static int
1123 socket_transport_recv (void *buf, int len)
1124 {
1125         int res;
1126         int total = 0;
1127         int fd = conn_fd;
1128         int flags = 0;
1129         static gint32 last_keepalive;
1130         gint32 msecs;
1131
1132         do {
1133         again:
1134                 res = recv (fd, (char *) buf + total, len - total, flags);
1135                 if (res > 0)
1136                         total += res;
1137                 if (agent_config.keepalive) {
1138                         gboolean need_keepalive = FALSE;
1139                         if (res == -1 && get_last_sock_error () == MONO_EWOULDBLOCK) {
1140                                 need_keepalive = TRUE;
1141                         } else if (res == -1) {
1142                                 /* This could happen if recv () is interrupted repeatedly */
1143                                 msecs = mono_msec_ticks ();
1144                                 if (msecs - last_keepalive >= agent_config.keepalive) {
1145                                         need_keepalive = TRUE;
1146                                         last_keepalive = msecs;
1147                                 }
1148                         }
1149                         if (need_keepalive) {
1150                                 process_profiler_event (EVENT_KIND_KEEPALIVE, NULL);
1151                                 goto again;
1152                         }
1153                 }
1154         } while ((res > 0 && total < len) || (res == -1 && get_last_sock_error () == MONO_EINTR));
1155         return total;
1156 }
1157  
1158 static void
1159 set_keepalive (void)
1160 {
1161         struct timeval tv;
1162         int result;
1163
1164         if (!agent_config.keepalive || !conn_fd)
1165                 return;
1166
1167         tv.tv_sec = agent_config.keepalive / 1000;
1168         tv.tv_usec = (agent_config.keepalive % 1000) * 1000;
1169
1170         result = setsockopt (conn_fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof(struct timeval));
1171         g_assert (result >= 0);
1172 }
1173
1174 static int
1175 socket_transport_accept (int socket_fd)
1176 {
1177         conn_fd = accept (socket_fd, NULL, NULL);
1178         if (conn_fd == -1) {
1179                 fprintf (stderr, "debugger-agent: Unable to listen on %d\n", socket_fd);
1180         } else {
1181                 DEBUG_PRINTF (1, "Accepted connection from client, connection fd=%d.\n", conn_fd);
1182         }
1183         
1184         return conn_fd;
1185 }
1186
1187 static gboolean
1188 socket_transport_send (void *data, int len)
1189 {
1190         int res;
1191
1192         do {
1193                 res = send (conn_fd, data, len, 0);
1194         } while (res == -1 && get_last_sock_error () == MONO_EINTR);
1195         if (res != len)
1196                 return FALSE;
1197         else
1198                 return TRUE;
1199 }
1200
1201 /*
1202  * socket_transport_connect:
1203  *
1204  *   Connect/Listen on HOST:PORT. If HOST is NULL, generate an address and listen on it.
1205  */
1206 static void
1207 socket_transport_connect (const char *address)
1208 {
1209         MonoAddressInfo *result;
1210         MonoAddressEntry *rp;
1211         int sfd = -1, s, res;
1212         char *host;
1213         int port;
1214
1215         if (agent_config.address) {
1216                 res = parse_address (agent_config.address, &host, &port);
1217                 g_assert (res == 0);
1218         } else {
1219                 host = NULL;
1220                 port = 0;
1221         }
1222
1223         conn_fd = -1;
1224         listen_fd = -1;
1225
1226         if (host) {
1227
1228                 mono_network_init ();
1229
1230                 /* Obtain address(es) matching host/port */
1231                 s = mono_get_address_info (host, port, MONO_HINT_UNSPECIFIED, &result);
1232                 if (s != 0) {
1233                         fprintf (stderr, "debugger-agent: Unable to resolve %s:%d: %d\n", host, port, s); // FIXME add portable error conversion functions
1234                         exit (1);
1235                 }
1236         }
1237
1238         if (agent_config.server) {
1239                 /* Wait for a connection */
1240                 if (!host) {
1241                         struct sockaddr_in addr;
1242                         socklen_t addrlen;
1243
1244                         /* No address, generate one */
1245                         sfd = socket (AF_INET, SOCK_STREAM, 0);
1246                         g_assert (sfd);
1247
1248                         /* This will bind the socket to a random port */
1249                         res = listen (sfd, 16);
1250                         if (res == -1) {
1251                                 fprintf (stderr, "debugger-agent: Unable to setup listening socket: %s\n", strerror (get_last_sock_error ()));
1252                                 exit (1);
1253                         }
1254                         listen_fd = sfd;
1255
1256                         addrlen = sizeof (addr);
1257                         memset (&addr, 0, sizeof (addr));
1258                         res = getsockname (sfd, (struct sockaddr*)&addr, &addrlen);
1259                         g_assert (res == 0);
1260
1261                         host = (char*)"127.0.0.1";
1262                         port = ntohs (addr.sin_port);
1263
1264                         /* Emit the address to stdout */
1265                         /* FIXME: Should print another interface, not localhost */
1266                         printf ("%s:%d\n", host, port);
1267                 } else {
1268                         /* Listen on the provided address */
1269                         for (rp = result->entries; rp != NULL; rp = rp->next) {
1270                                 MonoSocketAddress sockaddr;
1271                                 socklen_t sock_len;
1272                                 int n = 1;
1273
1274                                 mono_socket_address_init (&sockaddr, &sock_len, rp->family, &rp->address, port);
1275
1276                                 sfd = socket (rp->family, rp->socktype,
1277                                                           rp->protocol);
1278                                 if (sfd == -1)
1279                                         continue;
1280
1281                                 if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
1282                                         continue;
1283
1284                                 res = bind (sfd, &sockaddr.addr, sock_len);
1285                                 if (res == -1)
1286                                         continue;
1287
1288                                 res = listen (sfd, 16);
1289                                 if (res == -1)
1290                                         continue;
1291                                 listen_fd = sfd;
1292                                 break;
1293                         }
1294
1295                         mono_free_address_info (result);
1296                 }
1297
1298                 if (agent_config.defer)
1299                         return;
1300
1301                 DEBUG_PRINTF (1, "Listening on %s:%d (timeout=%d ms)...\n", host, port, agent_config.timeout);
1302
1303                 if (agent_config.timeout) {
1304                         fd_set readfds;
1305                         struct timeval tv;
1306
1307                         tv.tv_sec = 0;
1308                         tv.tv_usec = agent_config.timeout * 1000;
1309                         FD_ZERO (&readfds);
1310                         FD_SET (sfd, &readfds);
1311                         res = select (sfd + 1, &readfds, NULL, NULL, &tv);
1312                         if (res == 0) {
1313                                 fprintf (stderr, "debugger-agent: Timed out waiting to connect.\n");
1314                                 exit (1);
1315                         }
1316                 }
1317
1318                 MONO_PREPARE_BLOCKING;
1319                 conn_fd = socket_transport_accept (sfd);
1320                 MONO_FINISH_BLOCKING;
1321                 if (conn_fd == -1)
1322                         exit (1);
1323
1324                 DEBUG_PRINTF (1, "Accepted connection from client, socket fd=%d.\n", conn_fd);
1325         } else {
1326                 /* Connect to the specified address */
1327                 /* FIXME: Respect the timeout */
1328                 for (rp = result->entries; rp != NULL; rp = rp->next) {
1329                         MonoSocketAddress sockaddr;
1330                         socklen_t sock_len;
1331
1332                         mono_socket_address_init (&sockaddr, &sock_len, rp->family, &rp->address, port);
1333
1334                         sfd = socket (rp->family, rp->socktype,
1335                                                   rp->protocol);
1336                         if (sfd == -1)
1337                                 continue;
1338
1339                         if (connect (sfd, &sockaddr.addr, sock_len) != -1)
1340                                 break;       /* Success */
1341                         
1342                         close (sfd);
1343                 }
1344
1345                 if (rp == 0) {
1346                         fprintf (stderr, "debugger-agent: Unable to connect to %s:%d\n", host, port);
1347                         exit (1);
1348                 }
1349
1350                 conn_fd = sfd;
1351
1352                 mono_free_address_info (result);
1353         }
1354         
1355         if (!transport_handshake ())
1356                 exit (1);
1357 }
1358
1359 static void
1360 socket_transport_close1 (void)
1361 {
1362         /* This will interrupt the agent thread */
1363         /* Close the read part only so it can still send back replies */
1364         /* Also shut down the connection listener so that we can exit normally */
1365 #ifdef HOST_WIN32
1366         /* SD_RECEIVE doesn't break the recv in the debugger thread */
1367         shutdown (conn_fd, SD_BOTH);
1368         shutdown (listen_fd, SD_BOTH);
1369         closesocket (listen_fd);
1370 #else
1371         shutdown (conn_fd, SHUT_RD);
1372         shutdown (listen_fd, SHUT_RDWR);
1373         close (listen_fd);
1374 #endif
1375 }
1376
1377 static void
1378 socket_transport_close2 (void)
1379 {
1380 #ifdef HOST_WIN32
1381         shutdown (conn_fd, SD_BOTH);
1382 #else
1383         shutdown (conn_fd, SHUT_RDWR);
1384 #endif
1385 }
1386
1387 static void
1388 register_socket_transport (void)
1389 {
1390         DebuggerTransport trans;
1391
1392         trans.name = "dt_socket";
1393         trans.connect = socket_transport_connect;
1394         trans.close1 = socket_transport_close1;
1395         trans.close2 = socket_transport_close2;
1396         trans.send = socket_transport_send;
1397         trans.recv = socket_transport_recv;
1398
1399         register_transport (&trans);
1400 }
1401
1402 /*
1403  * socket_fd_transport_connect:
1404  *
1405  */
1406 static void
1407 socket_fd_transport_connect (const char *address)
1408 {
1409         int res;
1410
1411         res = sscanf (address, "%d", &conn_fd);
1412         if (res != 1) {
1413                 fprintf (stderr, "debugger-agent: socket-fd transport address is invalid: '%s'\n", address);
1414                 exit (1);
1415         }
1416
1417         if (!transport_handshake ())
1418                 exit (1);
1419 }
1420
1421 static void
1422 register_socket_fd_transport (void)
1423 {
1424         DebuggerTransport trans;
1425
1426         /* This is the same as the 'dt_socket' transport, but receives an already connected socket fd */
1427         trans.name = "socket-fd";
1428         trans.connect = socket_fd_transport_connect;
1429         trans.close1 = socket_transport_close1;
1430         trans.close2 = socket_transport_close2;
1431         trans.send = socket_transport_send;
1432         trans.recv = socket_transport_recv;
1433
1434         register_transport (&trans);
1435 }
1436
1437 #endif /* DISABLE_SOCKET_TRANSPORT */
1438
1439 /*
1440  * TRANSPORT CODE
1441  */
1442
1443 #define MAX_TRANSPORTS 16
1444
1445 static DebuggerTransport *transport;
1446
1447 static DebuggerTransport transports [MAX_TRANSPORTS];
1448 static int ntransports;
1449
1450 MONO_API void
1451 mono_debugger_agent_register_transport (DebuggerTransport *trans);
1452
1453 void
1454 mono_debugger_agent_register_transport (DebuggerTransport *trans)
1455 {
1456         register_transport (trans);
1457 }
1458
1459 static void
1460 register_transport (DebuggerTransport *trans)
1461 {
1462         g_assert (ntransports < MAX_TRANSPORTS);
1463
1464         memcpy (&transports [ntransports], trans, sizeof (DebuggerTransport));
1465         ntransports ++;
1466 }
1467
1468 static void
1469 transport_init (void)
1470 {
1471         int i;
1472
1473 #ifndef DISABLE_SOCKET_TRANSPORT
1474         register_socket_transport ();
1475         register_socket_fd_transport ();
1476 #endif
1477
1478         for (i = 0; i < ntransports; ++i) {
1479                 if (!strcmp (agent_config.transport, transports [i].name))
1480                         break;
1481         }
1482         if (i == ntransports) {
1483                 fprintf (stderr, "debugger-agent: The supported values for the 'transport' option are: ");
1484                 for (i = 0; i < ntransports; ++i)
1485                         fprintf (stderr, "%s'%s'", i > 0 ? ", " : "", transports [i].name);
1486                 fprintf (stderr, "\n");
1487                 exit (1);
1488         }
1489         transport = &transports [i];
1490 }
1491
1492 void
1493 transport_connect (const char *address)
1494 {
1495         transport->connect (address);
1496 }
1497
1498 static void
1499 transport_close1 (void)
1500 {
1501         transport->close1 ();
1502 }
1503
1504 static void
1505 transport_close2 (void)
1506 {
1507         transport->close2 ();
1508 }
1509
1510 static int
1511 transport_send (void *buf, int len)
1512 {
1513         return transport->send (buf, len);
1514 }
1515
1516 static int
1517 transport_recv (void *buf, int len)
1518 {
1519         return transport->recv (buf, len);
1520 }
1521
1522 gboolean
1523 mono_debugger_agent_transport_handshake (void)
1524 {
1525         return transport_handshake ();
1526 }
1527
1528 static gboolean
1529 transport_handshake (void)
1530 {
1531         char handshake_msg [128];
1532         guint8 buf [128];
1533         int res;
1534         
1535         disconnected = TRUE;
1536         
1537         /* Write handshake message */
1538         sprintf (handshake_msg, "DWP-Handshake");
1539         /* Must use try blocking as this can nest into code that runs blocking */
1540         MONO_TRY_BLOCKING;
1541         do {
1542                 res = transport_send (handshake_msg, strlen (handshake_msg));
1543         } while (res == -1 && get_last_sock_error () == MONO_EINTR);
1544         MONO_FINISH_TRY_BLOCKING;
1545
1546         g_assert (res != -1);
1547
1548         /* Read answer */
1549         MONO_TRY_BLOCKING;
1550         res = transport_recv (buf, strlen (handshake_msg));
1551         MONO_FINISH_TRY_BLOCKING;
1552         if ((res != strlen (handshake_msg)) || (memcmp (buf, handshake_msg, strlen (handshake_msg)) != 0)) {
1553                 fprintf (stderr, "debugger-agent: DWP handshake failed.\n");
1554                 return FALSE;
1555         }
1556
1557         /*
1558          * To support older clients, the client sends its protocol version after connecting
1559          * using a command. Until that is received, default to our protocol version.
1560          */
1561         major_version = MAJOR_VERSION;
1562         minor_version = MINOR_VERSION;
1563         protocol_version_set = FALSE;
1564
1565 #ifndef DISABLE_SOCKET_TRANSPORT
1566         // FIXME: Move this somewhere else
1567         /* 
1568          * Set TCP_NODELAY on the socket so the client receives events/command
1569          * results immediately.
1570          */
1571         if (conn_fd) {
1572                 int flag = 1;
1573                 int result = setsockopt (conn_fd,
1574                                  IPPROTO_TCP,
1575                                  TCP_NODELAY,
1576                                  (char *) &flag,
1577                                  sizeof(int));
1578                 g_assert (result >= 0);
1579         }
1580
1581         set_keepalive ();
1582 #endif
1583         
1584         disconnected = FALSE;
1585         return TRUE;
1586 }
1587
1588 static void
1589 stop_debugger_thread (void)
1590 {
1591         if (!inited)
1592                 return;
1593
1594         MONO_PREPARE_BLOCKING;
1595         transport_close1 ();
1596         MONO_FINISH_BLOCKING;
1597
1598         /* 
1599          * Wait for the thread to exit.
1600          *
1601          * If we continue with the shutdown without waiting for it, then the client might
1602          * not receive an answer to its last command like a resume.
1603          */
1604         if (GetCurrentThreadId () != debugger_thread_id) {
1605                 do {
1606                         MONO_TRY_BLOCKING;
1607                         mono_mutex_lock (&debugger_thread_exited_mutex);
1608                         if (!debugger_thread_exited)
1609                                 mono_cond_wait (&debugger_thread_exited_cond, &debugger_thread_exited_mutex);
1610                         mono_mutex_unlock (&debugger_thread_exited_mutex);
1611                         MONO_FINISH_TRY_BLOCKING;
1612                 } while (!debugger_thread_exited);
1613         }
1614
1615         MONO_PREPARE_BLOCKING;
1616         transport_close2 ();
1617         MONO_FINISH_BLOCKING;
1618 }
1619
1620 static void
1621 start_debugger_thread (void)
1622 {
1623         debugger_thread_handle = mono_threads_create_thread (debugger_thread, NULL, 0, 0, NULL);
1624         g_assert (debugger_thread_handle);
1625 }
1626
1627 /*
1628  * Functions to decode protocol data
1629  */
1630
1631 static inline int
1632 decode_byte (guint8 *buf, guint8 **endbuf, guint8 *limit)
1633 {
1634         *endbuf = buf + 1;
1635         g_assert (*endbuf <= limit);
1636         return buf [0];
1637 }
1638
1639 static inline int
1640 decode_int (guint8 *buf, guint8 **endbuf, guint8 *limit)
1641 {
1642         *endbuf = buf + 4;
1643         g_assert (*endbuf <= limit);
1644
1645         return (((int)buf [0]) << 24) | (((int)buf [1]) << 16) | (((int)buf [2]) << 8) | (((int)buf [3]) << 0);
1646 }
1647
1648 static inline gint64
1649 decode_long (guint8 *buf, guint8 **endbuf, guint8 *limit)
1650 {
1651         guint32 high = decode_int (buf, &buf, limit);
1652         guint32 low = decode_int (buf, &buf, limit);
1653
1654         *endbuf = buf;
1655
1656         return ((((guint64)high) << 32) | ((guint64)low));
1657 }
1658
1659 static inline int
1660 decode_id (guint8 *buf, guint8 **endbuf, guint8 *limit)
1661 {
1662         return decode_int (buf, endbuf, limit);
1663 }
1664
1665 static inline char*
1666 decode_string (guint8 *buf, guint8 **endbuf, guint8 *limit)
1667 {
1668         int len = decode_int (buf, &buf, limit);
1669         char *s;
1670
1671         if (len < 0) {
1672                 *endbuf = buf;
1673                 return NULL;
1674         }
1675
1676         s = g_malloc (len + 1);
1677         g_assert (s);
1678
1679         memcpy (s, buf, len);
1680         s [len] = '\0';
1681         buf += len;
1682         *endbuf = buf;
1683
1684         return s;
1685 }
1686
1687 /*
1688  * Functions to encode protocol data
1689  */
1690
1691 static inline void
1692 buffer_init (Buffer *buf, int size)
1693 {
1694         buf->buf = g_malloc (size);
1695         buf->p = buf->buf;
1696         buf->end = buf->buf + size;
1697 }
1698
1699 static inline int
1700 buffer_len (Buffer *buf)
1701 {
1702         return buf->p - buf->buf;
1703 }
1704
1705 static inline void
1706 buffer_make_room (Buffer *buf, int size)
1707 {
1708         if (buf->end - buf->p < size) {
1709                 int new_size = buf->end - buf->buf + size + 32;
1710                 guint8 *p = g_realloc (buf->buf, new_size);
1711                 size = buf->p - buf->buf;
1712                 buf->buf = p;
1713                 buf->p = p + size;
1714                 buf->end = buf->buf + new_size;
1715         }
1716 }
1717
1718 static inline void
1719 buffer_add_byte (Buffer *buf, guint8 val)
1720 {
1721         buffer_make_room (buf, 1);
1722         buf->p [0] = val;
1723         buf->p++;
1724 }
1725
1726 static inline void
1727 buffer_add_short (Buffer *buf, guint32 val)
1728 {
1729         buffer_make_room (buf, 2);
1730         buf->p [0] = (val >> 8) & 0xff;
1731         buf->p [1] = (val >> 0) & 0xff;
1732         buf->p += 2;
1733 }
1734
1735 static inline void
1736 buffer_add_int (Buffer *buf, guint32 val)
1737 {
1738         buffer_make_room (buf, 4);
1739         buf->p [0] = (val >> 24) & 0xff;
1740         buf->p [1] = (val >> 16) & 0xff;
1741         buf->p [2] = (val >> 8) & 0xff;
1742         buf->p [3] = (val >> 0) & 0xff;
1743         buf->p += 4;
1744 }
1745
1746 static inline void
1747 buffer_add_long (Buffer *buf, guint64 l)
1748 {
1749         buffer_add_int (buf, (l >> 32) & 0xffffffff);
1750         buffer_add_int (buf, (l >> 0) & 0xffffffff);
1751 }
1752
1753 static inline void
1754 buffer_add_id (Buffer *buf, int id)
1755 {
1756         buffer_add_int (buf, (guint64)id);
1757 }
1758
1759 static inline void
1760 buffer_add_data (Buffer *buf, guint8 *data, int len)
1761 {
1762         buffer_make_room (buf, len);
1763         memcpy (buf->p, data, len);
1764         buf->p += len;
1765 }
1766
1767 static inline void
1768 buffer_add_string (Buffer *buf, const char *str)
1769 {
1770         int len;
1771
1772         if (str == NULL) {
1773                 buffer_add_int (buf, 0);
1774         } else {
1775                 len = strlen (str);
1776                 buffer_add_int (buf, len);
1777                 buffer_add_data (buf, (guint8*)str, len);
1778         }
1779 }
1780
1781 static inline void
1782 buffer_add_buffer (Buffer *buf, Buffer *data)
1783 {
1784         buffer_add_data (buf, data->buf, buffer_len (data));
1785 }
1786
1787 static inline void
1788 buffer_free (Buffer *buf)
1789 {
1790         g_free (buf->buf);
1791 }
1792
1793 static gboolean
1794 send_packet (int command_set, int command, Buffer *data)
1795 {
1796         Buffer buf;
1797         int len, id;
1798         gboolean res;
1799
1800         id = InterlockedIncrement (&packet_id);
1801
1802         len = data->p - data->buf + 11;
1803         buffer_init (&buf, len);
1804         buffer_add_int (&buf, len);
1805         buffer_add_int (&buf, id);
1806         buffer_add_byte (&buf, 0); /* flags */
1807         buffer_add_byte (&buf, command_set);
1808         buffer_add_byte (&buf, command);
1809         memcpy (buf.buf + 11, data->buf, data->p - data->buf);
1810
1811         MONO_PREPARE_BLOCKING;
1812         res = transport_send (buf.buf, len);
1813         MONO_FINISH_BLOCKING;
1814
1815         buffer_free (&buf);
1816
1817         return res;
1818 }
1819
1820 static gboolean
1821 send_reply_packets (int npackets, ReplyPacket *packets)
1822 {
1823         Buffer buf;
1824         int i, len;
1825         gboolean res;
1826
1827         len = 0;
1828         for (i = 0; i < npackets; ++i)
1829                 len += buffer_len (packets [i].data) + 11;
1830         buffer_init (&buf, len);
1831         for (i = 0; i < npackets; ++i) {
1832                 buffer_add_int (&buf, buffer_len (packets [i].data) + 11);
1833                 buffer_add_int (&buf, packets [i].id);
1834                 buffer_add_byte (&buf, 0x80); /* flags */
1835                 buffer_add_byte (&buf, (packets [i].error >> 8) & 0xff);
1836                 buffer_add_byte (&buf, packets [i].error);
1837                 buffer_add_buffer (&buf, packets [i].data);
1838         }
1839
1840         MONO_PREPARE_BLOCKING;
1841         res = transport_send (buf.buf, len);
1842         MONO_FINISH_BLOCKING;
1843
1844         buffer_free (&buf);
1845
1846         return res;
1847 }
1848
1849 static gboolean
1850 send_reply_packet (int id, int error, Buffer *data)
1851 {
1852         ReplyPacket packet;
1853
1854         memset (&packet, 0, sizeof (ReplyPacket));
1855         packet.id = id;
1856         packet.error = error;
1857         packet.data = data;
1858
1859         return send_reply_packets (1, &packet);
1860 }
1861
1862 static void
1863 send_buffered_reply_packets (void)
1864 {
1865         int i;
1866
1867         send_reply_packets (nreply_packets, reply_packets);
1868         for (i = 0; i < nreply_packets; ++i)
1869                 buffer_free (reply_packets [i].data);
1870         DEBUG_PRINTF (1, "[dbg] Sent %d buffered reply packets [at=%lx].\n", nreply_packets, (long)mono_100ns_ticks () / 10000);
1871         nreply_packets = 0;
1872 }
1873
1874 static void
1875 buffer_reply_packet (int id, int error, Buffer *data)
1876 {
1877         ReplyPacket *p;
1878
1879         if (nreply_packets == 128)
1880                 send_buffered_reply_packets ();
1881
1882         p = &reply_packets [nreply_packets];
1883         p->id = id;
1884         p->error = error;
1885         p->data = g_new0 (Buffer, 1);
1886         buffer_init (p->data, buffer_len (data));
1887         buffer_add_buffer (p->data, data);
1888         nreply_packets ++;
1889 }
1890
1891 /*
1892  * OBJECT IDS
1893  */
1894
1895 /*
1896  * Represents an object accessible by the debugger client.
1897  */
1898 typedef struct {
1899         /* Unique id used in the wire protocol to refer to objects */
1900         int id;
1901         /*
1902          * A weakref gc handle pointing to the object. The gc handle is used to 
1903          * detect if the object was garbage collected.
1904          */
1905         guint32 handle;
1906 } ObjRef;
1907
1908 /* Maps objid -> ObjRef */
1909 /* Protected by the loader lock */
1910 static GHashTable *objrefs;
1911 /* Protected by the loader lock */
1912 static GHashTable *obj_to_objref;
1913 /* Protected by the dbg lock */
1914 static MonoGHashTable *suspended_objs;
1915
1916 static void
1917 free_objref (gpointer value)
1918 {
1919         ObjRef *o = value;
1920
1921         mono_gchandle_free (o->handle);
1922
1923         g_free (o);
1924 }
1925
1926 static void
1927 objrefs_init (void)
1928 {
1929         objrefs = g_hash_table_new_full (NULL, NULL, NULL, free_objref);
1930         obj_to_objref = g_hash_table_new (NULL, NULL);
1931         suspended_objs = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
1932         MONO_GC_REGISTER_ROOT_FIXED (suspended_objs);
1933 }
1934
1935 static void
1936 objrefs_cleanup (void)
1937 {
1938         g_hash_table_destroy (objrefs);
1939         objrefs = NULL;
1940 }
1941
1942 /*
1943  * Return an ObjRef for OBJ.
1944  */
1945 static ObjRef*
1946 get_objref (MonoObject *obj)
1947 {
1948         ObjRef *ref;
1949         GSList *reflist = NULL, *l;
1950         int hash = 0;
1951
1952         if (obj == NULL)
1953                 return 0;
1954
1955         if (suspend_count) {
1956                 /*
1957                  * Have to keep object refs created during suspensions alive for the duration of the suspension, so GCs during invokes don't collect them.
1958                  */
1959                 dbg_lock ();
1960                 mono_g_hash_table_insert (suspended_objs, obj, NULL);
1961                 dbg_unlock ();
1962         }
1963
1964         mono_loader_lock ();
1965         
1966         /* FIXME: The tables can grow indefinitely */
1967
1968         if (mono_gc_is_moving ()) {
1969                 /*
1970                  * Objects can move, so use a hash table mapping hash codes to lists of
1971                  * ObjRef structures.
1972                  */
1973                 hash = mono_object_hash (obj);
1974
1975                 reflist = g_hash_table_lookup (obj_to_objref, GINT_TO_POINTER (hash));
1976                 for (l = reflist; l; l = l->next) {
1977                         ref = l->data;
1978                         if (ref && mono_gchandle_get_target (ref->handle) == obj) {
1979                                 mono_loader_unlock ();
1980                                 return ref;
1981                         }
1982                 }
1983         } else {
1984                 /* Use a hash table with masked pointers to internalize object references */
1985                 ref = g_hash_table_lookup (obj_to_objref, GINT_TO_POINTER (~((gsize)obj)));
1986                 /* ref might refer to a different object with the same addr which was GCd */
1987                 if (ref && mono_gchandle_get_target (ref->handle) == obj) {
1988                         mono_loader_unlock ();
1989                         return ref;
1990                 }
1991         }
1992
1993         ref = g_new0 (ObjRef, 1);
1994         ref->id = InterlockedIncrement (&objref_id);
1995         ref->handle = mono_gchandle_new_weakref (obj, FALSE);
1996
1997         g_hash_table_insert (objrefs, GINT_TO_POINTER (ref->id), ref);
1998
1999         if (mono_gc_is_moving ()) {
2000                 reflist = g_slist_append (reflist, ref);
2001                 g_hash_table_insert (obj_to_objref, GINT_TO_POINTER (hash), reflist);
2002         } else {
2003                 g_hash_table_insert (obj_to_objref, GINT_TO_POINTER (~((gsize)obj)), ref);
2004         }
2005
2006         mono_loader_unlock ();
2007
2008         return ref;
2009 }
2010
2011 static gboolean
2012 true_pred (gpointer key, gpointer value, gpointer user_data)
2013 {
2014         return TRUE;
2015 }
2016
2017 static void
2018 clear_suspended_objs (void)
2019 {
2020         dbg_lock ();
2021         mono_g_hash_table_foreach_remove (suspended_objs, true_pred, NULL);
2022         dbg_unlock ();
2023 }
2024
2025 static inline int
2026 get_objid (MonoObject *obj)
2027 {
2028         return get_objref (obj)->id;
2029 }
2030
2031 /*
2032  * Set OBJ to the object identified by OBJID.
2033  * Returns 0 or an error code if OBJID is invalid or the object has been garbage
2034  * collected.
2035  */
2036 static ErrorCode
2037 get_object_allow_null (int objid, MonoObject **obj)
2038 {
2039         ObjRef *ref;
2040
2041         if (objid == 0) {
2042                 *obj = NULL;
2043                 return 0;
2044         }
2045
2046         if (!objrefs)
2047                 return ERR_INVALID_OBJECT;
2048
2049         mono_loader_lock ();
2050
2051         ref = g_hash_table_lookup (objrefs, GINT_TO_POINTER (objid));
2052
2053         if (ref) {
2054                 *obj = mono_gchandle_get_target (ref->handle);
2055                 mono_loader_unlock ();
2056                 if (!(*obj))
2057                         return ERR_INVALID_OBJECT;
2058                 return 0;
2059         } else {
2060                 mono_loader_unlock ();
2061                 return ERR_INVALID_OBJECT;
2062         }
2063 }
2064
2065 static ErrorCode
2066 get_object (int objid, MonoObject **obj)
2067 {
2068         int err = get_object_allow_null (objid, obj);
2069
2070         if (err)
2071                 return err;
2072         if (!(*obj))
2073                 return ERR_INVALID_OBJECT;
2074         return 0;
2075 }
2076
2077 static inline int
2078 decode_objid (guint8 *buf, guint8 **endbuf, guint8 *limit)
2079 {
2080         return decode_id (buf, endbuf, limit);
2081 }
2082
2083 static inline void
2084 buffer_add_objid (Buffer *buf, MonoObject *o)
2085 {
2086         buffer_add_id (buf, get_objid (o));
2087 }
2088
2089 /*
2090  * IDS
2091  */
2092
2093 typedef enum {
2094         ID_ASSEMBLY = 0,
2095         ID_MODULE = 1,
2096         ID_TYPE = 2,
2097         ID_METHOD = 3,
2098         ID_FIELD = 4,
2099         ID_DOMAIN = 5,
2100         ID_PROPERTY = 6,
2101         ID_NUM
2102 } IdType;
2103
2104 /*
2105  * Represents a runtime structure accessible to the debugger client
2106  */
2107 typedef struct {
2108         /* Unique id used in the wire protocol */
2109         int id;
2110         /* Domain of the runtime structure, NULL if the domain was unloaded */
2111         MonoDomain *domain;
2112         union {
2113                 gpointer val;
2114                 MonoClass *klass;
2115                 MonoMethod *method;
2116                 MonoImage *image;
2117                 MonoAssembly *assembly;
2118                 MonoClassField *field;
2119                 MonoDomain *domain;
2120                 MonoProperty *property;
2121         } data;
2122 } Id;
2123
2124 typedef struct {
2125         /* Maps runtime structure -> Id */
2126         /* Protected by the dbg lock */
2127         GHashTable *val_to_id [ID_NUM];
2128         /* Classes whose class load event has been sent */
2129         /* Protected by the loader lock */
2130         GHashTable *loaded_classes;
2131         /* Maps MonoClass->GPtrArray of file names */
2132         GHashTable *source_files;
2133         /* Maps source file basename -> GSList of classes */
2134         GHashTable *source_file_to_class;
2135         /* Same with ignore-case */
2136         GHashTable *source_file_to_class_ignorecase;
2137 } AgentDomainInfo;
2138
2139 /* Maps id -> Id */
2140 /* Protected by the dbg lock */
2141 static GPtrArray *ids [ID_NUM];
2142
2143 static void
2144 ids_init (void)
2145 {
2146         int i;
2147
2148         for (i = 0; i < ID_NUM; ++i)
2149                 ids [i] = g_ptr_array_new ();
2150 }
2151
2152 static void
2153 ids_cleanup (void)
2154 {
2155         int i, j;
2156
2157         for (i = 0; i < ID_NUM; ++i) {
2158                 if (ids [i]) {
2159                         for (j = 0; j < ids [i]->len; ++j)
2160                                 g_free (g_ptr_array_index (ids [i], j));
2161                         g_ptr_array_free (ids [i], TRUE);
2162                 }
2163                 ids [i] = NULL;
2164         }
2165 }
2166
2167 void
2168 mono_debugger_agent_free_domain_info (MonoDomain *domain)
2169 {
2170         AgentDomainInfo *info = domain_jit_info (domain)->agent_info;
2171         int i, j;
2172         GHashTableIter iter;
2173         GPtrArray *file_names;
2174         char *basename;
2175         GSList *l;
2176
2177         if (info) {
2178                 for (i = 0; i < ID_NUM; ++i)
2179                         if (info->val_to_id [i])
2180                                 g_hash_table_destroy (info->val_to_id [i]);
2181                 g_hash_table_destroy (info->loaded_classes);
2182
2183                 g_hash_table_iter_init (&iter, info->source_files);
2184                 while (g_hash_table_iter_next (&iter, NULL, (void**)&file_names)) {
2185                         for (i = 0; i < file_names->len; ++i)
2186                                 g_free (g_ptr_array_index (file_names, i));
2187                         g_ptr_array_free (file_names, TRUE);
2188                 }
2189
2190                 g_hash_table_iter_init (&iter, info->source_file_to_class);
2191                 while (g_hash_table_iter_next (&iter, (void**)&basename, (void**)&l)) {
2192                         g_free (basename);
2193                         g_slist_free (l);
2194                 }
2195
2196                 g_hash_table_iter_init (&iter, info->source_file_to_class_ignorecase);
2197                 while (g_hash_table_iter_next (&iter, (void**)&basename, (void**)&l)) {
2198                         g_free (basename);
2199                         g_slist_free (l);
2200                 }
2201
2202                 g_free (info);
2203         }
2204
2205         domain_jit_info (domain)->agent_info = NULL;
2206
2207         /* Clear ids referencing structures in the domain */
2208         dbg_lock ();
2209         for (i = 0; i < ID_NUM; ++i) {
2210                 if (ids [i]) {
2211                         for (j = 0; j < ids [i]->len; ++j) {
2212                                 Id *id = g_ptr_array_index (ids [i], j);
2213                                 if (id->domain == domain)
2214                                         id->domain = NULL;
2215                         }
2216                 }
2217         }
2218         dbg_unlock ();
2219
2220         mono_loader_lock ();
2221         g_hash_table_remove (domains, domain);
2222         mono_loader_unlock ();
2223 }
2224
2225 static AgentDomainInfo*
2226 get_agent_domain_info (MonoDomain *domain)
2227 {
2228         AgentDomainInfo *info = NULL;
2229
2230         mono_domain_lock (domain);
2231
2232         info = domain_jit_info (domain)->agent_info;
2233         if (!info) {
2234                 info = domain_jit_info (domain)->agent_info = g_new0 (AgentDomainInfo, 1);
2235                 info->loaded_classes = g_hash_table_new (mono_aligned_addr_hash, NULL);
2236                 info->source_files = g_hash_table_new (mono_aligned_addr_hash, NULL);
2237                 info->source_file_to_class = g_hash_table_new (g_str_hash, g_str_equal);
2238                 info->source_file_to_class_ignorecase = g_hash_table_new (g_str_hash, g_str_equal);
2239         }
2240
2241         mono_domain_unlock (domain);
2242
2243         return info;
2244 }
2245
2246 static int
2247 get_id (MonoDomain *domain, IdType type, gpointer val)
2248 {
2249         Id *id;
2250         AgentDomainInfo *info;
2251
2252         if (val == NULL)
2253                 return 0;
2254
2255         info = get_agent_domain_info (domain);
2256
2257         dbg_lock ();
2258
2259         if (info->val_to_id [type] == NULL)
2260                 info->val_to_id [type] = g_hash_table_new (mono_aligned_addr_hash, NULL);
2261
2262         id = g_hash_table_lookup (info->val_to_id [type], val);
2263         if (id) {
2264                 dbg_unlock ();
2265                 return id->id;
2266         }
2267
2268         id = g_new0 (Id, 1);
2269         /* Reserve id 0 */
2270         id->id = ids [type]->len + 1;
2271         id->domain = domain;
2272         id->data.val = val;
2273
2274         g_hash_table_insert (info->val_to_id [type], val, id);
2275         g_ptr_array_add (ids [type], id);
2276
2277         dbg_unlock ();
2278
2279         return id->id;
2280 }
2281
2282 static inline gpointer
2283 decode_ptr_id (guint8 *buf, guint8 **endbuf, guint8 *limit, IdType type, MonoDomain **domain, int *err)
2284 {
2285         Id *res;
2286
2287         int id = decode_id (buf, endbuf, limit);
2288
2289         *err = 0;
2290         if (domain)
2291                 *domain = NULL;
2292
2293         if (id == 0)
2294                 return NULL;
2295
2296         // FIXME: error handling
2297         dbg_lock ();
2298         g_assert (id > 0 && id <= ids [type]->len);
2299
2300         res = g_ptr_array_index (ids [type], GPOINTER_TO_INT (id - 1));
2301         dbg_unlock ();
2302
2303         if (res->domain == NULL) {
2304                 DEBUG_PRINTF (1, "ERR_UNLOADED, id=%d, type=%d.\n", id, type);
2305                 *err = ERR_UNLOADED;
2306                 return NULL;
2307         }
2308
2309         if (domain)
2310                 *domain = res->domain;
2311
2312         return res->data.val;
2313 }
2314
2315 static inline int
2316 buffer_add_ptr_id (Buffer *buf, MonoDomain *domain, IdType type, gpointer val)
2317 {
2318         int id = get_id (domain, type, val);
2319
2320         buffer_add_id (buf, id);
2321         return id;
2322 }
2323
2324 static inline MonoClass*
2325 decode_typeid (guint8 *buf, guint8 **endbuf, guint8 *limit, MonoDomain **domain, int *err)
2326 {
2327         MonoClass *klass;
2328
2329         klass = decode_ptr_id (buf, endbuf, limit, ID_TYPE, domain, err);
2330         if (G_UNLIKELY (log_level >= 2) && klass) {
2331                 char *s;
2332
2333                 s = mono_type_full_name (&klass->byval_arg);
2334                 DEBUG_PRINTF (2, "[dbg]   recv class [%s]\n", s);
2335                 g_free (s);
2336         }
2337         return klass;
2338 }
2339
2340 static inline MonoAssembly*
2341 decode_assemblyid (guint8 *buf, guint8 **endbuf, guint8 *limit, MonoDomain **domain, int *err)
2342 {
2343         return decode_ptr_id (buf, endbuf, limit, ID_ASSEMBLY, domain, err);
2344 }
2345
2346 static inline MonoImage*
2347 decode_moduleid (guint8 *buf, guint8 **endbuf, guint8 *limit, MonoDomain **domain, int *err)
2348 {
2349         return decode_ptr_id (buf, endbuf, limit, ID_MODULE, domain, err);
2350 }
2351
2352 static inline MonoMethod*
2353 decode_methodid (guint8 *buf, guint8 **endbuf, guint8 *limit, MonoDomain **domain, int *err)
2354 {
2355         MonoMethod *m;
2356
2357         m = decode_ptr_id (buf, endbuf, limit, ID_METHOD, domain, err);
2358         if (G_UNLIKELY (log_level >= 2) && m) {
2359                 char *s;
2360
2361                 s = mono_method_full_name (m, TRUE);
2362                 DEBUG_PRINTF (2, "[dbg]   recv method [%s]\n", s);
2363                 g_free (s);
2364         }
2365         return m;
2366 }
2367
2368 static inline MonoClassField*
2369 decode_fieldid (guint8 *buf, guint8 **endbuf, guint8 *limit, MonoDomain **domain, int *err)
2370 {
2371         return decode_ptr_id (buf, endbuf, limit, ID_FIELD, domain, err);
2372 }
2373
2374 static inline MonoDomain*
2375 decode_domainid (guint8 *buf, guint8 **endbuf, guint8 *limit, MonoDomain **domain, int *err)
2376 {
2377         return decode_ptr_id (buf, endbuf, limit, ID_DOMAIN, domain, err);
2378 }
2379
2380 static inline MonoProperty*
2381 decode_propertyid (guint8 *buf, guint8 **endbuf, guint8 *limit, MonoDomain **domain, int *err)
2382 {
2383         return decode_ptr_id (buf, endbuf, limit, ID_PROPERTY, domain, err);
2384 }
2385
2386 static inline void
2387 buffer_add_typeid (Buffer *buf, MonoDomain *domain, MonoClass *klass)
2388 {
2389         buffer_add_ptr_id (buf, domain, ID_TYPE, klass);
2390         if (G_UNLIKELY (log_level >= 2) && klass) {
2391                 char *s;
2392
2393                 s = mono_type_full_name (&klass->byval_arg);
2394                 if (GetCurrentThreadId () == debugger_thread_id)
2395                         DEBUG_PRINTF (2, "[dbg]   send class [%s]\n", s);
2396                 else
2397                         DEBUG_PRINTF (2, "[%p]   send class [%s]\n", (gpointer)GetCurrentThreadId (), s);
2398                 g_free (s);
2399         }
2400 }
2401
2402 static inline void
2403 buffer_add_methodid (Buffer *buf, MonoDomain *domain, MonoMethod *method)
2404 {
2405         buffer_add_ptr_id (buf, domain, ID_METHOD, method);
2406         if (G_UNLIKELY (log_level >= 2) && method) {
2407                 char *s;
2408
2409                 s = mono_method_full_name (method, 1);
2410                 DEBUG_PRINTF (2, "[dbg]   send method [%s]\n", s);
2411                 g_free (s);
2412         }
2413 }
2414
2415 static inline void
2416 buffer_add_assemblyid (Buffer *buf, MonoDomain *domain, MonoAssembly *assembly)
2417 {
2418         int id;
2419
2420         id = buffer_add_ptr_id (buf, domain, ID_ASSEMBLY, assembly);
2421         if (G_UNLIKELY (log_level >= 2) && assembly)
2422                 DEBUG_PRINTF (2, "[dbg]   send assembly [%s][%s][%d]\n", assembly->aname.name, domain->friendly_name, id);
2423 }
2424
2425 static inline void
2426 buffer_add_moduleid (Buffer *buf, MonoDomain *domain, MonoImage *image)
2427 {
2428         buffer_add_ptr_id (buf, domain, ID_MODULE, image);
2429 }
2430
2431 static inline void
2432 buffer_add_fieldid (Buffer *buf, MonoDomain *domain, MonoClassField *field)
2433 {
2434         buffer_add_ptr_id (buf, domain, ID_FIELD, field);
2435 }
2436
2437 static inline void
2438 buffer_add_propertyid (Buffer *buf, MonoDomain *domain, MonoProperty *property)
2439 {
2440         buffer_add_ptr_id (buf, domain, ID_PROPERTY, property);
2441 }
2442
2443 static inline void
2444 buffer_add_domainid (Buffer *buf, MonoDomain *domain)
2445 {
2446         buffer_add_ptr_id (buf, domain, ID_DOMAIN, domain);
2447 }
2448
2449 static void invoke_method (void);
2450
2451 /*
2452  * SUSPEND/RESUME
2453  */
2454
2455 /*
2456  * save_thread_context:
2457  *
2458  *   Set CTX as the current threads context which is used for computing stack traces.
2459  * This function is signal-safe.
2460  */
2461 static void
2462 save_thread_context (MonoContext *ctx)
2463 {
2464         DebuggerTlsData *tls;
2465
2466         tls = mono_native_tls_get_value (debugger_tls_id);
2467         g_assert (tls);
2468
2469         if (ctx)
2470                 mono_thread_state_init_from_monoctx (&tls->context, ctx);
2471         else
2472                 mono_thread_state_init_from_current (&tls->context);
2473 }
2474
2475 /* Number of threads suspended */
2476 /* 
2477  * If this is equal to the size of thread_to_tls, the runtime is considered
2478  * suspended.
2479  */
2480 static gint32 threads_suspend_count;
2481
2482 static mono_mutex_t suspend_mutex;
2483
2484 /* Cond variable used to wait for suspend_count becoming 0 */
2485 static mono_cond_t suspend_cond;
2486
2487 /* Semaphore used to wait for a thread becoming suspended */
2488 static MonoSemType suspend_sem;
2489
2490 static void
2491 suspend_init (void)
2492 {
2493         mono_mutex_init (&suspend_mutex);
2494         mono_cond_init (&suspend_cond, NULL);   
2495         MONO_SEM_INIT (&suspend_sem, 0);
2496 }
2497
2498 typedef struct
2499 {
2500         StackFrameInfo last_frame;
2501         gboolean last_frame_set;
2502         MonoContext ctx;
2503         gpointer lmf;
2504 } GetLastFrameUserData;
2505
2506 static gboolean
2507 get_last_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
2508 {
2509         GetLastFrameUserData *data = user_data;
2510
2511         if (info->type == FRAME_TYPE_MANAGED_TO_NATIVE || info->type == FRAME_TYPE_TRAMPOLINE)
2512                 return FALSE;
2513
2514         if (!data->last_frame_set) {
2515                 /* Store the last frame */
2516                 memcpy (&data->last_frame, info, sizeof (StackFrameInfo));
2517                 data->last_frame_set = TRUE;
2518                 return FALSE;
2519         } else {
2520                 /* Store the context/lmf for the frame above the last frame */
2521                 memcpy (&data->ctx, ctx, sizeof (MonoContext));
2522                 data->lmf = info->lmf;
2523                 return TRUE;
2524         }
2525 }
2526
2527 /*
2528  * thread_interrupt:
2529  *
2530  *   Process interruption of a thread. This should be signal safe.
2531  */
2532 static void
2533 thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, MonoJitInfo *ji)
2534 {
2535         gboolean res;
2536         gpointer ip;
2537         MonoNativeThreadId tid;
2538
2539         g_assert (info);
2540
2541         ip = MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx);
2542         tid = mono_thread_info_get_tid (info);
2543
2544         // FIXME: Races when the thread leaves managed code before hitting a single step
2545         // event.
2546
2547         if (ji && !ji->is_trampoline) {
2548                 /* Running managed code, will be suspended by the single step code */
2549                 DEBUG_PRINTF (1, "[%p] Received interrupt while at %s(%p), continuing.\n", (gpointer)(gsize)tid, jinfo_get_method (ji)->name, ip);
2550         } else {
2551                 /* 
2552                  * Running native code, will be suspended when it returns to/enters 
2553                  * managed code. Treat it as already suspended.
2554                  * This might interrupt the code in process_single_step_inner (), we use the
2555                  * tls->suspending flag to avoid races when that happens.
2556                  */
2557                 if (!tls->suspended && !tls->suspending) {
2558                         MonoContext ctx;
2559                         GetLastFrameUserData data;
2560
2561                         // FIXME: printf is not signal safe, but this is only used during
2562                         // debugger debugging
2563                         if (ip)
2564                                 DEBUG_PRINTF (1, "[%p] Received interrupt while at %p, treating as suspended.\n", (gpointer)(gsize)tid, ip);
2565                         //save_thread_context (&ctx);
2566
2567                         if (!tls->thread)
2568                                 /* Already terminated */
2569                                 return;
2570
2571                         /*
2572                          * We are in a difficult position: we want to be able to provide stack
2573                          * traces for this thread, but we can't use the current ctx+lmf, since
2574                          * the thread is still running, so it might return to managed code,
2575                          * making these invalid.
2576                          * So we start a stack walk and save the first frame, along with the
2577                          * parent frame's ctx+lmf. This (hopefully) works because the thread will be 
2578                          * suspended when it returns to managed code, so the parent's ctx should
2579                          * remain valid.
2580                          */
2581                         data.last_frame_set = FALSE;
2582                         mono_get_eh_callbacks ()->mono_walk_stack_with_state (get_last_frame, mono_thread_info_get_suspend_state (info), MONO_UNWIND_SIGNAL_SAFE, &data);
2583                         if (data.last_frame_set) {
2584                                 memcpy (&tls->async_last_frame, &data.last_frame, sizeof (StackFrameInfo));
2585                                 res = mono_thread_state_init_from_monoctx (&tls->async_state, &ctx);
2586                                 g_assert (res);
2587                                 mono_thread_state_init_from_monoctx (&tls->context, &ctx);
2588                                 g_assert (res);
2589
2590                                 memcpy (&tls->async_state.ctx, &data.ctx, sizeof (MonoContext));
2591                                 tls->async_state.unwind_data [MONO_UNWIND_DATA_LMF] = data.lmf;
2592                                 tls->async_state.unwind_data [MONO_UNWIND_DATA_JIT_TLS] = ((MonoThreadInfo*)tls->thread->thread_info)->jit_data;
2593                         } else {
2594                                 tls->async_state.valid = FALSE;
2595                         }
2596
2597                         mono_memory_barrier ();
2598
2599                         tls->suspended = TRUE;
2600                         MONO_SEM_POST (&suspend_sem);
2601                 }
2602         }
2603 }
2604
2605 /*
2606  * reset_native_thread_suspend_state:
2607  * 
2608  *   Reset the suspended flag and state on native threads
2609  */
2610 static void
2611 reset_native_thread_suspend_state (gpointer key, gpointer value, gpointer user_data)
2612 {
2613         DebuggerTlsData *tls = value;
2614
2615         if (!tls->really_suspended && tls->suspended) {
2616                 tls->suspended = FALSE;
2617                 /*
2618                  * The thread might still be running if it was executing native code, so the state won't be invalided by
2619                  * suspend_current ().
2620                  */
2621                 tls->context.valid = FALSE;
2622                 tls->async_state.valid = FALSE;
2623                 invalidate_frames (tls);
2624         }
2625 }
2626
2627 typedef struct {
2628         DebuggerTlsData *tls;
2629         gboolean valid_info;
2630 } InterruptData;
2631
2632 static SuspendThreadResult
2633 debugger_interrupt_critical (MonoThreadInfo *info, gpointer user_data)
2634 {
2635         InterruptData *data = user_data;
2636         MonoJitInfo *ji;
2637
2638         data->valid_info = TRUE;
2639         ji = mono_jit_info_table_find_internal (
2640                         mono_thread_info_get_suspend_state (info)->unwind_data [MONO_UNWIND_DATA_DOMAIN],
2641                         MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx),
2642                         TRUE,
2643                         TRUE);
2644
2645         /* This is signal safe */
2646         thread_interrupt (data->tls, info, ji);
2647         return MonoResumeThread;
2648 }
2649
2650 /*
2651  * notify_thread:
2652  *
2653  *   Notify a thread that it needs to suspend.
2654  */
2655 static void
2656 notify_thread (gpointer key, gpointer value, gpointer user_data)
2657 {
2658         MonoInternalThread *thread = key;
2659         DebuggerTlsData *tls = value;
2660         gsize tid = thread->tid;
2661
2662         if (GetCurrentThreadId () == tid || tls->terminated)
2663                 return;
2664
2665         DEBUG_PRINTF (1, "[%p] Interrupting %p...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid);
2666
2667         /* This is _not_ equivalent to ves_icall_System_Threading_Thread_Abort () */
2668         InterruptData interrupt_data = { 0 };
2669         interrupt_data.tls = tls;
2670
2671         mono_thread_info_safe_suspend_and_run ((MonoNativeThreadId)(gpointer)(gsize)thread->tid, FALSE, debugger_interrupt_critical, &interrupt_data);
2672         if (!interrupt_data.valid_info) {
2673                 DEBUG_PRINTF (1, "[%p] mono_thread_info_suspend_sync () failed for %p...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid);
2674                 /* 
2675                  * Attached thread which died without detaching.
2676                  */
2677                 tls->terminated = TRUE;
2678         }
2679 }
2680
2681 static void
2682 process_suspend (DebuggerTlsData *tls, MonoContext *ctx)
2683 {
2684         guint8 *ip = MONO_CONTEXT_GET_IP (ctx);
2685         MonoJitInfo *ji;
2686         MonoMethod *method;
2687
2688         if (mono_loader_lock_is_owned_by_self ()) {
2689                 /*
2690                  * Shortcut for the check in suspend_current (). This speeds up processing
2691                  * when executing long running code inside the loader lock, i.e. assembly load
2692                  * hooks.
2693                  */
2694                 return;
2695         }
2696
2697         if (debugger_thread_id == GetCurrentThreadId ())
2698                 return;
2699
2700         /* Prevent races with mono_debugger_agent_thread_interrupt () */
2701         if (suspend_count - tls->resume_count > 0)
2702                 tls->suspending = TRUE;
2703
2704         DEBUG_PRINTF (1, "[%p] Received single step event for suspending.\n", (gpointer)GetCurrentThreadId ());
2705
2706         if (suspend_count - tls->resume_count == 0) {
2707                 /* 
2708                  * We are executing a single threaded invoke but the single step for 
2709                  * suspending is still active.
2710                  * FIXME: This slows down single threaded invokes.
2711                  */
2712                 DEBUG_PRINTF (1, "[%p] Ignored during single threaded invoke.\n", (gpointer)GetCurrentThreadId ());
2713                 return;
2714         }
2715
2716         ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, NULL);
2717
2718         /* Can't suspend in these methods */
2719         method = jinfo_get_method (ji);
2720         if (method->klass == mono_defaults.string_class && (!strcmp (method->name, "memset") || strstr (method->name, "memcpy")))
2721                 return;
2722
2723         save_thread_context (ctx);
2724
2725         suspend_current ();
2726 }
2727
2728 /*
2729  * suspend_vm:
2730  *
2731  * Increase the suspend count of the VM. While the suspend count is greater 
2732  * than 0, runtime threads are suspended at certain points during execution.
2733  */
2734 static void
2735 suspend_vm (void)
2736 {
2737         mono_loader_lock ();
2738
2739         MONO_TRY_BLOCKING;
2740         mono_mutex_lock (&suspend_mutex);
2741         MONO_FINISH_TRY_BLOCKING;
2742
2743         suspend_count ++;
2744
2745         DEBUG_PRINTF (1, "[%p] Suspending vm...\n", (gpointer)GetCurrentThreadId ());
2746
2747         if (suspend_count == 1) {
2748                 // FIXME: Is it safe to call this inside the lock ?
2749                 start_single_stepping ();
2750                 mono_g_hash_table_foreach (thread_to_tls, notify_thread, NULL);
2751         }
2752
2753         mono_mutex_unlock (&suspend_mutex);
2754
2755         if (suspend_count == 1)
2756                 /*
2757                  * Suspend creation of new threadpool threads, since they cannot run
2758                  */
2759                 mono_threadpool_ms_suspend ();
2760
2761         mono_loader_unlock ();
2762 }
2763
2764 /*
2765  * resume_vm:
2766  *
2767  * Decrease the suspend count of the VM. If the count reaches 0, runtime threads
2768  * are resumed.
2769  */
2770 static void
2771 resume_vm (void)
2772 {
2773         int err;
2774
2775         g_assert (debugger_thread_id == GetCurrentThreadId ());
2776
2777         mono_loader_lock ();
2778
2779         MONO_TRY_BLOCKING;
2780         mono_mutex_lock (&suspend_mutex);
2781         MONO_FINISH_TRY_BLOCKING;
2782
2783         g_assert (suspend_count > 0);
2784         suspend_count --;
2785
2786         DEBUG_PRINTF (1, "[%p] Resuming vm, suspend count=%d...\n", (gpointer)GetCurrentThreadId (), suspend_count);
2787
2788         if (suspend_count == 0) {
2789                 // FIXME: Is it safe to call this inside the lock ?
2790                 stop_single_stepping ();
2791                 mono_g_hash_table_foreach (thread_to_tls, reset_native_thread_suspend_state, NULL);
2792         }
2793
2794         /* Signal this even when suspend_count > 0, since some threads might have resume_count > 0 */
2795         err = mono_cond_broadcast (&suspend_cond);
2796         g_assert (err == 0);
2797
2798         mono_mutex_unlock (&suspend_mutex);
2799         //g_assert (err == 0);
2800
2801         if (suspend_count == 0)
2802                 mono_threadpool_ms_resume ();
2803
2804         mono_loader_unlock ();
2805 }
2806
2807 /*
2808  * resume_thread:
2809  *
2810  *   Resume just one thread.
2811  */
2812 static void
2813 resume_thread (MonoInternalThread *thread)
2814 {
2815         int err;
2816         DebuggerTlsData *tls;
2817
2818         g_assert (debugger_thread_id == GetCurrentThreadId ());
2819
2820         mono_loader_lock ();
2821
2822         tls = mono_g_hash_table_lookup (thread_to_tls, thread);
2823         g_assert (tls);
2824         
2825         MONO_TRY_BLOCKING;
2826         mono_mutex_lock (&suspend_mutex);
2827         MONO_FINISH_TRY_BLOCKING;
2828
2829         g_assert (suspend_count > 0);
2830
2831         DEBUG_PRINTF (1, "[sdb] Resuming thread %p...\n", (gpointer)(gssize)thread->tid);
2832
2833         tls->resume_count += suspend_count;
2834
2835         /* 
2836          * Signal suspend_count without decreasing suspend_count, the threads will wake up
2837          * but only the one whose resume_count field is > 0 will be resumed.
2838          */
2839         err = mono_cond_broadcast (&suspend_cond);
2840         g_assert (err == 0);
2841
2842         mono_mutex_unlock (&suspend_mutex);
2843         //g_assert (err == 0);
2844
2845         mono_loader_unlock ();
2846 }
2847
2848 static void
2849 free_frames (StackFrame **frames, int nframes)
2850 {
2851         int i;
2852
2853         for (i = 0; i < nframes; ++i) {
2854                 if (frames [i]->jit)
2855                         mono_debug_free_method_jit_info (frames [i]->jit);
2856                 g_free (frames [i]);
2857         }
2858         g_free (frames);
2859 }
2860
2861 static void
2862 invalidate_frames (DebuggerTlsData *tls)
2863 {
2864         if (!tls)
2865                 tls = mono_native_tls_get_value (debugger_tls_id);
2866         g_assert (tls);
2867
2868         free_frames (tls->frames, tls->frame_count);
2869         tls->frame_count = 0;
2870         tls->frames = NULL;
2871
2872         free_frames (tls->restore_frames, tls->restore_frame_count);
2873         tls->restore_frame_count = 0;
2874         tls->restore_frames = NULL;
2875 }
2876
2877 /*
2878  * suspend_current:
2879  *
2880  *   Suspend the current thread until the runtime is resumed. If the thread has a 
2881  * pending invoke, then the invoke is executed before this function returns. 
2882  */
2883 static void
2884 suspend_current (void)
2885 {
2886         DebuggerTlsData *tls;
2887         int err;
2888
2889         g_assert (debugger_thread_id != GetCurrentThreadId ());
2890
2891         if (mono_loader_lock_is_owned_by_self ()) {
2892                 /*
2893                  * If we own the loader mutex, can't suspend until we release it, since the
2894                  * whole runtime can deadlock otherwise.
2895                  */
2896                 return;
2897         }
2898
2899         tls = mono_native_tls_get_value (debugger_tls_id);
2900         g_assert (tls);
2901
2902         MONO_TRY_BLOCKING;
2903         mono_mutex_lock (&suspend_mutex);
2904         MONO_FINISH_TRY_BLOCKING;
2905
2906         tls->suspending = FALSE;
2907         tls->really_suspended = TRUE;
2908
2909         if (!tls->suspended) {
2910                 tls->suspended = TRUE;
2911                 MONO_SEM_POST (&suspend_sem);
2912         }
2913
2914         DEBUG_PRINTF (1, "[%p] Suspended.\n", (gpointer)GetCurrentThreadId ());
2915
2916         MONO_TRY_BLOCKING;
2917         while (suspend_count - tls->resume_count > 0) {
2918                 err = mono_cond_wait (&suspend_cond, &suspend_mutex);
2919                 g_assert (err == 0);
2920         }
2921         MONO_FINISH_TRY_BLOCKING;
2922
2923         tls->suspended = FALSE;
2924         tls->really_suspended = FALSE;
2925
2926         threads_suspend_count --;
2927
2928         mono_mutex_unlock (&suspend_mutex);
2929
2930         DEBUG_PRINTF (1, "[%p] Resumed.\n", (gpointer)GetCurrentThreadId ());
2931
2932         if (tls->pending_invoke) {
2933                 /* Save the original context */
2934                 tls->pending_invoke->has_ctx = TRUE;
2935                 tls->pending_invoke->ctx = tls->context.ctx;
2936
2937                 invoke_method ();
2938         }
2939
2940         /* The frame info becomes invalid after a resume */
2941         tls->context.valid = FALSE;
2942         tls->async_state.valid = FALSE;
2943         invalidate_frames (tls);
2944 }
2945
2946 static void
2947 count_thread (gpointer key, gpointer value, gpointer user_data)
2948 {
2949         DebuggerTlsData *tls = value;
2950
2951         if (!tls->suspended && !tls->terminated)
2952                 *(int*)user_data = *(int*)user_data + 1;
2953 }
2954
2955 static int
2956 count_threads_to_wait_for (void)
2957 {
2958         int count = 0;
2959
2960         mono_loader_lock ();
2961         mono_g_hash_table_foreach (thread_to_tls, count_thread, &count);
2962         mono_loader_unlock ();
2963
2964         return count;
2965 }       
2966
2967 /*
2968  * wait_for_suspend:
2969  *
2970  *   Wait until the runtime is completely suspended.
2971  */
2972 static void
2973 wait_for_suspend (void)
2974 {
2975         int nthreads, nwait, err;
2976         gboolean waited = FALSE;
2977
2978         // FIXME: Threads starting/stopping ?
2979         mono_loader_lock ();
2980         nthreads = mono_g_hash_table_size (thread_to_tls);
2981         mono_loader_unlock ();
2982
2983         while (TRUE) {
2984                 nwait = count_threads_to_wait_for ();
2985                 if (nwait) {
2986                         DEBUG_PRINTF (1, "Waiting for %d(%d) threads to suspend...\n", nwait, nthreads);
2987                         err = MONO_SEM_WAIT (&suspend_sem);
2988                         g_assert (err == 0);
2989                         waited = TRUE;
2990                 } else {
2991                         break;
2992                 }
2993         }
2994
2995         if (waited)
2996                 DEBUG_PRINTF (1, "%d threads suspended.\n", nthreads);
2997 }
2998
2999 /*
3000  * is_suspended:
3001  *
3002  *   Return whenever the runtime is suspended.
3003  */
3004 static gboolean
3005 is_suspended (void)
3006 {
3007         return count_threads_to_wait_for () == 0;
3008 }
3009
3010 static void
3011 no_seq_points_found (MonoMethod *method)
3012 {
3013         /*
3014          * This can happen in full-aot mode with assemblies AOTed without the 'soft-debug' option to save space.
3015          */
3016         printf ("Unable to find seq points for method '%s'.\n", mono_method_full_name (method, TRUE));
3017 }
3018
3019 typedef struct {
3020         DebuggerTlsData *tls;
3021         GSList *frames;
3022 } ComputeFramesUserData;
3023
3024 static gboolean
3025 process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
3026 {
3027         ComputeFramesUserData *ud = user_data;
3028         StackFrame *frame;
3029         MonoMethod *method, *actual_method, *api_method;
3030         SeqPoint sp;
3031         int flags = 0;
3032
3033         if (info->type != FRAME_TYPE_MANAGED) {
3034                 if (info->type == FRAME_TYPE_DEBUGGER_INVOKE) {
3035                         /* Mark the last frame as an invoke frame */
3036                         if (ud->frames)
3037                                 ((StackFrame*)g_slist_last (ud->frames)->data)->flags |= FRAME_FLAG_DEBUGGER_INVOKE;
3038                 }
3039                 return FALSE;
3040         }
3041
3042         if (info->ji)
3043                 method = jinfo_get_method (info->ji);
3044         else
3045                 method = info->method;
3046         actual_method = info->actual_method;
3047         api_method = method;
3048
3049         if (!method)
3050                 return FALSE;
3051
3052         if (!method || (method->wrapper_type && method->wrapper_type != MONO_WRAPPER_DYNAMIC_METHOD && method->wrapper_type != MONO_WRAPPER_MANAGED_TO_NATIVE))
3053                 return FALSE;
3054
3055         if (info->il_offset == -1) {
3056                 /* mono_debug_il_offset_from_address () doesn't seem to be precise enough (#2092) */
3057                 if (ud->frames == NULL) {
3058                         if (mono_find_prev_seq_point_for_native_offset (info->domain, method, info->native_offset, NULL, &sp))
3059                                 info->il_offset = sp.il_offset;
3060                 }
3061                 if (info->il_offset == -1)
3062                         info->il_offset = mono_debug_il_offset_from_address (method, info->domain, info->native_offset);
3063         }
3064
3065         DEBUG_PRINTF (1, "\tFrame: %s:[il=0x%x, native=0x%x] %d\n", mono_method_full_name (method, TRUE), info->il_offset, info->native_offset, info->managed);
3066
3067         if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
3068                 if (!CHECK_PROTOCOL_VERSION (2, 17))
3069                         /* Older clients can't handle this flag */
3070                         return FALSE;
3071                 api_method = mono_marshal_method_from_wrapper (method);
3072                 if (!api_method)
3073                         return FALSE;
3074                 actual_method = api_method;
3075                 flags |= FRAME_FLAG_NATIVE_TRANSITION;
3076         }
3077
3078         frame = g_new0 (StackFrame, 1);
3079         frame->method = method;
3080         frame->actual_method = actual_method;
3081         frame->api_method = api_method;
3082         frame->il_offset = info->il_offset;
3083         frame->native_offset = info->native_offset;
3084         frame->flags = flags;
3085         frame->ji = info->ji;
3086         if (info->reg_locations)
3087                 memcpy (frame->reg_locations, info->reg_locations, MONO_MAX_IREGS * sizeof (mgreg_t*));
3088         if (ctx) {
3089                 frame->ctx = *ctx;
3090                 frame->has_ctx = TRUE;
3091         }
3092         frame->domain = info->domain;
3093
3094         ud->frames = g_slist_append (ud->frames, frame);
3095
3096         return FALSE;
3097 }
3098
3099 static gboolean
3100 process_filter_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
3101 {
3102         ComputeFramesUserData *ud = user_data;
3103
3104         /*
3105          * 'tls->filter_ctx' is the location of the throw site.
3106          *
3107          * mono_walk_stack() will never actually hit the throw site, but unwind
3108          * directly from the filter to the call site; we abort stack unwinding here
3109          * once this happens and resume from the throw site.
3110          */
3111
3112         if (MONO_CONTEXT_GET_SP (ctx) >= MONO_CONTEXT_GET_SP (&ud->tls->filter_state.ctx))
3113                 return TRUE;
3114
3115         return process_frame (info, ctx, user_data);
3116 }
3117
3118 /*
3119  * Return a malloc-ed list of StackFrame structures.
3120  */
3121 static StackFrame**
3122 compute_frame_info_from (MonoInternalThread *thread, DebuggerTlsData *tls, MonoThreadUnwindState *state, int *out_nframes)
3123 {
3124         ComputeFramesUserData user_data;
3125         MonoUnwindOptions opts = MONO_UNWIND_DEFAULT|MONO_UNWIND_REG_LOCATIONS;
3126         StackFrame **res;
3127         int i, nframes;
3128         GSList *l;
3129
3130         user_data.tls = tls;
3131         user_data.frames = NULL;
3132
3133         mono_walk_stack_with_state (process_frame, state, opts, &user_data);
3134
3135         nframes = g_slist_length (user_data.frames);
3136         res = g_new0 (StackFrame*, nframes);
3137         l = user_data.frames;
3138         for (i = 0; i < nframes; ++i) {
3139                 res [i] = l->data;
3140                 l = l->next;
3141         }
3142         *out_nframes = nframes;
3143
3144         return res;
3145 }
3146
3147 static void
3148 compute_frame_info (MonoInternalThread *thread, DebuggerTlsData *tls)
3149 {
3150         ComputeFramesUserData user_data;
3151         GSList *tmp;
3152         int i, findex, new_frame_count;
3153         StackFrame **new_frames, *f;
3154         MonoUnwindOptions opts = MONO_UNWIND_DEFAULT|MONO_UNWIND_REG_LOCATIONS;
3155
3156         // FIXME: Locking on tls
3157         if (tls->frames && tls->frames_up_to_date)
3158                 return;
3159
3160         DEBUG_PRINTF (1, "Frames for %p(tid=%lx):\n", thread, (glong)thread->tid);
3161
3162         user_data.tls = tls;
3163         user_data.frames = NULL;
3164         if (tls->terminated) {
3165                 tls->frame_count = 0;
3166                 return;
3167         } if (!tls->really_suspended && tls->async_state.valid) {
3168                 /* Have to use the state saved by the signal handler */
3169                 process_frame (&tls->async_last_frame, NULL, &user_data);
3170                 mono_walk_stack_with_state (process_frame, &tls->async_state, opts, &user_data);
3171         } else if (tls->filter_state.valid) {
3172                 /*
3173                  * We are inside an exception filter.
3174                  *
3175                  * First we add all the frames from inside the filter; 'tls->ctx' has the current context.
3176                  */
3177                 if (tls->context.valid)
3178                         mono_walk_stack_with_state (process_filter_frame, &tls->context, opts, &user_data);
3179                 /*
3180                  * After that, we resume unwinding from the location where the exception has been thrown.
3181                  */
3182                 mono_walk_stack_with_state (process_frame, &tls->filter_state, opts, &user_data);
3183         } else if (tls->context.valid) {
3184                 mono_walk_stack_with_state (process_frame, &tls->context, opts, &user_data);
3185         } else {
3186                 // FIXME:
3187                 tls->frame_count = 0;
3188                 return;
3189         }
3190
3191         new_frame_count = g_slist_length (user_data.frames);
3192         new_frames = g_new0 (StackFrame*, new_frame_count);
3193         findex = 0;
3194         for (tmp = user_data.frames; tmp; tmp = tmp->next) {
3195                 f = tmp->data;
3196
3197                 /* 
3198                  * Reuse the id for already existing stack frames, so invokes don't invalidate
3199                  * the still valid stack frames.
3200                  */
3201                 for (i = 0; i < tls->frame_count; ++i) {
3202                         if (MONO_CONTEXT_GET_SP (&tls->frames [i]->ctx) == MONO_CONTEXT_GET_SP (&f->ctx)) {
3203                                 f->id = tls->frames [i]->id;
3204                                 break;
3205                         }
3206                 }
3207
3208                 if (i >= tls->frame_count)
3209                         f->id = InterlockedIncrement (&frame_id);
3210
3211                 new_frames [findex ++] = f;
3212         }
3213
3214         g_slist_free (user_data.frames);
3215
3216         invalidate_frames (tls);
3217
3218         tls->frames = new_frames;
3219         tls->frame_count = new_frame_count;
3220         tls->frames_up_to_date = TRUE;
3221 }
3222
3223 /*
3224  * GHFunc to emit an appdomain creation event
3225  * @param key Don't care
3226  * @param value A loaded appdomain
3227  * @param user_data Don't care
3228  */
3229 static void
3230 emit_appdomain_load (gpointer key, gpointer value, gpointer user_data)
3231 {
3232         process_profiler_event (EVENT_KIND_APPDOMAIN_CREATE, value);
3233         g_hash_table_foreach (get_agent_domain_info (value)->loaded_classes, emit_type_load, NULL);
3234 }
3235
3236 /*
3237  * GHFunc to emit a thread start event
3238  * @param key A thread id
3239  * @param value A thread object
3240  * @param user_data Don't care
3241  */
3242 static void
3243 emit_thread_start (gpointer key, gpointer value, gpointer user_data)
3244 {
3245         if (GPOINTER_TO_INT (key) != debugger_thread_id)
3246                 process_profiler_event (EVENT_KIND_THREAD_START, value);
3247 }
3248
3249 /*
3250  * GFunc to emit an assembly load event
3251  * @param value A loaded assembly
3252  * @param user_data Don't care
3253  */
3254 static void
3255 emit_assembly_load (gpointer value, gpointer user_data)
3256 {
3257         process_profiler_event (EVENT_KIND_ASSEMBLY_LOAD, value);
3258 }
3259
3260 /*
3261  * GFunc to emit a type load event
3262  * @param value A loaded type
3263  * @param user_data Don't care
3264  */
3265 static void
3266 emit_type_load (gpointer key, gpointer value, gpointer user_data)
3267 {
3268         process_profiler_event (EVENT_KIND_TYPE_LOAD, value);
3269 }
3270
3271 static char*
3272 strdup_tolower (char *s)
3273 {
3274         char *s2, *p;
3275
3276         s2 = g_strdup (s);
3277         for (p = s2; *p; ++p)
3278                 *p = tolower (*p);
3279         return s2;
3280 }
3281
3282 /*
3283  * Same as g_path_get_basename () but handles windows paths as well,
3284  * which can occur in .mdb files created by pdb2mdb.
3285  */
3286 static char*
3287 dbg_path_get_basename (const char *filename)
3288 {
3289         char *r;
3290
3291         if (!filename || strchr (filename, '/') || !strchr (filename, '\\'))
3292                 return g_path_get_basename (filename);
3293
3294         /* From gpath.c */
3295
3296         /* No separator -> filename */
3297         r = strrchr (filename, '\\');
3298         if (r == NULL)
3299                 return g_strdup (filename);
3300
3301         /* Trailing slash, remove component */
3302         if (r [1] == 0){
3303                 char *copy = g_strdup (filename);
3304                 copy [r-filename] = 0;
3305                 r = strrchr (copy, '\\');
3306
3307                 if (r == NULL){
3308                         g_free (copy);
3309                         return g_strdup ("/");
3310                 }
3311                 r = g_strdup (&r[1]);
3312                 g_free (copy);
3313                 return r;
3314         }
3315
3316         return g_strdup (&r[1]);
3317 }
3318
3319 static void
3320 init_jit_info_dbg_attrs (MonoJitInfo *ji)
3321 {
3322         static MonoClass *hidden_klass, *step_through_klass, *non_user_klass;
3323         MonoCustomAttrInfo *ainfo;
3324
3325         if (ji->dbg_attrs_inited)
3326                 return;
3327
3328         if (!hidden_klass) {
3329                 hidden_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerHiddenAttribute");
3330                 g_assert (hidden_klass);
3331         }
3332         if (!step_through_klass) {
3333                 step_through_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerStepThroughAttribute");
3334                 g_assert (step_through_klass);
3335         }
3336         if (!non_user_klass) {
3337                 non_user_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerNonUserCodeAttribute");
3338                 g_assert (non_user_klass);
3339         }
3340
3341         ainfo = mono_custom_attrs_from_method (jinfo_get_method (ji));
3342         if (ainfo) {
3343                 if (mono_custom_attrs_has_attr (ainfo, hidden_klass))
3344                         ji->dbg_hidden = TRUE;
3345                 if (mono_custom_attrs_has_attr (ainfo, step_through_klass))
3346                         ji->dbg_step_through = TRUE;
3347                 if (mono_custom_attrs_has_attr (ainfo, non_user_klass))
3348                         ji->dbg_non_user_code = TRUE;
3349                 mono_custom_attrs_free (ainfo);
3350         }
3351
3352         ainfo = mono_custom_attrs_from_class (jinfo_get_method (ji)->klass);
3353         if (ainfo) {
3354                 if (mono_custom_attrs_has_attr (ainfo, step_through_klass))
3355                         ji->dbg_step_through = TRUE;
3356                 if (mono_custom_attrs_has_attr (ainfo, non_user_klass))
3357                         ji->dbg_non_user_code = TRUE;
3358                 mono_custom_attrs_free (ainfo);
3359         }
3360
3361         mono_memory_barrier ();
3362         ji->dbg_attrs_inited = TRUE;
3363 }
3364
3365 /*
3366  * EVENT HANDLING
3367  */
3368
3369 /*
3370  * create_event_list:
3371  *
3372  *   Return a list of event request ids matching EVENT, starting from REQS, which
3373  * can be NULL to include all event requests. Set SUSPEND_POLICY to the suspend
3374  * policy.
3375  * We return request ids, instead of requests, to simplify threading, since 
3376  * requests could be deleted anytime when the loader lock is not held.
3377  * LOCKING: Assumes the loader lock is held.
3378  */
3379 static GSList*
3380 create_event_list (EventKind event, GPtrArray *reqs, MonoJitInfo *ji, EventInfo *ei, int *suspend_policy)
3381 {
3382         int i, j;
3383         GSList *events = NULL;
3384
3385         *suspend_policy = SUSPEND_POLICY_NONE;
3386
3387         if (!reqs)
3388                 reqs = event_requests;
3389
3390         if (!reqs)
3391                 return NULL;
3392
3393         for (i = 0; i < reqs->len; ++i) {
3394                 EventRequest *req = g_ptr_array_index (reqs, i);
3395                 if (req->event_kind == event) {
3396                         gboolean filtered = FALSE;
3397
3398                         /* Apply filters */
3399                         for (j = 0; j < req->nmodifiers; ++j) {
3400                                 Modifier *mod = &req->modifiers [j];
3401
3402                                 if (mod->kind == MOD_KIND_COUNT) {
3403                                         filtered = TRUE;
3404                                         if (mod->data.count > 0) {
3405                                                 if (mod->data.count > 0) {
3406                                                         mod->data.count --;
3407                                                         if (mod->data.count == 0)
3408                                                                 filtered = FALSE;
3409                                                 }
3410                                         }
3411                                 } else if (mod->kind == MOD_KIND_THREAD_ONLY) {
3412                                         if (mod->data.thread != mono_thread_internal_current ())
3413                                                 filtered = TRUE;
3414                                 } else if (mod->kind == MOD_KIND_EXCEPTION_ONLY && ei) {
3415                                         if (mod->data.exc_class && mod->subclasses && !mono_class_is_assignable_from (mod->data.exc_class, ei->exc->vtable->klass))
3416                                                 filtered = TRUE;
3417                                         if (mod->data.exc_class && !mod->subclasses && mod->data.exc_class != ei->exc->vtable->klass)
3418                                                 filtered = TRUE;
3419                                         if (ei->caught && !mod->caught)
3420                                                 filtered = TRUE;
3421                                         if (!ei->caught && !mod->uncaught)
3422                                                 filtered = TRUE;
3423                                 } else if (mod->kind == MOD_KIND_ASSEMBLY_ONLY && ji) {
3424                                         int k;
3425                                         gboolean found = FALSE;
3426                                         MonoAssembly **assemblies = mod->data.assemblies;
3427
3428                                         if (assemblies) {
3429                                                 for (k = 0; assemblies [k]; ++k)
3430                                                         if (assemblies [k] == jinfo_get_method (ji)->klass->image->assembly)
3431                                                                 found = TRUE;
3432                                         }
3433                                         if (!found)
3434                                                 filtered = TRUE;
3435                                 } else if (mod->kind == MOD_KIND_SOURCE_FILE_ONLY && ei && ei->klass) {
3436                                         gpointer iter = NULL;
3437                                         MonoMethod *method;
3438                                         MonoDebugSourceInfo *sinfo;
3439                                         char *source_file, *s;
3440                                         gboolean found = FALSE;
3441                                         int i;
3442                                         GPtrArray *source_file_list;
3443
3444                                         while ((method = mono_class_get_methods (ei->klass, &iter))) {
3445                                                 MonoDebugMethodInfo *minfo = mono_debug_lookup_method (method);
3446
3447                                                 if (minfo) {
3448                                                         mono_debug_get_seq_points (minfo, &source_file, &source_file_list, NULL, NULL, NULL);
3449                                                         for (i = 0; i < source_file_list->len; ++i) {
3450                                                                 sinfo = g_ptr_array_index (source_file_list, i);
3451                                                                 /*
3452                                                                  * Do a case-insesitive match by converting the file name to
3453                                                                  * lowercase.
3454                                                                  */
3455                                                                 s = strdup_tolower (sinfo->source_file);
3456                                                                 if (g_hash_table_lookup (mod->data.source_files, s))
3457                                                                         found = TRUE;
3458                                                                 else {
3459                                                                         char *s2 = dbg_path_get_basename (sinfo->source_file);
3460                                                                         char *s3 = strdup_tolower (s2);
3461
3462                                                                         if (g_hash_table_lookup (mod->data.source_files, s3))
3463                                                                                 found = TRUE;
3464                                                                         g_free (s2);
3465                                                                         g_free (s3);
3466                                                                 }
3467                                                                 g_free (s);
3468                                                         }
3469                                                         g_ptr_array_free (source_file_list, TRUE);
3470                                                 }
3471                                         }
3472                                         if (!found)
3473                                                 filtered = TRUE;
3474                                 } else if (mod->kind == MOD_KIND_TYPE_NAME_ONLY && ei && ei->klass) {
3475                                         char *s;
3476
3477                                         s = mono_type_full_name (&ei->klass->byval_arg);
3478                                         if (!g_hash_table_lookup (mod->data.type_names, s))
3479                                                 filtered = TRUE;
3480                                         g_free (s);
3481                                 } else if (mod->kind == MOD_KIND_STEP) {
3482                                         if ((mod->data.filter & STEP_FILTER_STATIC_CTOR) && ji &&
3483                                                 (jinfo_get_method (ji)->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) &&
3484                                                 !strcmp (jinfo_get_method (ji)->name, ".cctor") &&
3485                                                 (jinfo_get_method (ji) != ((SingleStepReq*)req->info)->start_method))
3486                                                 filtered = TRUE;
3487                                         if ((mod->data.filter & STEP_FILTER_DEBUGGER_HIDDEN) && ji) {
3488                                                 init_jit_info_dbg_attrs (ji);
3489                                                 if (ji->dbg_hidden)
3490                                                         filtered = TRUE;
3491                                         }
3492                                         if ((mod->data.filter & STEP_FILTER_DEBUGGER_STEP_THROUGH) && ji) {
3493                                                 init_jit_info_dbg_attrs (ji);
3494                                                 if (ji->dbg_step_through)
3495                                                         filtered = TRUE;
3496                                         }
3497                                         if ((mod->data.filter & STEP_FILTER_DEBUGGER_NON_USER_CODE) && ji) {
3498                                                 init_jit_info_dbg_attrs (ji);
3499                                                 if (ji->dbg_non_user_code)
3500                                                         filtered = TRUE;
3501                                         }
3502                                 }
3503                         }
3504
3505                         if (!filtered) {
3506                                 *suspend_policy = MAX (*suspend_policy, req->suspend_policy);
3507                                 events = g_slist_append (events, GINT_TO_POINTER (req->id));
3508                         }
3509                 }
3510         }
3511
3512         /* Send a VM START/DEATH event by default */
3513         if (event == EVENT_KIND_VM_START)
3514                 events = g_slist_append (events, GINT_TO_POINTER (0));
3515         if (event == EVENT_KIND_VM_DEATH)
3516                 events = g_slist_append (events, GINT_TO_POINTER (0));
3517
3518         return events;
3519 }
3520
3521 static G_GNUC_UNUSED const char*
3522 event_to_string (EventKind event)
3523 {
3524         switch (event) {
3525         case EVENT_KIND_VM_START: return "VM_START";
3526         case EVENT_KIND_VM_DEATH: return "VM_DEATH";
3527         case EVENT_KIND_THREAD_START: return "THREAD_START";
3528         case EVENT_KIND_THREAD_DEATH: return "THREAD_DEATH";
3529         case EVENT_KIND_APPDOMAIN_CREATE: return "APPDOMAIN_CREATE";
3530         case EVENT_KIND_APPDOMAIN_UNLOAD: return "APPDOMAIN_UNLOAD";
3531         case EVENT_KIND_METHOD_ENTRY: return "METHOD_ENTRY";
3532         case EVENT_KIND_METHOD_EXIT: return "METHOD_EXIT";
3533         case EVENT_KIND_ASSEMBLY_LOAD: return "ASSEMBLY_LOAD";
3534         case EVENT_KIND_ASSEMBLY_UNLOAD: return "ASSEMBLY_UNLOAD";
3535         case EVENT_KIND_BREAKPOINT: return "BREAKPOINT";
3536         case EVENT_KIND_STEP: return "STEP";
3537         case EVENT_KIND_TYPE_LOAD: return "TYPE_LOAD";
3538         case EVENT_KIND_EXCEPTION: return "EXCEPTION";
3539         case EVENT_KIND_KEEPALIVE: return "KEEPALIVE";
3540         case EVENT_KIND_USER_BREAK: return "USER_BREAK";
3541         case EVENT_KIND_USER_LOG: return "USER_LOG";
3542         default:
3543                 g_assert_not_reached ();
3544                 return "";
3545         }
3546 }
3547
3548 /*
3549  * process_event:
3550  *
3551  *   Send an event to the client, suspending the vm if needed.
3552  * LOCKING: Since this can suspend the calling thread, no locks should be held
3553  * by the caller.
3554  * The EVENTS list is freed by this function.
3555  */
3556 static void
3557 process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx, GSList *events, int suspend_policy)
3558 {
3559         Buffer buf;
3560         GSList *l;
3561         MonoDomain *domain = mono_domain_get ();
3562         MonoThread *thread = NULL;
3563         MonoObject *keepalive_obj = NULL;
3564         gboolean send_success = FALSE;
3565         static int ecount;
3566         int nevents;
3567
3568         if (!inited) {
3569                 DEBUG_PRINTF (2, "Debugger agent not initialized yet: dropping %s\n", event_to_string (event));
3570                 return;
3571         }
3572
3573         if (!vm_start_event_sent && event != EVENT_KIND_VM_START) {
3574                 // FIXME: We miss those events
3575                 DEBUG_PRINTF (2, "VM start event not sent yet: dropping %s\n", event_to_string (event));
3576                 return;
3577         }
3578
3579         if (vm_death_event_sent) {
3580                 DEBUG_PRINTF (2, "VM death event has been sent: dropping %s\n", event_to_string (event));
3581                 return;
3582         }
3583
3584         if (mono_runtime_is_shutting_down () && event != EVENT_KIND_VM_DEATH) {
3585                 DEBUG_PRINTF (2, "Mono runtime is shutting down: dropping %s\n", event_to_string (event));
3586                 return;
3587         }
3588
3589         if (disconnected) {
3590                 DEBUG_PRINTF (2, "Debugger client is not connected: dropping %s\n", event_to_string (event));
3591                 return;
3592         }
3593
3594         if (event == EVENT_KIND_KEEPALIVE)
3595                 suspend_policy = SUSPEND_POLICY_NONE;
3596         else {
3597                 if (events == NULL)
3598                         return;
3599
3600                 if (agent_config.defer) {
3601                         /* Make sure the thread id is always set when doing deferred debugging */
3602                         if (debugger_thread_id == GetCurrentThreadId ()) {
3603                                 /* Don't suspend on events from the debugger thread */
3604                                 suspend_policy = SUSPEND_POLICY_NONE;
3605                                 thread = mono_thread_get_main ();
3606                         }
3607                         else thread = mono_thread_current ();
3608                 } else {
3609                         if (debugger_thread_id == GetCurrentThreadId () && event != EVENT_KIND_VM_DEATH)
3610                                 // FIXME: Send these with a NULL thread, don't suspend the current thread
3611                                 return;
3612                 }
3613         }
3614
3615         nevents = g_slist_length (events);
3616         buffer_init (&buf, 128);
3617         buffer_add_byte (&buf, suspend_policy);
3618         buffer_add_int (&buf, nevents);
3619
3620         for (l = events; l; l = l->next) {
3621                 buffer_add_byte (&buf, event); // event kind
3622                 buffer_add_int (&buf, GPOINTER_TO_INT (l->data)); // request id
3623
3624                 ecount ++;
3625
3626                 if (!thread)
3627                         thread = mono_thread_current ();
3628
3629                 if (event == EVENT_KIND_VM_START && arg != NULL)
3630                         thread = arg;
3631
3632                 buffer_add_objid (&buf, (MonoObject*)thread); // thread
3633
3634                 switch (event) {
3635                 case EVENT_KIND_THREAD_START:
3636                 case EVENT_KIND_THREAD_DEATH:
3637                         break;
3638                 case EVENT_KIND_APPDOMAIN_CREATE:
3639                 case EVENT_KIND_APPDOMAIN_UNLOAD:
3640                         buffer_add_domainid (&buf, arg);
3641                         break;
3642                 case EVENT_KIND_METHOD_ENTRY:
3643                 case EVENT_KIND_METHOD_EXIT:
3644                         buffer_add_methodid (&buf, domain, arg);
3645                         break;
3646                 case EVENT_KIND_ASSEMBLY_LOAD:
3647                         buffer_add_assemblyid (&buf, domain, arg);
3648                         break;
3649                 case EVENT_KIND_ASSEMBLY_UNLOAD: {
3650                         DebuggerTlsData *tls;
3651
3652                         /* The domain the assembly belonged to is not equal to the current domain */
3653                         tls = mono_native_tls_get_value (debugger_tls_id);
3654                         g_assert (tls);
3655                         g_assert (tls->domain_unloading);
3656
3657                         buffer_add_assemblyid (&buf, tls->domain_unloading, arg);
3658                         break;
3659                 }
3660                 case EVENT_KIND_TYPE_LOAD:
3661                         buffer_add_typeid (&buf, domain, arg);
3662                         break;
3663                 case EVENT_KIND_BREAKPOINT:
3664                 case EVENT_KIND_STEP:
3665                         buffer_add_methodid (&buf, domain, arg);
3666                         buffer_add_long (&buf, il_offset);
3667                         break;
3668                 case EVENT_KIND_VM_START:
3669                         buffer_add_domainid (&buf, mono_get_root_domain ());
3670                         break;
3671                 case EVENT_KIND_VM_DEATH:
3672                         if (CHECK_PROTOCOL_VERSION (2, 27))
3673                                 buffer_add_int (&buf, mono_environment_exitcode_get ());
3674                         break;
3675                 case EVENT_KIND_EXCEPTION: {
3676                         EventInfo *ei = arg;
3677                         buffer_add_objid (&buf, ei->exc);
3678                         /*
3679                          * We are not yet suspending, so get_objref () will not keep this object alive. So we need to do it
3680                          * later after the suspension. (#12494).
3681                          */
3682                         keepalive_obj = ei->exc;
3683                         break;
3684                 }
3685                 case EVENT_KIND_USER_BREAK:
3686                         break;
3687                 case EVENT_KIND_USER_LOG: {
3688                         EventInfo *ei = arg;
3689                         buffer_add_int (&buf, ei->level);
3690                         buffer_add_string (&buf, ei->category ? ei->category : "");
3691                         buffer_add_string (&buf, ei->message ? ei->message : "");
3692                         break;
3693                 }
3694                 case EVENT_KIND_KEEPALIVE:
3695                         suspend_policy = SUSPEND_POLICY_NONE;
3696                         break;
3697                 default:
3698                         g_assert_not_reached ();
3699                 }
3700         }
3701
3702         if (event == EVENT_KIND_VM_START) {
3703                 suspend_policy = agent_config.suspend ? SUSPEND_POLICY_ALL : SUSPEND_POLICY_NONE;
3704                 if (!agent_config.defer)
3705                         start_debugger_thread ();
3706         }
3707    
3708         if (event == EVENT_KIND_VM_DEATH) {
3709                 vm_death_event_sent = TRUE;
3710                 suspend_policy = SUSPEND_POLICY_NONE;
3711         }
3712
3713         if (mono_runtime_is_shutting_down ())
3714                 suspend_policy = SUSPEND_POLICY_NONE;
3715
3716         if (suspend_policy != SUSPEND_POLICY_NONE) {
3717                 /* 
3718                  * Save the thread context and start suspending before sending the packet,
3719                  * since we could be receiving the resume request before send_packet ()
3720                  * returns.
3721                  */
3722                 save_thread_context (ctx);
3723                 suspend_vm ();
3724
3725                 if (keepalive_obj)
3726                         /* This will keep this object alive */
3727                         get_objref (keepalive_obj);
3728         }
3729
3730         send_success = send_packet (CMD_SET_EVENT, CMD_COMPOSITE, &buf);
3731
3732         buffer_free (&buf);
3733
3734         g_slist_free (events);
3735         events = NULL;
3736
3737         if (!send_success) {
3738                 DEBUG_PRINTF (2, "Sending command %s failed.\n", event_to_string (event));
3739                 return;
3740         }
3741         
3742         if (event == EVENT_KIND_VM_START) {
3743                 vm_start_event_sent = TRUE;
3744         }
3745
3746         DEBUG_PRINTF (1, "[%p] Sent %d events %s(%d), suspend=%d.\n", (gpointer)GetCurrentThreadId (), nevents, event_to_string (event), ecount, suspend_policy);
3747
3748         switch (suspend_policy) {
3749         case SUSPEND_POLICY_NONE:
3750                 break;
3751         case SUSPEND_POLICY_ALL:
3752                 suspend_current ();
3753                 break;
3754         case SUSPEND_POLICY_EVENT_THREAD:
3755                 NOT_IMPLEMENTED;
3756                 break;
3757         default:
3758                 g_assert_not_reached ();
3759         }
3760 }
3761
3762 static void
3763 process_profiler_event (EventKind event, gpointer arg)
3764 {
3765         int suspend_policy;
3766         GSList *events;
3767         EventInfo ei, *ei_arg = NULL;
3768
3769         if (event == EVENT_KIND_TYPE_LOAD) {
3770                 ei.klass = arg;
3771                 ei_arg = &ei;
3772         }
3773
3774         mono_loader_lock ();
3775         events = create_event_list (event, NULL, NULL, ei_arg, &suspend_policy);
3776         mono_loader_unlock ();
3777
3778         process_event (event, arg, 0, NULL, events, suspend_policy);
3779 }
3780
3781 static void
3782 runtime_initialized (MonoProfiler *prof)
3783 {
3784         process_profiler_event (EVENT_KIND_VM_START, mono_thread_current ());
3785         if (agent_config.defer)
3786                 start_debugger_thread ();
3787 }
3788
3789 static void
3790 runtime_shutdown (MonoProfiler *prof)
3791 {
3792         process_profiler_event (EVENT_KIND_VM_DEATH, mono_thread_current ());
3793
3794         mono_debugger_agent_cleanup ();
3795 }
3796
3797 static void
3798 thread_startup (MonoProfiler *prof, uintptr_t tid)
3799 {
3800         MonoInternalThread *thread = mono_thread_internal_current ();
3801         MonoInternalThread *old_thread;
3802         DebuggerTlsData *tls;
3803
3804         if (tid == debugger_thread_id)
3805                 return;
3806
3807         g_assert (thread->tid == tid);
3808
3809         mono_loader_lock ();
3810         old_thread = mono_g_hash_table_lookup (tid_to_thread, (gpointer)tid);
3811         mono_loader_unlock ();
3812         if (old_thread) {
3813                 if (thread == old_thread) {
3814                         /* 
3815                          * For some reason, thread_startup () might be called for the same thread
3816                          * multiple times (attach ?).
3817                          */
3818                         DEBUG_PRINTF (1, "[%p] thread_start () called multiple times for %p, ignored.\n", (gpointer)tid, (gpointer)tid);
3819                         return;
3820                 } else {
3821                         /*
3822                          * thread_end () might not be called for some threads, and the tid could
3823                          * get reused.
3824                          */
3825                         DEBUG_PRINTF (1, "[%p] Removing stale data for tid %p.\n", (gpointer)tid, (gpointer)tid);
3826                         mono_loader_lock ();
3827                         mono_g_hash_table_remove (thread_to_tls, old_thread);
3828                         mono_g_hash_table_remove (tid_to_thread, (gpointer)tid);
3829                         mono_g_hash_table_remove (tid_to_thread_obj, (gpointer)tid);
3830                         mono_loader_unlock ();
3831                 }
3832         }
3833
3834         tls = mono_native_tls_get_value (debugger_tls_id);
3835         g_assert (!tls);
3836         // FIXME: Free this somewhere
3837         tls = g_new0 (DebuggerTlsData, 1);
3838         MONO_GC_REGISTER_ROOT_SINGLE (tls->thread);
3839         tls->thread = thread;
3840         mono_native_tls_set_value (debugger_tls_id, tls);
3841
3842         DEBUG_PRINTF (1, "[%p] Thread started, obj=%p, tls=%p.\n", (gpointer)tid, thread, tls);
3843
3844         mono_loader_lock ();
3845         mono_g_hash_table_insert (thread_to_tls, thread, tls);
3846         mono_g_hash_table_insert (tid_to_thread, (gpointer)tid, thread);
3847         mono_g_hash_table_insert (tid_to_thread_obj, (gpointer)tid, mono_thread_current ());
3848         mono_loader_unlock ();
3849
3850         process_profiler_event (EVENT_KIND_THREAD_START, thread);
3851
3852         /* 
3853          * suspend_vm () could have missed this thread, so wait for a resume.
3854          */
3855         suspend_current ();
3856 }
3857
3858 static void
3859 thread_end (MonoProfiler *prof, uintptr_t tid)
3860 {
3861         MonoInternalThread *thread;
3862         DebuggerTlsData *tls = NULL;
3863
3864         mono_loader_lock ();
3865         thread = mono_g_hash_table_lookup (tid_to_thread, (gpointer)tid);
3866         if (thread) {
3867                 mono_g_hash_table_remove (tid_to_thread_obj, (gpointer)tid);
3868                 tls = mono_g_hash_table_lookup (thread_to_tls, thread);
3869                 if (tls) {
3870                         /* FIXME: Maybe we need to free this instead, but some code can't handle that */
3871                         tls->terminated = TRUE;
3872                         /* Can't remove from tid_to_thread, as that would defeat the check in thread_start () */
3873                         MONO_GC_UNREGISTER_ROOT (tls->thread);
3874                         tls->thread = NULL;
3875                 }
3876         }
3877         mono_loader_unlock ();
3878
3879         /* We might be called for threads started before we registered the start callback */
3880         if (thread) {
3881                 DEBUG_PRINTF (1, "[%p] Thread terminated, obj=%p, tls=%p.\n", (gpointer)tid, thread, tls);
3882
3883                 if (GetCurrentThreadId () == tid && !mono_native_tls_get_value (debugger_tls_id)) {
3884                         /*
3885                          * This can happen on darwin since we deregister threads using pthread dtors.
3886                          * process_profiler_event () and the code it calls cannot handle a null TLS value.
3887                          */
3888                         return;
3889                 }
3890
3891                 process_profiler_event (EVENT_KIND_THREAD_DEATH, thread);
3892         }
3893 }
3894
3895 static void
3896 appdomain_load (MonoProfiler *prof, MonoDomain *domain, int result)
3897 {
3898         mono_loader_lock ();
3899         g_hash_table_insert (domains, domain, domain);
3900         mono_loader_unlock ();
3901
3902         process_profiler_event (EVENT_KIND_APPDOMAIN_CREATE, domain);
3903 }
3904
3905 static void
3906 appdomain_start_unload (MonoProfiler *prof, MonoDomain *domain)
3907 {
3908         DebuggerTlsData *tls;
3909
3910         /* This might be called during shutdown on the debugger thread from the CMD_VM_EXIT code */
3911         if (is_debugger_thread ())
3912                 return;
3913
3914         /*
3915          * Remember the currently unloading appdomain as it is needed to generate
3916          * proper ids for unloading assemblies.
3917          */
3918         tls = mono_native_tls_get_value (debugger_tls_id);
3919         g_assert (tls);
3920         tls->domain_unloading = domain;
3921 }
3922
3923 static void
3924 appdomain_unload (MonoProfiler *prof, MonoDomain *domain)
3925 {
3926         DebuggerTlsData *tls;
3927
3928         if (is_debugger_thread ())
3929                 return;
3930
3931         tls = mono_native_tls_get_value (debugger_tls_id);
3932         g_assert (tls);
3933         tls->domain_unloading = NULL;
3934
3935         clear_breakpoints_for_domain (domain);
3936         
3937         mono_loader_lock ();
3938         /* Invalidate each thread's frame stack */
3939         mono_g_hash_table_foreach (thread_to_tls, invalidate_each_thread, NULL);
3940         mono_loader_unlock ();
3941         
3942         process_profiler_event (EVENT_KIND_APPDOMAIN_UNLOAD, domain);
3943 }
3944
3945 /*
3946  * invalidate_each_thread:
3947  *
3948  *   A GHFunc to invalidate frames.
3949  *   value must be a DebuggerTlsData*
3950  */
3951 static void
3952 invalidate_each_thread (gpointer key, gpointer value, gpointer user_data)
3953 {
3954         invalidate_frames (value);
3955 }
3956
3957 static void
3958 assembly_load (MonoProfiler *prof, MonoAssembly *assembly, int result)
3959 {
3960         /* Sent later in jit_end () */
3961         dbg_lock ();
3962         g_ptr_array_add (pending_assembly_loads, assembly);
3963         dbg_unlock ();
3964 }
3965
3966 static void
3967 assembly_unload (MonoProfiler *prof, MonoAssembly *assembly)
3968 {
3969         if (is_debugger_thread ())
3970                 return;
3971
3972         process_profiler_event (EVENT_KIND_ASSEMBLY_UNLOAD, assembly);
3973
3974         clear_event_requests_for_assembly (assembly);
3975         clear_types_for_assembly (assembly);
3976 }
3977
3978 static void
3979 send_type_load (MonoClass *klass)
3980 {
3981         gboolean type_load = FALSE;
3982         MonoDomain *domain = mono_domain_get ();
3983         AgentDomainInfo *info = NULL;
3984
3985         info = get_agent_domain_info (domain);
3986
3987         mono_loader_lock ();
3988
3989         if (!g_hash_table_lookup (info->loaded_classes, klass)) {
3990                 type_load = TRUE;
3991                 g_hash_table_insert (info->loaded_classes, klass, klass);
3992         }
3993
3994         mono_loader_unlock ();
3995
3996         if (type_load)
3997                 emit_type_load (klass, klass, NULL);
3998 }
3999
4000 /*
4001  * Emit load events for all types currently loaded in the domain.
4002  * Takes the loader and domain locks.
4003  * user_data is unused.
4004  */
4005 static void
4006 send_types_for_domain (MonoDomain *domain, void *user_data)
4007 {
4008         AgentDomainInfo *info = NULL;
4009
4010         info = get_agent_domain_info (domain);
4011         g_assert (info);
4012         
4013         mono_loader_lock ();
4014         g_hash_table_foreach (info->loaded_classes, emit_type_load, NULL);
4015         mono_loader_unlock ();
4016 }
4017
4018 static void
4019 jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result)
4020 {
4021         /*
4022          * We emit type load events when the first method of the type is JITted,
4023          * since the class load profiler callbacks might be called with the
4024          * loader lock held. They could also occur in the debugger thread.
4025          * Same for assembly load events.
4026          */
4027         while (TRUE) {
4028                 MonoAssembly *assembly = NULL;
4029
4030                 // FIXME: Maybe store this in TLS so the thread of the event is correct ?
4031                 dbg_lock ();
4032                 if (pending_assembly_loads->len > 0) {
4033                         assembly = g_ptr_array_index (pending_assembly_loads, 0);
4034                         g_ptr_array_remove_index (pending_assembly_loads, 0);
4035                 }
4036                 dbg_unlock ();
4037
4038                 if (assembly) {
4039                         process_profiler_event (EVENT_KIND_ASSEMBLY_LOAD, assembly);
4040                 } else {
4041                         break;
4042                 }
4043         }
4044
4045         send_type_load (method->klass);
4046
4047         if (!result)
4048                 add_pending_breakpoints (method, jinfo);
4049 }
4050
4051 /*
4052  * BREAKPOINTS/SINGLE STEPPING
4053  */
4054
4055 /* 
4056  * Contains information about an inserted breakpoint.
4057  */
4058 typedef struct {
4059         long il_offset, native_offset;
4060         guint8 *ip;
4061         MonoJitInfo *ji;
4062         MonoDomain *domain;
4063 } BreakpointInstance;
4064
4065 /*
4066  * Contains generic information about a breakpoint.
4067  */
4068 typedef struct {
4069         /* 
4070          * The method where the breakpoint is placed. Can be NULL in which case it 
4071          * is inserted into every method. This is used to implement method entry/
4072          * exit events. Can be a generic method definition, in which case the
4073          * breakpoint is inserted into every instance.
4074          */
4075         MonoMethod *method;
4076         long il_offset;
4077         EventRequest *req;
4078         /* 
4079          * A list of BreakpointInstance structures describing where the breakpoint
4080          * was inserted. There could be more than one because of 
4081          * generics/appdomains/method entry/exit.
4082          */
4083         GPtrArray *children;
4084 } MonoBreakpoint;
4085
4086 /* List of breakpoints */
4087 /* Protected by the loader lock */
4088 static GPtrArray *breakpoints;
4089 /* Maps breakpoint locations to the number of breakpoints at that location */
4090 static GHashTable *bp_locs;
4091
4092 static void
4093 breakpoints_init (void)
4094 {
4095         breakpoints = g_ptr_array_new ();
4096         bp_locs = g_hash_table_new (NULL, NULL);
4097 }       
4098
4099 /*
4100  * insert_breakpoint:
4101  *
4102  *   Insert the breakpoint described by BP into the method described by
4103  * JI.
4104  */
4105 static void
4106 insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo *ji, MonoBreakpoint *bp, MonoError *error)
4107 {
4108         int count;
4109         BreakpointInstance *inst;
4110         SeqPointIterator it;
4111         gboolean it_has_sp = FALSE;
4112
4113         if (error)
4114                 mono_error_init (error);
4115
4116         mono_seq_point_iterator_init (&it, seq_points);
4117         while (mono_seq_point_iterator_next (&it)) {
4118                 if (it.seq_point.il_offset == bp->il_offset) {
4119                         it_has_sp = TRUE;
4120                         break;
4121                 }
4122         }
4123
4124         if (!it_has_sp) {
4125                 /*
4126                  * The set of IL offsets with seq points doesn't completely match the
4127                  * info returned by CMD_METHOD_GET_DEBUG_INFO (#407).
4128                  */
4129                 mono_seq_point_iterator_init (&it, seq_points);
4130                 while (mono_seq_point_iterator_next (&it)) {
4131                         if (it.seq_point.il_offset != METHOD_ENTRY_IL_OFFSET &&
4132                                 it.seq_point.il_offset != METHOD_EXIT_IL_OFFSET &&
4133                                 it.seq_point.il_offset + 1 == bp->il_offset) {
4134                                 it_has_sp = TRUE;
4135                                 break;
4136                         }
4137                 }
4138         }
4139
4140         if (!it_has_sp) {
4141                 char *s = g_strdup_printf ("Unable to insert breakpoint at %s:%d", mono_method_full_name (jinfo_get_method (ji), TRUE), bp->il_offset);
4142
4143                 mono_seq_point_iterator_init (&it, seq_points);
4144                 while (mono_seq_point_iterator_next (&it))
4145                         DEBUG_PRINTF (1, "%d\n", it.seq_point.il_offset);
4146
4147                 if (error) {
4148                         mono_error_set_error (error, MONO_ERROR_GENERIC, "%s", s);
4149                         g_warning ("%s", s);
4150                         g_free (s);
4151                         return;
4152                 } else {
4153                         g_warning ("%s", s);
4154                         g_free (s);
4155                         return;
4156                 }
4157         }
4158
4159         inst = g_new0 (BreakpointInstance, 1);
4160         inst->il_offset = it.seq_point.il_offset;
4161         inst->native_offset = it.seq_point.native_offset;
4162         inst->ip = (guint8*)ji->code_start + it.seq_point.native_offset;
4163         inst->ji = ji;
4164         inst->domain = domain;
4165
4166         mono_loader_lock ();
4167
4168         g_ptr_array_add (bp->children, inst);
4169
4170         mono_loader_unlock ();
4171
4172         dbg_lock ();
4173         count = GPOINTER_TO_INT (g_hash_table_lookup (bp_locs, inst->ip));
4174         g_hash_table_insert (bp_locs, inst->ip, GINT_TO_POINTER (count + 1));
4175         dbg_unlock ();
4176
4177         if (it.seq_point.native_offset == SEQ_POINT_NATIVE_OFFSET_DEAD_CODE) {
4178                 DEBUG_PRINTF (1, "[dbg] Attempting to insert seq point at dead IL offset %d, ignoring.\n", (int)bp->il_offset);
4179         } else if (count == 0) {
4180 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
4181                 mono_arch_set_breakpoint (ji, inst->ip);
4182 #else
4183                 NOT_IMPLEMENTED;
4184 #endif
4185         }
4186
4187         DEBUG_PRINTF (1, "[dbg] Inserted breakpoint at %s:[il=0x%x,native=0x%x] [%p](%d).\n", mono_method_full_name (jinfo_get_method (ji), TRUE), (int)it.seq_point.il_offset, (int)it.seq_point.native_offset, inst->ip, count);
4188 }
4189
4190 static void
4191 remove_breakpoint (BreakpointInstance *inst)
4192 {
4193 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
4194         int count;
4195         MonoJitInfo *ji = inst->ji;
4196         guint8 *ip = inst->ip;
4197
4198         dbg_lock ();
4199         count = GPOINTER_TO_INT (g_hash_table_lookup (bp_locs, ip));
4200         g_hash_table_insert (bp_locs, ip, GINT_TO_POINTER (count - 1));
4201         dbg_unlock ();
4202
4203         g_assert (count > 0);
4204
4205         if (count == 1 && inst->native_offset != SEQ_POINT_NATIVE_OFFSET_DEAD_CODE) {
4206                 mono_arch_clear_breakpoint (ji, ip);
4207                 DEBUG_PRINTF (1, "[dbg] Clear breakpoint at %s [%p].\n", mono_method_full_name (jinfo_get_method (ji), TRUE), ip);
4208         }
4209 #else
4210         NOT_IMPLEMENTED;
4211 #endif
4212 }       
4213
4214 /*
4215  * This doesn't take any locks.
4216  */
4217 static inline gboolean
4218 bp_matches_method (MonoBreakpoint *bp, MonoMethod *method)
4219 {
4220         int i;
4221
4222         if (!bp->method)
4223                 return TRUE;
4224         if (method == bp->method)
4225                 return TRUE;
4226         if (method->is_inflated && ((MonoMethodInflated*)method)->declaring == bp->method)
4227                 return TRUE;
4228
4229         if (bp->method->is_inflated && method->is_inflated) {
4230                 MonoMethodInflated *bpimethod = (MonoMethodInflated*)bp->method;
4231                 MonoMethodInflated *imethod = (MonoMethodInflated*)method;
4232
4233                 /* Open generic methods should match closed generic methods of the same class */
4234                 if (bpimethod->declaring == imethod->declaring && bpimethod->context.class_inst == imethod->context.class_inst && bpimethod->context.method_inst && bpimethod->context.method_inst->is_open) {
4235                         for (i = 0; i < bpimethod->context.method_inst->type_argc; ++i) {
4236                                 MonoType *t1 = bpimethod->context.method_inst->type_argv [i];
4237
4238                                 /* FIXME: Handle !mvar */
4239                                 if (t1->type != MONO_TYPE_MVAR)
4240                                         return FALSE;
4241                         }
4242                         return TRUE;
4243                 }
4244         }
4245
4246         return FALSE;
4247 }
4248
4249 /*
4250  * add_pending_breakpoints:
4251  *
4252  *   Insert pending breakpoints into the newly JITted method METHOD.
4253  */
4254 static void
4255 add_pending_breakpoints (MonoMethod *method, MonoJitInfo *ji)
4256 {
4257         int i, j;
4258         MonoSeqPointInfo *seq_points;
4259         MonoDomain *domain;
4260         MonoMethod *jmethod;
4261
4262         if (!breakpoints)
4263                 return;
4264
4265         domain = mono_domain_get ();
4266
4267         mono_loader_lock ();
4268
4269         for (i = 0; i < breakpoints->len; ++i) {
4270                 MonoBreakpoint *bp = g_ptr_array_index (breakpoints, i);
4271                 gboolean found = FALSE;
4272
4273                 if (!bp_matches_method (bp, method))
4274                         continue;
4275
4276                 for (j = 0; j < bp->children->len; ++j) {
4277                         BreakpointInstance *inst = g_ptr_array_index (bp->children, j);
4278
4279                         if (inst->ji == ji)
4280                                 found = TRUE;
4281                 }
4282
4283                 if (!found) {
4284                         MonoMethod *declaring = NULL;
4285
4286                         jmethod = jinfo_get_method (ji);
4287                         if (jmethod->is_inflated)
4288                                 declaring = mono_method_get_declaring_generic_method (jmethod);
4289
4290                         mono_domain_lock (domain);
4291                         seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, jmethod);
4292                         if (!seq_points && declaring)
4293                                 seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, declaring);
4294                         mono_domain_unlock (domain);
4295                         if (!seq_points)
4296                                 /* Could be AOT code */
4297                                 continue;
4298                         g_assert (seq_points);
4299
4300                         insert_breakpoint (seq_points, domain, ji, bp, NULL);
4301                 }
4302         }
4303
4304         mono_loader_unlock ();
4305 }
4306
4307 static void
4308 set_bp_in_method (MonoDomain *domain, MonoMethod *method, MonoSeqPointInfo *seq_points, MonoBreakpoint *bp, MonoError *error)
4309 {
4310         gpointer code;
4311         MonoJitInfo *ji;
4312
4313         if (error)
4314                 mono_error_init (error);
4315
4316         code = mono_jit_find_compiled_method_with_jit_info (domain, method, &ji);
4317         if (!code) {
4318                 /* Might be AOTed code */
4319                 code = mono_aot_get_method (domain, method);
4320                 g_assert (code);
4321                 ji = mono_jit_info_table_find (domain, code);
4322                 g_assert (ji);
4323         }
4324         g_assert (code);
4325
4326         insert_breakpoint (seq_points, domain, ji, bp, error);
4327 }
4328
4329 static void
4330 clear_breakpoint (MonoBreakpoint *bp);
4331
4332 /*
4333  * set_breakpoint:
4334  *
4335  *   Set a breakpoint at IL_OFFSET in METHOD.
4336  * METHOD can be NULL, in which case a breakpoint is placed in all methods.
4337  * METHOD can also be a generic method definition, in which case a breakpoint
4338  * is placed in all instances of the method.
4339  * If ERROR is non-NULL, then it is set and NULL is returnd if some breakpoints couldn't be
4340  * inserted.
4341  */
4342 static MonoBreakpoint*
4343 set_breakpoint (MonoMethod *method, long il_offset, EventRequest *req, MonoError *error)
4344 {
4345         MonoBreakpoint *bp;
4346         GHashTableIter iter, iter2;
4347         MonoDomain *domain;
4348         MonoMethod *m;
4349         MonoSeqPointInfo *seq_points;
4350         GPtrArray *methods;
4351         GPtrArray *method_domains;
4352         GPtrArray *method_seq_points;
4353         int i;
4354
4355         if (error)
4356                 mono_error_init (error);
4357
4358         // FIXME:
4359         // - suspend/resume the vm to prevent code patching problems
4360         // - multiple breakpoints on the same location
4361         // - dynamic methods
4362         // - races
4363
4364         bp = g_new0 (MonoBreakpoint, 1);
4365         bp->method = method;
4366         bp->il_offset = il_offset;
4367         bp->req = req;
4368         bp->children = g_ptr_array_new ();
4369
4370         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) : "<all>", (int)il_offset);
4371
4372         methods = g_ptr_array_new ();
4373         method_domains = g_ptr_array_new ();
4374         method_seq_points = g_ptr_array_new ();
4375
4376         mono_loader_lock ();
4377         g_hash_table_iter_init (&iter, domains);
4378         while (g_hash_table_iter_next (&iter, (void**)&domain, NULL)) {
4379                 mono_domain_lock (domain);
4380                 g_hash_table_iter_init (&iter2, domain_jit_info (domain)->seq_points);
4381                 while (g_hash_table_iter_next (&iter2, (void**)&m, (void**)&seq_points)) {
4382                         if (bp_matches_method (bp, m)) {
4383                                 /* Save the info locally to simplify the code inside the domain lock */
4384                                 g_ptr_array_add (methods, m);
4385                                 g_ptr_array_add (method_domains, domain);
4386                                 g_ptr_array_add (method_seq_points, seq_points);
4387                         }
4388                 }
4389                 mono_domain_unlock (domain);
4390         }
4391
4392         for (i = 0; i < methods->len; ++i) {
4393                 m = g_ptr_array_index (methods, i);
4394                 domain = g_ptr_array_index (method_domains, i);
4395                 seq_points = g_ptr_array_index (method_seq_points, i);
4396                 set_bp_in_method (domain, m, seq_points, bp, error);
4397         }
4398
4399         g_ptr_array_add (breakpoints, bp);
4400         mono_loader_unlock ();
4401
4402         g_ptr_array_free (methods, TRUE);
4403         g_ptr_array_free (method_domains, TRUE);
4404         g_ptr_array_free (method_seq_points, TRUE);
4405
4406         if (error && !mono_error_ok (error)) {
4407                 clear_breakpoint (bp);
4408                 return NULL;
4409         }
4410
4411         return bp;
4412 }
4413
4414 static void
4415 clear_breakpoint (MonoBreakpoint *bp)
4416 {
4417         int i;
4418
4419         // FIXME: locking, races
4420         for (i = 0; i < bp->children->len; ++i) {
4421                 BreakpointInstance *inst = g_ptr_array_index (bp->children, i);
4422
4423                 remove_breakpoint (inst);
4424
4425                 g_free (inst);
4426         }
4427
4428         mono_loader_lock ();
4429         g_ptr_array_remove (breakpoints, bp);
4430         mono_loader_unlock ();
4431
4432         g_ptr_array_free (bp->children, TRUE);
4433         g_free (bp);
4434 }
4435
4436 static void
4437 breakpoints_cleanup (void)
4438 {
4439         int i;
4440
4441         mono_loader_lock ();
4442         i = 0;
4443         while (i < event_requests->len) {
4444                 EventRequest *req = g_ptr_array_index (event_requests, i);
4445
4446                 if (req->event_kind == EVENT_KIND_BREAKPOINT) {
4447                         clear_breakpoint (req->info);
4448                         g_ptr_array_remove_index_fast (event_requests, i);
4449                         g_free (req);
4450                 } else {
4451                         i ++;
4452                 }
4453         }
4454
4455         for (i = 0; i < breakpoints->len; ++i)
4456                 g_free (g_ptr_array_index (breakpoints, i));
4457
4458         g_ptr_array_free (breakpoints, TRUE);
4459         g_hash_table_destroy (bp_locs);
4460
4461         breakpoints = NULL;
4462         bp_locs = NULL;
4463
4464         mono_loader_unlock ();
4465 }
4466
4467 /*
4468  * clear_breakpoints_for_domain:
4469  *
4470  *   Clear breakpoint instances which reference DOMAIN.
4471  */
4472 static void
4473 clear_breakpoints_for_domain (MonoDomain *domain)
4474 {
4475         int i, j;
4476
4477         /* This could be called after shutdown */
4478         if (!breakpoints)
4479                 return;
4480
4481         mono_loader_lock ();
4482         for (i = 0; i < breakpoints->len; ++i) {
4483                 MonoBreakpoint *bp = g_ptr_array_index (breakpoints, i);
4484
4485                 j = 0;
4486                 while (j < bp->children->len) {
4487                         BreakpointInstance *inst = g_ptr_array_index (bp->children, j);
4488
4489                         if (inst->domain == domain) {
4490                                 remove_breakpoint (inst);
4491
4492                                 g_free (inst);
4493
4494                                 g_ptr_array_remove_index_fast (bp->children, j);
4495                         } else {
4496                                 j ++;
4497                         }
4498                 }
4499         }
4500         mono_loader_unlock ();
4501 }
4502
4503 /*
4504  * ss_update:
4505  *
4506  * Return FALSE if single stepping needs to continue.
4507  */
4508 static gboolean
4509 ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, DebuggerTlsData *tls, MonoContext *ctx)
4510 {
4511         MonoDebugMethodInfo *minfo;
4512         MonoDebugSourceLocation *loc = NULL;
4513         gboolean hit = TRUE;
4514         MonoMethod *method;
4515
4516         if (req->depth == STEP_DEPTH_OVER && (sp->flags & MONO_SEQ_POINT_FLAG_NONEMPTY_STACK)) {
4517                 /*
4518                  * These seq points are inserted by the JIT after calls, step over needs to skip them.
4519                  */
4520                 DEBUG_PRINTF (1, "[%p] Seq point at nonempty stack %x while stepping over, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset);
4521                 return FALSE;
4522         }
4523
4524         if (req->depth == STEP_DEPTH_OVER && hit) {
4525                 if (!tls->context.valid)
4526                         mono_thread_state_init_from_monoctx (&tls->context, ctx);
4527                 compute_frame_info (tls->thread, tls);
4528                 if (req->nframes && tls->frame_count && tls->frame_count > req->nframes) {
4529                         /* Hit the breakpoint in a recursive call */
4530                         DEBUG_PRINTF (1, "[%p] Breakpoint at lower frame while stepping over, continuing single stepping.\n", (gpointer)GetCurrentThreadId ());
4531                         return FALSE;
4532                 }
4533         }
4534
4535         if (req->depth == STEP_DEPTH_INTO && req->size == STEP_SIZE_MIN && (sp->flags & MONO_SEQ_POINT_FLAG_NONEMPTY_STACK) && ss_req->start_method){
4536                 method = jinfo_get_method (ji);
4537                 if (!tls->context.valid)
4538                         mono_thread_state_init_from_monoctx (&tls->context, ctx);
4539                 compute_frame_info (tls->thread, tls);
4540                 if (ss_req->start_method == method && req->nframes && tls->frame_count == req->nframes) {//Check also frame count(could be recursion)
4541                         DEBUG_PRINTF (1, "[%p] Seq point at nonempty stack %x while stepping in, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset);
4542                         return FALSE;
4543                 }
4544         }
4545
4546         if (req->size != STEP_SIZE_LINE)
4547                 return TRUE;
4548
4549         /* Have to check whenever a different source line was reached */
4550         method = jinfo_get_method (ji);
4551         minfo = mono_debug_lookup_method (method);
4552
4553         if (minfo)
4554                 loc = mono_debug_symfile_lookup_location (minfo, sp->il_offset);
4555
4556         if (!loc) {
4557                 DEBUG_PRINTF (1, "[%p] No line number info for il offset %x, continuing single stepping.\n", (gpointer)GetCurrentThreadId (), sp->il_offset);
4558                 ss_req->last_method = method;
4559                 hit = FALSE;
4560         } else if (loc && method == ss_req->last_method && loc->row == ss_req->last_line) {
4561                 DEBUG_PRINTF (1, "[%p] Same source line (%d), continuing single stepping.\n", (gpointer)GetCurrentThreadId (), loc->row);
4562                 hit = FALSE;
4563         }
4564                                 
4565         if (loc) {
4566                 ss_req->last_method = method;
4567                 ss_req->last_line = loc->row;
4568                 mono_debug_free_source_location (loc);
4569         }
4570
4571         return hit;
4572 }
4573
4574 static gboolean
4575 breakpoint_matches_assembly (MonoBreakpoint *bp, MonoAssembly *assembly)
4576 {
4577         return bp->method && bp->method->klass->image->assembly == assembly;
4578 }
4579
4580 static void
4581 process_breakpoint_inner (DebuggerTlsData *tls, gboolean from_signal)
4582 {
4583         MonoJitInfo *ji;
4584         guint8 *ip;
4585         int i, j, suspend_policy;
4586         guint32 native_offset;
4587         MonoBreakpoint *bp;
4588         BreakpointInstance *inst;
4589         GPtrArray *bp_reqs, *ss_reqs_orig, *ss_reqs;
4590         GSList *bp_events = NULL, *ss_events = NULL, *enter_leave_events = NULL;
4591         EventKind kind = EVENT_KIND_BREAKPOINT;
4592         MonoContext *ctx = &tls->restore_state.ctx;
4593         MonoMethod *method;
4594         MonoSeqPointInfo *info;
4595         SeqPoint sp;
4596         gboolean found_sp;
4597
4598         // FIXME: Speed this up
4599
4600         ip = MONO_CONTEXT_GET_IP (ctx);
4601         ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, NULL);
4602         g_assert (ji && !ji->is_trampoline);
4603         method = jinfo_get_method (ji);
4604
4605         /* Compute the native offset of the breakpoint from the ip */
4606         native_offset = ip - (guint8*)ji->code_start;   
4607
4608         /* 
4609          * Skip the instruction causing the breakpoint signal.
4610          */
4611         if (from_signal)
4612                 mono_arch_skip_breakpoint (ctx, ji);
4613
4614         if (method->wrapper_type || tls->disable_breakpoints)
4615                 return;
4616
4617         bp_reqs = g_ptr_array_new ();
4618         ss_reqs = g_ptr_array_new ();
4619         ss_reqs_orig = g_ptr_array_new ();
4620
4621         mono_loader_lock ();
4622
4623         /*
4624          * The ip points to the instruction causing the breakpoint event, which is after
4625          * the offset recorded in the seq point map, so find the prev seq point before ip.
4626          */
4627         found_sp = mono_find_prev_seq_point_for_native_offset (mono_domain_get (), method, native_offset, &info, &sp);
4628
4629         if (!found_sp)
4630                 no_seq_points_found (method);
4631
4632         g_assert (found_sp);
4633
4634         DEBUG_PRINTF (1, "[%p] Breakpoint hit, method=%s, ip=%p, [il=0x%x,native=0x%x].\n", (gpointer)GetCurrentThreadId (), method->name, ip, sp.il_offset, native_offset);
4635
4636         bp = NULL;
4637         for (i = 0; i < breakpoints->len; ++i) {
4638                 bp = g_ptr_array_index (breakpoints, i);
4639
4640                 if (!bp->method)
4641                         continue;
4642
4643                 for (j = 0; j < bp->children->len; ++j) {
4644                         inst = g_ptr_array_index (bp->children, j);
4645                         if (inst->ji == ji && inst->il_offset == sp.il_offset && inst->native_offset == sp.native_offset) {
4646                                 if (bp->req->event_kind == EVENT_KIND_STEP) {
4647                                         g_ptr_array_add (ss_reqs_orig, bp->req);
4648                                 } else {
4649                                         g_ptr_array_add (bp_reqs, bp->req);
4650                                 }
4651                         }
4652                 }
4653         }
4654         if (bp_reqs->len == 0 && ss_reqs_orig->len == 0) {
4655                 /* Maybe a method entry/exit event */
4656                 if (sp.il_offset == METHOD_ENTRY_IL_OFFSET)
4657                         kind = EVENT_KIND_METHOD_ENTRY;
4658                 else if (sp.il_offset == METHOD_EXIT_IL_OFFSET)
4659                         kind = EVENT_KIND_METHOD_EXIT;
4660         }
4661
4662         /* Process single step requests */
4663         for (i = 0; i < ss_reqs_orig->len; ++i) {
4664                 EventRequest *req = g_ptr_array_index (ss_reqs_orig, i);
4665                 SingleStepReq *ss_req = req->info;
4666                 gboolean hit;
4667
4668                 if (mono_thread_internal_current () != ss_req->thread)
4669                         continue;
4670
4671                 hit = ss_update (ss_req, ji, &sp, tls, ctx);
4672                 if (hit)
4673                         g_ptr_array_add (ss_reqs, req);
4674
4675                 /* Start single stepping again from the current sequence point */
4676                 ss_start (ss_req, method, &sp, info, ctx, tls, FALSE, NULL, 0);
4677         }
4678         
4679         if (ss_reqs->len > 0)
4680                 ss_events = create_event_list (EVENT_KIND_STEP, ss_reqs, ji, NULL, &suspend_policy);
4681         if (bp_reqs->len > 0)
4682                 bp_events = create_event_list (EVENT_KIND_BREAKPOINT, bp_reqs, ji, NULL, &suspend_policy);
4683         if (kind != EVENT_KIND_BREAKPOINT)
4684                 enter_leave_events = create_event_list (kind, NULL, ji, NULL, &suspend_policy);
4685
4686         mono_loader_unlock ();
4687
4688         g_ptr_array_free (bp_reqs, TRUE);
4689         g_ptr_array_free (ss_reqs, TRUE);
4690
4691         /* 
4692          * FIXME: The first event will suspend, so the second will only be sent after the
4693          * resume.
4694          */
4695         if (ss_events)
4696                 process_event (EVENT_KIND_STEP, method, 0, ctx, ss_events, suspend_policy);
4697         if (bp_events)
4698                 process_event (kind, method, 0, ctx, bp_events, suspend_policy);
4699         if (enter_leave_events)
4700                 process_event (kind, method, 0, ctx, enter_leave_events, suspend_policy);
4701 }
4702
4703 /* Process a breakpoint/single step event after resuming from a signal handler */
4704 static void
4705 process_signal_event (void (*func) (DebuggerTlsData*, gboolean))
4706 {
4707         DebuggerTlsData *tls;
4708         MonoThreadUnwindState orig_restore_state;
4709         MonoContext ctx;
4710
4711         tls = mono_native_tls_get_value (debugger_tls_id);
4712         /* Have to save/restore the restore_ctx as we can be called recursively during invokes etc. */
4713         memcpy (&orig_restore_state, &tls->restore_state, sizeof (MonoThreadUnwindState));
4714         mono_thread_state_init_from_monoctx (&tls->restore_state, &tls->handler_ctx);
4715
4716         func (tls, TRUE);
4717
4718         /* This is called when resuming from a signal handler, so it shouldn't return */
4719         memcpy (&ctx, &tls->restore_state.ctx, sizeof (MonoContext));
4720         memcpy (&tls->restore_state, &orig_restore_state, sizeof (MonoThreadUnwindState));
4721         mono_restore_context (&ctx);
4722         g_assert_not_reached ();
4723 }
4724
4725 static void
4726 process_breakpoint (void)
4727 {
4728         process_signal_event (process_breakpoint_inner);
4729 }
4730
4731 static void
4732 resume_from_signal_handler (void *sigctx, void *func)
4733 {
4734         DebuggerTlsData *tls;
4735         MonoContext ctx;
4736
4737         /* Save the original context in TLS */
4738         // FIXME: This might not work on an altstack ?
4739         tls = mono_native_tls_get_value (debugger_tls_id);
4740         if (!tls)
4741                 fprintf (stderr, "Thread %p is not attached to the JIT.\n", (gpointer)GetCurrentThreadId ());
4742         g_assert (tls);
4743
4744         // FIXME: MonoContext usually doesn't include the fp registers, so these are 
4745         // clobbered by a single step/breakpoint event. If this turns out to be a problem,
4746         // clob:c could be added to op_seq_point.
4747
4748         mono_sigctx_to_monoctx (sigctx, &ctx);
4749         memcpy (&tls->handler_ctx, &ctx, sizeof (MonoContext));
4750 #ifdef MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX
4751         mono_arch_setup_resume_sighandler_ctx (&ctx, func);
4752 #else
4753         MONO_CONTEXT_SET_IP (&ctx, func);
4754 #endif
4755         mono_monoctx_to_sigctx (&ctx, sigctx);
4756
4757 #ifdef PPC_USES_FUNCTION_DESCRIPTOR
4758         mono_ppc_set_func_into_sigctx (sigctx, func);
4759 #endif
4760 }
4761
4762 void
4763 mono_debugger_agent_breakpoint_hit (void *sigctx)
4764 {
4765         /*
4766          * We are called from a signal handler, and running code there causes all kinds of
4767          * problems, like the original signal is disabled, libgc can't handle altstack, etc.
4768          * So set up the signal context to return to the real breakpoint handler function.
4769          */
4770         resume_from_signal_handler (sigctx, process_breakpoint);
4771 }
4772
4773 static gboolean
4774 user_break_cb (StackFrameInfo *frame, MonoContext *ctx, gpointer data)
4775 {
4776         if (frame->managed) {
4777                 *(MonoContext*)data = *ctx;
4778
4779                 return TRUE;
4780         } else {
4781                 return FALSE;
4782         }
4783 }
4784
4785 /*
4786  * Called by System.Diagnostics.Debugger:Break ().
4787  */
4788 void
4789 mono_debugger_agent_user_break (void)
4790 {
4791         if (agent_config.enabled) {
4792                 MonoContext ctx;
4793                 int suspend_policy;
4794                 GSList *events;
4795
4796                 /* Obtain a context */
4797                 MONO_CONTEXT_SET_IP (&ctx, NULL);
4798                 mono_walk_stack_with_ctx (user_break_cb, NULL, 0, &ctx);
4799                 g_assert (MONO_CONTEXT_GET_IP (&ctx) != NULL);
4800
4801                 mono_loader_lock ();
4802                 events = create_event_list (EVENT_KIND_USER_BREAK, NULL, NULL, NULL, &suspend_policy);
4803                 mono_loader_unlock ();
4804
4805                 process_event (EVENT_KIND_USER_BREAK, NULL, 0, &ctx, events, suspend_policy);
4806         } else {
4807                 G_BREAKPOINT ();
4808         }
4809 }
4810
4811 static const char*
4812 ss_depth_to_string (StepDepth depth)
4813 {
4814         switch (depth) {
4815         case STEP_DEPTH_OVER:
4816                 return "over";
4817         case STEP_DEPTH_OUT:
4818                 return "out";
4819         case STEP_DEPTH_INTO:
4820                 return "into";
4821         default:
4822                 g_assert_not_reached ();
4823                 return NULL;
4824         }
4825 }
4826
4827 static void
4828 process_single_step_inner (DebuggerTlsData *tls, gboolean from_signal)
4829 {
4830         MonoJitInfo *ji;
4831         guint8 *ip;
4832         GPtrArray *reqs;
4833         int il_offset, suspend_policy;
4834         MonoDomain *domain;
4835         GSList *events;
4836         MonoContext *ctx = &tls->restore_state.ctx;
4837         MonoMethod *method;
4838         SeqPoint sp;
4839         MonoSeqPointInfo *info;
4840
4841         ip = MONO_CONTEXT_GET_IP (ctx);
4842
4843         /* Skip the instruction causing the single step */
4844         if (from_signal)
4845                 mono_arch_skip_single_step (ctx);
4846
4847         if (suspend_count > 0) {
4848                 process_suspend (tls, ctx);
4849                 return;
4850         }
4851
4852         if (!ss_req)
4853                 // FIXME: A suspend race
4854                 return;
4855
4856         if (mono_thread_internal_current () != ss_req->thread)
4857                 return;
4858
4859         if (log_level > 0) {
4860                 ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, &domain);
4861
4862                 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);
4863         }
4864
4865         ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, &domain);
4866         g_assert (ji && !ji->is_trampoline);
4867         method = jinfo_get_method (ji);
4868         g_assert (method);
4869
4870         if (method->wrapper_type && method->wrapper_type != MONO_WRAPPER_DYNAMIC_METHOD)
4871                 return;
4872
4873         /* 
4874          * FIXME:
4875          * Stopping in memset makes half-initialized vtypes visible.
4876          * Stopping in memcpy makes half-copied vtypes visible.
4877          */
4878         if (method->klass == mono_defaults.string_class && (!strcmp (method->name, "memset") || strstr (method->name, "memcpy")))
4879                 return;
4880
4881         /*
4882          * The ip points to the instruction causing the single step event, which is before
4883          * the offset recorded in the seq point map, so find the next seq point after ip.
4884          */
4885         if (!mono_find_next_seq_point_for_native_offset (domain, method, (guint8*)ip - (guint8*)ji->code_start, &info, &sp))
4886                 return;
4887
4888         il_offset = sp.il_offset;
4889
4890         if (!ss_update (ss_req, ji, &sp, tls, ctx))
4891                 return;
4892
4893         /* Start single stepping again from the current sequence point */
4894         ss_start (ss_req, method, &sp, info, ctx, tls, FALSE, NULL, 0);
4895
4896         if ((ss_req->filter & STEP_FILTER_STATIC_CTOR) &&
4897                 (method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) &&
4898                 !strcmp (method->name, ".cctor"))
4899                 return;
4900
4901         // FIXME: Has to lock earlier
4902
4903         reqs = g_ptr_array_new ();
4904
4905         mono_loader_lock ();
4906
4907         g_ptr_array_add (reqs, ss_req->req);
4908
4909         events = create_event_list (EVENT_KIND_STEP, reqs, ji, NULL, &suspend_policy);
4910
4911         g_ptr_array_free (reqs, TRUE);
4912
4913         mono_loader_unlock ();
4914
4915         process_event (EVENT_KIND_STEP, jinfo_get_method (ji), il_offset, ctx, events, suspend_policy);
4916 }
4917
4918 static void
4919 process_single_step (void)
4920 {
4921         process_signal_event (process_single_step_inner);
4922 }
4923
4924 /*
4925  * mono_debugger_agent_single_step_event:
4926  *
4927  *   Called from a signal handler to handle a single step event.
4928  */
4929 void
4930 mono_debugger_agent_single_step_event (void *sigctx)
4931 {
4932         /* Resume to process_single_step through the signal context */
4933
4934         // FIXME: Since step out/over is implemented using step in, the step in case should
4935         // be as fast as possible. Move the relevant code from process_single_step_inner ()
4936         // here
4937
4938         if (GetCurrentThreadId () == debugger_thread_id) {
4939                 /* 
4940                  * This could happen despite our best effors when the runtime calls 
4941                  * assembly/type resolve hooks.
4942                  * FIXME: Breakpoints too.
4943                  */
4944                 MonoContext ctx;
4945
4946                 mono_sigctx_to_monoctx (sigctx, &ctx);
4947                 mono_arch_skip_single_step (&ctx);
4948                 mono_monoctx_to_sigctx (&ctx, sigctx);
4949                 return;
4950         }
4951
4952         resume_from_signal_handler (sigctx, process_single_step);
4953 }
4954
4955 void
4956 debugger_agent_single_step_from_context (MonoContext *ctx)
4957 {
4958         DebuggerTlsData *tls;
4959         MonoThreadUnwindState orig_restore_state;
4960
4961         if (GetCurrentThreadId () == debugger_thread_id)
4962                 return;
4963
4964         tls = mono_native_tls_get_value (debugger_tls_id);
4965         g_assert (tls);
4966
4967         /* Have to save/restore the restore_ctx as we can be called recursively during invokes etc. */
4968         memcpy (&orig_restore_state, &tls->restore_state, sizeof (MonoThreadUnwindState));
4969         mono_thread_state_init_from_monoctx (&tls->restore_state, ctx);
4970         memcpy (&tls->handler_ctx, ctx, sizeof (MonoContext));
4971
4972         process_single_step_inner (tls, FALSE);
4973
4974         memcpy (ctx, &tls->restore_state.ctx, sizeof (MonoContext));
4975         memcpy (&tls->restore_state, &orig_restore_state, sizeof (MonoThreadUnwindState));
4976 }
4977
4978 void
4979 debugger_agent_breakpoint_from_context (MonoContext *ctx)
4980 {
4981         DebuggerTlsData *tls;
4982         MonoThreadUnwindState orig_restore_state;
4983         guint8 *orig_ip;
4984
4985         if (GetCurrentThreadId () == debugger_thread_id)
4986                 return;
4987
4988         orig_ip = MONO_CONTEXT_GET_IP (ctx);
4989         MONO_CONTEXT_SET_IP (ctx, orig_ip - 1);
4990
4991         tls = mono_native_tls_get_value (debugger_tls_id);
4992         g_assert (tls);
4993         memcpy (&orig_restore_state, &tls->restore_state, sizeof (MonoThreadUnwindState));
4994         mono_thread_state_init_from_monoctx (&tls->restore_state, ctx);
4995         memcpy (&tls->handler_ctx, ctx, sizeof (MonoContext));
4996
4997         process_breakpoint_inner (tls, FALSE);
4998
4999         memcpy (ctx, &tls->restore_state.ctx, sizeof (MonoContext));
5000         memcpy (&tls->restore_state, &orig_restore_state, sizeof (MonoThreadUnwindState));
5001         if (MONO_CONTEXT_GET_IP (ctx) == orig_ip - 1)
5002                 MONO_CONTEXT_SET_IP (ctx, orig_ip);
5003 }
5004
5005 /*
5006  * start_single_stepping:
5007  *
5008  *   Turn on single stepping. Can be called multiple times, for example,
5009  * by a single step event request + a suspend.
5010  */
5011 static void
5012 start_single_stepping (void)
5013 {
5014 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
5015         int val = InterlockedIncrement (&ss_count);
5016
5017         if (val == 1)
5018                 mono_arch_start_single_stepping ();
5019 #else
5020         g_assert_not_reached ();
5021 #endif
5022 }
5023
5024 static void
5025 stop_single_stepping (void)
5026 {
5027 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
5028         int val = InterlockedDecrement (&ss_count);
5029
5030         if (val == 0)
5031                 mono_arch_stop_single_stepping ();
5032 #else
5033         g_assert_not_reached ();
5034 #endif
5035 }
5036
5037 /*
5038  * ss_stop:
5039  *
5040  *   Stop the single stepping operation given by SS_REQ.
5041  */
5042 static void
5043 ss_stop (SingleStepReq *ss_req)
5044 {
5045         if (ss_req->bps) {
5046                 GSList *l;
5047
5048                 for (l = ss_req->bps; l; l = l->next) {
5049                         clear_breakpoint (l->data);
5050                 }
5051                 g_slist_free (ss_req->bps);
5052                 ss_req->bps = NULL;
5053         }
5054
5055         if (ss_req->global) {
5056                 stop_single_stepping ();
5057                 ss_req->global = FALSE;
5058         }
5059 }
5060
5061 /*
5062  * ss_start:
5063  *
5064  *   Start the single stepping operation given by SS_REQ from the sequence point SP.
5065  * If CTX is not set, then this can target any thread. If CTX is set, then TLS should
5066  * belong to the same thread as CTX.
5067  * If FRAMES is not-null, use that instead of tls->frames for placing breakpoints etc.
5068  */
5069 static void
5070 ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointInfo *info, MonoContext *ctx, DebuggerTlsData *tls,
5071                   gboolean step_to_catch, StackFrame **frames, int nframes)
5072 {
5073         int i, j, frame_index;
5074         SeqPoint *next_sp, *parent_sp = NULL;
5075         SeqPoint local_sp, local_parent_sp;
5076         gboolean found_sp;
5077         MonoBreakpoint *bp;
5078         MonoSeqPointInfo *parent_info;
5079         MonoMethod *parent_sp_method = NULL;
5080         gboolean enable_global = FALSE;
5081
5082         /* Stop the previous operation */
5083         ss_stop (ss_req);
5084
5085         /*
5086          * Implement single stepping using breakpoints if possible.
5087          */
5088         if (step_to_catch) {
5089                 bp = set_breakpoint (method, sp->il_offset, ss_req->req, NULL);
5090                 ss_req->bps = g_slist_append (ss_req->bps, bp);
5091         } else {
5092                 frame_index = 1;
5093
5094                 if (ctx && !frames) {
5095                         /* Need parent frames */
5096                         if (!tls->context.valid)
5097                                 mono_thread_state_init_from_monoctx (&tls->context, ctx);
5098                         compute_frame_info (tls->thread, tls);
5099                         frames = tls->frames;
5100                         nframes = tls->frame_count;
5101                 }
5102
5103                 /*
5104                  * Find the first sequence point in the current or in a previous frame which
5105                  * is not the last in its method.
5106                  */
5107                 if (ss_req->depth == STEP_DEPTH_OUT) {
5108                         /* Ignore seq points in current method */
5109                         while (frame_index < nframes) {
5110                                 StackFrame *frame = frames [frame_index];
5111
5112                                 method = frame->method;
5113                                 found_sp = mono_find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp);
5114                                 sp = (found_sp)? &local_sp : NULL;
5115                                 frame_index ++;
5116                                 if (sp && sp->next_len != 0)
5117                                         break;
5118                         }
5119                         // There could be method calls before the next seq point in the caller when using nested calls
5120                         //enable_global = TRUE;
5121                 } else {
5122                         if (sp && sp->next_len == 0) {
5123                                 sp = NULL;
5124                                 while (frame_index < nframes) {
5125                                         StackFrame *frame = frames [frame_index];
5126
5127                                         method = frame->method;
5128                                         found_sp = mono_find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp);
5129                                         sp = (found_sp)? &local_sp : NULL;
5130                                         if (sp && sp->next_len != 0)
5131                                                 break;
5132                                         sp = NULL;
5133                                         frame_index ++;
5134                                 }
5135                         } else {
5136                                 /* Have to put a breakpoint into a parent frame since the seq points might not cover all control flow out of the method */
5137                                 while (frame_index < nframes) {
5138                                         StackFrame *frame = frames [frame_index];
5139
5140                                         parent_sp_method = frame->method;
5141                                         found_sp = mono_find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &parent_info, &local_parent_sp);
5142                                         parent_sp = found_sp ? &local_parent_sp : NULL;
5143                                         if (found_sp && parent_sp->next_len != 0)
5144                                                 break;
5145                                         parent_sp = NULL;
5146                                         frame_index ++;
5147                                 }
5148                         }
5149                 }
5150
5151                 if (sp && sp->next_len > 0) {
5152                         SeqPoint* next = g_new(SeqPoint, sp->next_len);
5153
5154                         mono_seq_point_init_next (info, *sp, next);
5155                         for (i = 0; i < sp->next_len; i++) {
5156                                 next_sp = &next[i];
5157
5158                                 bp = set_breakpoint (method, next_sp->il_offset, ss_req->req, NULL);
5159                                 ss_req->bps = g_slist_append (ss_req->bps, bp);
5160                         }
5161                         g_free (next);
5162                 }
5163
5164                 if (parent_sp) {
5165                         SeqPoint* next = g_new(SeqPoint, parent_sp->next_len);
5166
5167                         mono_seq_point_init_next (parent_info, *parent_sp, next);
5168                         for (i = 0; i < parent_sp->next_len; i++) {
5169                                 next_sp = &next[i];
5170
5171                                 bp = set_breakpoint (parent_sp_method, next_sp->il_offset, ss_req->req, NULL);
5172                                 ss_req->bps = g_slist_append (ss_req->bps, bp);
5173                         }
5174                         g_free (next);
5175                 }
5176
5177                 if (ss_req->nframes == 0)
5178                         ss_req->nframes = nframes;
5179
5180                 if ((ss_req->depth == STEP_DEPTH_OVER) && (!sp && !parent_sp)) {
5181                         DEBUG_PRINTF (1, "[dbg] No parent frame for step over, transition to step into.\n");
5182                         /*
5183                          * This is needed since if we leave managed code, and later return to it, step over
5184                          * is not going to stop.
5185                          * This approach is a bit ugly, since we change the step depth, but it only affects
5186                          * clients who reuse the same step request, and only in this special case.
5187                          */
5188                         ss_req->depth = STEP_DEPTH_INTO;
5189                 }
5190
5191                 if (ss_req->depth == STEP_DEPTH_OVER) {
5192                         /* Need to stop in catch clauses as well */
5193                         for (i = 0; i < nframes; ++i) {
5194                                 StackFrame *frame = frames [i];
5195
5196                                 if (frame->ji) {
5197                                         MonoJitInfo *jinfo = frame->ji;
5198                                         for (j = 0; j < jinfo->num_clauses; ++j) {
5199                                                 MonoJitExceptionInfo *ei = &jinfo->clauses [j];
5200
5201                                                 found_sp = mono_find_next_seq_point_for_native_offset (frame->domain, frame->method, (char*)ei->handler_start - (char*)jinfo->code_start, NULL, &local_sp);
5202                                                 sp = (found_sp)? &local_sp : NULL;
5203                                                 if (sp) {
5204                                                         bp = set_breakpoint (frame->method, sp->il_offset, ss_req->req, NULL);
5205                                                         ss_req->bps = g_slist_append (ss_req->bps, bp);
5206                                                 }
5207                                         }
5208                                 }
5209                         }
5210                 }
5211
5212                 if (ss_req->depth == STEP_DEPTH_INTO) {
5213                         /* Enable global stepping so we stop at method entry too */
5214                         enable_global = TRUE;
5215                 }
5216
5217                 /*
5218                  * The ctx/frame info computed above will become invalid when we continue.
5219                  */
5220                 tls->context.valid = FALSE;
5221                 tls->async_state.valid = FALSE;
5222                 invalidate_frames (tls);
5223         }
5224
5225         if (enable_global) {
5226                 DEBUG_PRINTF (1, "[dbg] Turning on global single stepping.\n");
5227                 ss_req->global = TRUE;
5228                 start_single_stepping ();
5229         } else if (!ss_req->bps) {
5230                 DEBUG_PRINTF (1, "[dbg] Turning on global single stepping.\n");
5231                 ss_req->global = TRUE;
5232                 start_single_stepping ();
5233         } else {
5234                 ss_req->global = FALSE;
5235         }
5236 }
5237
5238 /*
5239  * Start single stepping of thread THREAD
5240  */
5241 static ErrorCode
5242 ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilter filter, EventRequest *req)
5243 {
5244         DebuggerTlsData *tls;
5245         MonoSeqPointInfo *info = NULL;
5246         SeqPoint *sp = NULL;
5247         SeqPoint local_sp;
5248         gboolean found_sp;
5249         MonoMethod *method = NULL;
5250         MonoDebugMethodInfo *minfo;
5251         gboolean step_to_catch = FALSE;
5252         gboolean set_ip = FALSE;
5253         StackFrame **frames = NULL;
5254         int nframes = 0;
5255
5256         if (suspend_count == 0)
5257                 return ERR_NOT_SUSPENDED;
5258
5259         wait_for_suspend ();
5260
5261         // FIXME: Multiple requests
5262         if (ss_req) {
5263                 DEBUG_PRINTF (0, "Received a single step request while the previous one was still active.\n");
5264                 return ERR_NOT_IMPLEMENTED;
5265         }
5266
5267         DEBUG_PRINTF (1, "[dbg] Starting single step of thread %p (depth=%s).\n", thread, ss_depth_to_string (depth));
5268
5269         ss_req = g_new0 (SingleStepReq, 1);
5270         ss_req->req = req;
5271         ss_req->thread = thread;
5272         ss_req->size = size;
5273         ss_req->depth = depth;
5274         ss_req->filter = filter;
5275         req->info = ss_req;
5276
5277         mono_loader_lock ();
5278         tls = mono_g_hash_table_lookup (thread_to_tls, thread);
5279         mono_loader_unlock ();
5280         g_assert (tls);
5281         g_assert (tls->context.valid);
5282
5283         if (tls->restore_state.valid && MONO_CONTEXT_GET_IP (&tls->context.ctx) != MONO_CONTEXT_GET_IP (&tls->restore_state.ctx)) {
5284                 /*
5285                  * Need to start single stepping from restore_state and not from the current state
5286                  */
5287                 set_ip = TRUE;
5288                 frames = compute_frame_info_from (thread, tls, &tls->restore_state, &nframes);
5289         }
5290
5291         ss_req->start_sp = ss_req->last_sp = MONO_CONTEXT_GET_SP (&tls->context.ctx);
5292
5293         if (tls->catch_state.valid) {
5294                 gboolean res;
5295                 StackFrameInfo frame;
5296                 MonoContext new_ctx;
5297                 MonoLMF *lmf = NULL;
5298
5299                 /*
5300                  * We are stopped at a throw site. Stepping should go to the catch site.
5301                  */
5302
5303                 /* Find the the jit info for the catch context */
5304                 res = mono_find_jit_info_ext (tls->catch_state.unwind_data [MONO_UNWIND_DATA_DOMAIN], ((MonoThreadInfo*)thread->thread_info)->jit_data, NULL, &tls->catch_state.ctx, &new_ctx, NULL, &lmf, NULL, &frame);
5305                 g_assert (res);
5306                 g_assert (frame.type == FRAME_TYPE_MANAGED);
5307
5308                 /*
5309                  * Find the seq point corresponding to the landing site ip, which is the first seq
5310                  * point after ip.
5311                  */
5312                 found_sp = mono_find_next_seq_point_for_native_offset (frame.domain, frame.method, frame.native_offset, &info, &local_sp);
5313                 sp = (found_sp)? &local_sp : NULL;
5314                 if (!sp)
5315                         no_seq_points_found (frame.method);
5316                 g_assert (sp);
5317
5318                 method = frame.method;
5319
5320                 step_to_catch = TRUE;
5321                 /* This make sure the seq point is not skipped by process_single_step () */
5322                 ss_req->last_sp = NULL;
5323         }
5324
5325         if (!step_to_catch) {
5326                 StackFrame *frame = NULL;
5327
5328                 if (set_ip) {
5329                         if (frames && nframes)
5330                                 frame = frames [0];
5331                 } else {
5332                         compute_frame_info (thread, tls);
5333
5334                         if (tls->frame_count)
5335                                 frame = tls->frames [0];
5336                 }
5337
5338                 if (ss_req->size == STEP_SIZE_LINE) {
5339                         if (frame) {
5340                                 ss_req->last_method = frame->method;
5341                                 ss_req->last_line = -1;
5342
5343                                 minfo = mono_debug_lookup_method (frame->method);
5344                                 if (minfo && frame->il_offset != -1) {
5345                                         MonoDebugSourceLocation *loc = mono_debug_symfile_lookup_location (minfo, frame->il_offset);
5346
5347                                         if (loc) {
5348                                                 ss_req->last_line = loc->row;
5349                                                 g_free (loc);
5350                                         }
5351                                 }
5352                         }
5353                 }
5354
5355                 if (frame) {
5356                         if (!method && frame->il_offset != -1) {
5357                                 /* FIXME: Sort the table and use a binary search */
5358                                 found_sp = mono_find_prev_seq_point_for_native_offset (frame->domain, frame->method, frame->native_offset, &info, &local_sp);
5359                                 sp = (found_sp)? &local_sp : NULL;
5360                                 if (!sp)
5361                                         no_seq_points_found (frame->method);
5362                                 g_assert (sp);
5363                                 method = frame->method;
5364                         }
5365                 }
5366         }
5367
5368         ss_req->start_method = method;
5369
5370         ss_start (ss_req, method, sp, info, set_ip ? &tls->restore_state.ctx : &tls->context.ctx, tls, step_to_catch, frames, nframes);
5371
5372         if (frames)
5373                 free_frames (frames, nframes);
5374
5375         return 0;
5376 }
5377
5378 static void
5379 ss_destroy (SingleStepReq *req)
5380 {
5381         // FIXME: Locking
5382         g_assert (ss_req == req);
5383
5384         ss_stop (ss_req);
5385
5386         g_free (ss_req);
5387         ss_req = NULL;
5388 }
5389
5390 static void
5391 ss_clear_for_assembly (SingleStepReq *req, MonoAssembly *assembly)
5392 {
5393         GSList *l;
5394         gboolean found = TRUE;
5395
5396         while (found) {
5397                 found = FALSE;
5398                 for (l = ss_req->bps; l; l = l->next) {
5399                         if (breakpoint_matches_assembly (l->data, assembly)) {
5400                                 clear_breakpoint (l->data);
5401                                 ss_req->bps = g_slist_delete_link (ss_req->bps, l);
5402                                 found = TRUE;
5403                                 break;
5404                         }
5405                 }
5406         }
5407 }
5408
5409 /*
5410  * Called from metadata by the icall for System.Diagnostics.Debugger:Log ().
5411  */
5412 void
5413 mono_debugger_agent_debug_log (int level, MonoString *category, MonoString *message)
5414 {
5415         int suspend_policy;
5416         GSList *events;
5417         EventInfo ei;
5418
5419         if (!agent_config.enabled)
5420                 return;
5421
5422         mono_loader_lock ();
5423         events = create_event_list (EVENT_KIND_USER_LOG, NULL, NULL, NULL, &suspend_policy);
5424         mono_loader_unlock ();
5425
5426         ei.level = level;
5427         ei.category = category ? mono_string_to_utf8 (category) : NULL;
5428         ei.message = message ? mono_string_to_utf8 (message) : NULL;
5429
5430         process_event (EVENT_KIND_USER_LOG, &ei, 0, NULL, events, suspend_policy);
5431
5432         g_free (ei.category);
5433         g_free (ei.message);
5434 }
5435
5436 gboolean
5437 mono_debugger_agent_debug_log_is_enabled (void)
5438 {
5439         /* Treat this as true even if there is no event request for EVENT_KIND_USER_LOG */
5440         return agent_config.enabled;
5441 }
5442
5443 #if defined(PLATFORM_ANDROID) || defined(TARGET_ANDROID)
5444 void
5445 mono_debugger_agent_unhandled_exception (MonoException *exc)
5446 {
5447         int suspend_policy;
5448         GSList *events;
5449         EventInfo ei;
5450
5451         if (!inited)
5452                 return;
5453
5454         memset (&ei, 0, sizeof (EventInfo));
5455         ei.exc = (MonoObject*)exc;
5456
5457         mono_loader_lock ();
5458         events = create_event_list (EVENT_KIND_EXCEPTION, NULL, NULL, &ei, &suspend_policy);
5459         mono_loader_unlock ();
5460
5461         process_event (EVENT_KIND_EXCEPTION, &ei, 0, NULL, events, suspend_policy);
5462 }
5463 #endif
5464
5465 void
5466 mono_debugger_agent_handle_exception (MonoException *exc, MonoContext *throw_ctx, 
5467                                       MonoContext *catch_ctx)
5468 {
5469         int i, j, suspend_policy;
5470         GSList *events;
5471         MonoJitInfo *ji, *catch_ji;
5472         EventInfo ei;
5473         DebuggerTlsData *tls = NULL;
5474
5475         if (thread_to_tls != NULL) {
5476                 MonoInternalThread *thread = mono_thread_internal_current ();
5477
5478                 mono_loader_lock ();
5479                 tls = mono_g_hash_table_lookup (thread_to_tls, thread);
5480                 mono_loader_unlock ();
5481
5482                 if (tls && tls->abort_requested)
5483                         return;
5484                 if (tls && tls->disable_breakpoints)
5485                         return;
5486         }
5487
5488         memset (&ei, 0, sizeof (EventInfo));
5489
5490         /* Just-In-Time debugging */
5491         if (!catch_ctx) {
5492                 if (agent_config.onuncaught && !inited) {
5493                         finish_agent_init (FALSE);
5494
5495                         /*
5496                          * Send an unsolicited EXCEPTION event with a dummy request id.
5497                          */
5498                         events = g_slist_append (NULL, GUINT_TO_POINTER (0xffffff));
5499                         ei.exc = (MonoObject*)exc;
5500                         process_event (EVENT_KIND_EXCEPTION, &ei, 0, throw_ctx, events, SUSPEND_POLICY_ALL);
5501                         return;
5502                 }
5503         } else if (agent_config.onthrow && !inited) {
5504                 GSList *l;
5505                 gboolean found = FALSE;
5506
5507                 for (l = agent_config.onthrow; l; l = l->next) {
5508                         char *ex_type = l->data;
5509                         char *f = mono_type_full_name (&exc->object.vtable->klass->byval_arg);
5510
5511                         if (!strcmp (ex_type, "") || !strcmp (ex_type, f))
5512                                 found = TRUE;
5513
5514                         g_free (f);
5515                 }
5516
5517                 if (found) {
5518                         finish_agent_init (FALSE);
5519
5520                         /*
5521                          * Send an unsolicited EXCEPTION event with a dummy request id.
5522                          */
5523                         events = g_slist_append (NULL, GUINT_TO_POINTER (0xffffff));
5524                         ei.exc = (MonoObject*)exc;
5525                         process_event (EVENT_KIND_EXCEPTION, &ei, 0, throw_ctx, events, SUSPEND_POLICY_ALL);
5526                         return;
5527                 }
5528         }
5529
5530         if (!inited)
5531                 return;
5532
5533         ji = mini_jit_info_table_find (mono_domain_get (), MONO_CONTEXT_GET_IP (throw_ctx), NULL);
5534         if (catch_ctx)
5535                 catch_ji = mini_jit_info_table_find (mono_domain_get (), MONO_CONTEXT_GET_IP (catch_ctx), NULL);
5536         else
5537                 catch_ji = NULL;
5538
5539         ei.exc = (MonoObject*)exc;
5540         ei.caught = catch_ctx != NULL;
5541
5542         mono_loader_lock ();
5543
5544         /* Treat exceptions which are caught in non-user code as unhandled */
5545         for (i = 0; i < event_requests->len; ++i) {
5546                 EventRequest *req = g_ptr_array_index (event_requests, i);
5547                 if (req->event_kind != EVENT_KIND_EXCEPTION)
5548                         continue;
5549
5550                 for (j = 0; j < req->nmodifiers; ++j) {
5551                         Modifier *mod = &req->modifiers [j];
5552
5553                         if (mod->kind == MOD_KIND_ASSEMBLY_ONLY && catch_ji) {
5554                                 int k;
5555                                 gboolean found = FALSE;
5556                                 MonoAssembly **assemblies = mod->data.assemblies;
5557
5558                                 if (assemblies) {
5559                                         for (k = 0; assemblies [k]; ++k)
5560                                                 if (assemblies [k] == jinfo_get_method (catch_ji)->klass->image->assembly)
5561                                                         found = TRUE;
5562                                 }
5563                                 if (!found)
5564                                         ei.caught = FALSE;
5565                         }
5566                 }
5567         }
5568
5569         events = create_event_list (EVENT_KIND_EXCEPTION, NULL, ji, &ei, &suspend_policy);
5570         mono_loader_unlock ();
5571
5572         if (tls && ei.caught && catch_ctx) {
5573                 memset (&tls->catch_state, 0, sizeof (tls->catch_state));
5574                 tls->catch_state.ctx = *catch_ctx;
5575                 tls->catch_state.unwind_data [MONO_UNWIND_DATA_DOMAIN] = mono_domain_get ();
5576                 tls->catch_state.valid = TRUE;
5577         }
5578
5579         process_event (EVENT_KIND_EXCEPTION, &ei, 0, throw_ctx, events, suspend_policy);
5580
5581         if (tls)
5582                 tls->catch_state.valid = FALSE;
5583 }
5584
5585 void
5586 mono_debugger_agent_begin_exception_filter (MonoException *exc, MonoContext *ctx, MonoContext *orig_ctx)
5587 {
5588         DebuggerTlsData *tls;
5589
5590         if (!inited)
5591                 return;
5592
5593         tls = mono_native_tls_get_value (debugger_tls_id);
5594         if (!tls)
5595                 return;
5596
5597         /*
5598          * We're about to invoke an exception filter during the first pass of exception handling.
5599          *
5600          * 'ctx' is the context that'll get passed to the filter ('call_filter (ctx, ei->data.filter)'),
5601          * 'orig_ctx' is the context where the exception has been thrown.
5602          *
5603          *
5604          * See mcs/class/Mono.Debugger.Soft/Tests/dtest-excfilter.il for an example.
5605          *
5606          * If we're stopped in Filter(), normal stack unwinding would first unwind to
5607          * the call site (line 37) and then continue to Main(), but it would never
5608          * include the throw site (line 32).
5609          *
5610          * Since exception filters are invoked during the first pass of exception handling,
5611          * the stack frames of the throw site are still intact, so we should include them
5612          * in a stack trace.
5613          *
5614          * We do this here by saving the context of the throw site in 'tls->filter_state'.
5615          *
5616          * Exception filters are used by MonoDroid, where we want to stop inside a call filter,
5617          * but report the location of the 'throw' to the user.
5618          *
5619          */
5620
5621         g_assert (mono_thread_state_init_from_monoctx (&tls->filter_state, orig_ctx));
5622 }
5623
5624 void
5625 mono_debugger_agent_end_exception_filter (MonoException *exc, MonoContext *ctx, MonoContext *orig_ctx)
5626 {
5627         DebuggerTlsData *tls;
5628
5629         if (!inited)
5630                 return;
5631
5632         tls = mono_native_tls_get_value (debugger_tls_id);
5633         if (!tls)
5634                 return;
5635
5636         tls->filter_state.valid = FALSE;
5637 }
5638
5639 /*
5640  * buffer_add_value_full:
5641  *
5642  *   Add the encoding of the value at ADDR described by T to the buffer.
5643  * AS_VTYPE determines whenever to treat primitive types as primitive types or
5644  * vtypes.
5645  */
5646 static void
5647 buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain,
5648                                            gboolean as_vtype, GHashTable *parent_vtypes)
5649 {
5650         MonoObject *obj;
5651         gboolean boxed_vtype = FALSE;
5652
5653         if (t->byref) {
5654                 if (!(*(void**)addr)) {
5655                         /* This can happen with compiler generated locals */
5656                         //printf ("%s\n", mono_type_full_name (t));
5657                         buffer_add_byte (buf, VALUE_TYPE_ID_NULL);
5658                         return;
5659                 }
5660                 g_assert (*(void**)addr);
5661                 addr = *(void**)addr;
5662         }
5663
5664         if (as_vtype) {
5665                 switch (t->type) {
5666                 case MONO_TYPE_BOOLEAN:
5667                 case MONO_TYPE_I1:
5668                 case MONO_TYPE_U1:
5669                 case MONO_TYPE_CHAR:
5670                 case MONO_TYPE_I2:
5671                 case MONO_TYPE_U2:
5672                 case MONO_TYPE_I4:
5673                 case MONO_TYPE_U4:
5674                 case MONO_TYPE_R4:
5675                 case MONO_TYPE_I8:
5676                 case MONO_TYPE_U8:
5677                 case MONO_TYPE_R8:
5678                 case MONO_TYPE_I:
5679                 case MONO_TYPE_U:
5680                 case MONO_TYPE_PTR:
5681                         goto handle_vtype;
5682                         break;
5683                 default:
5684                         break;
5685                 }
5686         }
5687
5688         switch (t->type) {
5689         case MONO_TYPE_VOID:
5690                 buffer_add_byte (buf, t->type);
5691                 break;
5692         case MONO_TYPE_BOOLEAN:
5693         case MONO_TYPE_I1:
5694         case MONO_TYPE_U1:
5695                 buffer_add_byte (buf, t->type);
5696                 buffer_add_int (buf, *(gint8*)addr);
5697                 break;
5698         case MONO_TYPE_CHAR:
5699         case MONO_TYPE_I2:
5700         case MONO_TYPE_U2:
5701                 buffer_add_byte (buf, t->type);
5702                 buffer_add_int (buf, *(gint16*)addr);
5703                 break;
5704         case MONO_TYPE_I4:
5705         case MONO_TYPE_U4:
5706         case MONO_TYPE_R4:
5707                 buffer_add_byte (buf, t->type);
5708                 buffer_add_int (buf, *(gint32*)addr);
5709                 break;
5710         case MONO_TYPE_I8:
5711         case MONO_TYPE_U8:
5712         case MONO_TYPE_R8:
5713                 buffer_add_byte (buf, t->type);
5714                 buffer_add_long (buf, *(gint64*)addr);
5715                 break;
5716         case MONO_TYPE_I:
5717         case MONO_TYPE_U:
5718                 /* Treat it as a vtype */
5719                 goto handle_vtype;
5720         case MONO_TYPE_PTR: {
5721                 gssize val = *(gssize*)addr;
5722                 
5723                 buffer_add_byte (buf, t->type);
5724                 buffer_add_long (buf, val);
5725                 break;
5726         }
5727         handle_ref:
5728         case MONO_TYPE_STRING:
5729         case MONO_TYPE_SZARRAY:
5730         case MONO_TYPE_OBJECT:
5731         case MONO_TYPE_CLASS:
5732         case MONO_TYPE_ARRAY:
5733                 obj = *(MonoObject**)addr;
5734
5735                 if (!obj) {
5736                         buffer_add_byte (buf, VALUE_TYPE_ID_NULL);
5737                 } else {
5738                         if (obj->vtable->klass->valuetype) {
5739                                 t = &obj->vtable->klass->byval_arg;
5740                                 addr = mono_object_unbox (obj);
5741                                 boxed_vtype = TRUE;
5742                                 goto handle_vtype;
5743                         } else if (obj->vtable->klass->rank) {
5744                                 buffer_add_byte (buf, obj->vtable->klass->byval_arg.type);
5745                         } else if (obj->vtable->klass->byval_arg.type == MONO_TYPE_GENERICINST) {
5746                                 buffer_add_byte (buf, MONO_TYPE_CLASS);
5747                         } else {
5748                                 buffer_add_byte (buf, obj->vtable->klass->byval_arg.type);
5749                         }
5750                         buffer_add_objid (buf, obj);
5751                 }
5752                 break;
5753         handle_vtype:
5754         case MONO_TYPE_VALUETYPE:
5755         case MONO_TYPE_TYPEDBYREF: {
5756                 int nfields;
5757                 gpointer iter;
5758                 MonoClassField *f;
5759                 MonoClass *klass = mono_class_from_mono_type (t);
5760                 int vtype_index;
5761
5762                 if (boxed_vtype) {
5763                         /*
5764                          * Handle boxed vtypes recursively referencing themselves using fields.
5765                          */
5766                         if (!parent_vtypes)
5767                                 parent_vtypes = g_hash_table_new (NULL, NULL);
5768                         vtype_index = GPOINTER_TO_INT (g_hash_table_lookup (parent_vtypes, addr));
5769                         if (vtype_index) {
5770                                 if (CHECK_PROTOCOL_VERSION (2, 33)) {
5771                                         buffer_add_byte (buf, VALUE_TYPE_ID_PARENT_VTYPE);
5772                                         buffer_add_int (buf, vtype_index - 1);
5773                                 } else {
5774                                         /* The client can't handle PARENT_VTYPE */
5775                                         buffer_add_byte (buf, VALUE_TYPE_ID_NULL);
5776                                 }
5777                                 break;
5778                         } else {
5779                                 g_hash_table_insert (parent_vtypes, addr, GINT_TO_POINTER (g_hash_table_size (parent_vtypes) + 1));
5780                         }
5781                 }
5782
5783                 buffer_add_byte (buf, MONO_TYPE_VALUETYPE);
5784                 buffer_add_byte (buf, klass->enumtype);
5785                 buffer_add_typeid (buf, domain, klass);
5786
5787                 nfields = 0;
5788                 iter = NULL;
5789                 while ((f = mono_class_get_fields (klass, &iter))) {
5790                         if (f->type->attrs & FIELD_ATTRIBUTE_STATIC)
5791                                 continue;
5792                         if (mono_field_is_deleted (f))
5793                                 continue;
5794                         nfields ++;
5795                 }
5796                 buffer_add_int (buf, nfields);
5797
5798                 iter = NULL;
5799                 while ((f = mono_class_get_fields (klass, &iter))) {
5800                         if (f->type->attrs & FIELD_ATTRIBUTE_STATIC)
5801                                 continue;
5802                         if (mono_field_is_deleted (f))
5803                                 continue;
5804                         buffer_add_value_full (buf, f->type, (guint8*)addr + f->offset - sizeof (MonoObject), domain, FALSE, parent_vtypes);
5805                 }
5806
5807                 if (boxed_vtype) {
5808                         g_hash_table_remove (parent_vtypes, addr);
5809                         if (g_hash_table_size (parent_vtypes) == 0) {
5810                                 g_hash_table_destroy (parent_vtypes);
5811                                 parent_vtypes = NULL;
5812                         }
5813                 }
5814                 break;
5815         }
5816         case MONO_TYPE_GENERICINST:
5817                 if (mono_type_generic_inst_is_valuetype (t)) {
5818                         goto handle_vtype;
5819                 } else {
5820                         goto handle_ref;
5821                 }
5822                 break;
5823         default:
5824                 NOT_IMPLEMENTED;
5825         }
5826 }
5827
5828 static void
5829 buffer_add_value (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain)
5830 {
5831         buffer_add_value_full (buf, t, addr, domain, FALSE, NULL);
5832 }
5833
5834 static gboolean
5835 obj_is_of_type (MonoObject *obj, MonoType *t)
5836 {
5837         MonoClass *klass = obj->vtable->klass;
5838         if (!mono_class_is_assignable_from (mono_class_from_mono_type (t), klass)) {
5839                 if (mono_class_is_transparent_proxy (klass)) {
5840                         klass = ((MonoTransparentProxy *)obj)->remote_class->proxy_class;
5841                         if (mono_class_is_assignable_from (mono_class_from_mono_type (t), klass)) {
5842                                 return TRUE;
5843                         }
5844                 }
5845                 return FALSE;
5846         }
5847         return TRUE;
5848 }
5849
5850 static ErrorCode
5851 decode_value (MonoType *t, MonoDomain *domain, guint8 *addr, guint8 *buf, guint8 **endbuf, guint8 *limit);
5852
5853 static ErrorCode
5854 decode_vtype (MonoType *t, MonoDomain *domain, guint8 *addr, guint8 *buf, guint8 **endbuf, guint8 *limit)
5855 {
5856         gboolean is_enum;
5857         MonoClass *klass;
5858         MonoClassField *f;
5859         int nfields;
5860         gpointer iter = NULL;
5861         MonoDomain *d;
5862         int err;
5863
5864         is_enum = decode_byte (buf, &buf, limit);
5865         /* Enums are sent as a normal vtype */
5866         if (is_enum)
5867                 return ERR_NOT_IMPLEMENTED;
5868         klass = decode_typeid (buf, &buf, limit, &d, &err);
5869         if (err)
5870                 return err;
5871
5872         if (t && klass != mono_class_from_mono_type (t)) {
5873                 char *name = mono_type_full_name (t);
5874                 char *name2 = mono_type_full_name (&klass->byval_arg);
5875                 DEBUG_PRINTF (1, "[%p] Expected value of type %s, got %s.\n", (gpointer)GetCurrentThreadId (), name, name2);
5876                 g_free (name);
5877                 g_free (name2);
5878                 return ERR_INVALID_ARGUMENT;
5879         }
5880
5881         nfields = decode_int (buf, &buf, limit);
5882         while ((f = mono_class_get_fields (klass, &iter))) {
5883                 if (f->type->attrs & FIELD_ATTRIBUTE_STATIC)
5884                         continue;
5885                 if (mono_field_is_deleted (f))
5886                         continue;
5887                 err = decode_value (f->type, domain, (guint8*)addr + f->offset - sizeof (MonoObject), buf, &buf, limit);
5888                 if (err)
5889                         return err;
5890                 nfields --;
5891         }
5892         g_assert (nfields == 0);
5893
5894         *endbuf = buf;
5895
5896         return 0;
5897 }
5898
5899 static ErrorCode
5900 decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr, guint8 *buf, guint8 **endbuf, guint8 *limit)
5901 {
5902         int err;
5903
5904         if (type != t->type && !MONO_TYPE_IS_REFERENCE (t) &&
5905                 !(t->type == MONO_TYPE_I && type == MONO_TYPE_VALUETYPE) &&
5906                 !(t->type == MONO_TYPE_U && type == MONO_TYPE_VALUETYPE) &&
5907                 !(t->type == MONO_TYPE_PTR && type == MONO_TYPE_I8) &&
5908                 !(t->type == MONO_TYPE_GENERICINST && type == MONO_TYPE_VALUETYPE) &&
5909                 !(t->type == MONO_TYPE_VALUETYPE && type == MONO_TYPE_OBJECT)) {
5910                 char *name = mono_type_full_name (t);
5911                 DEBUG_PRINTF (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer)GetCurrentThreadId (), name, type);
5912                 g_free (name);
5913                 return ERR_INVALID_ARGUMENT;
5914         }
5915
5916         switch (t->type) {
5917         case MONO_TYPE_BOOLEAN:
5918                 *(guint8*)addr = decode_int (buf, &buf, limit);
5919                 break;
5920         case MONO_TYPE_CHAR:
5921                 *(gunichar2*)addr = decode_int (buf, &buf, limit);
5922                 break;
5923         case MONO_TYPE_I1:
5924                 *(gint8*)addr = decode_int (buf, &buf, limit);
5925                 break;
5926         case MONO_TYPE_U1:
5927                 *(guint8*)addr = decode_int (buf, &buf, limit);
5928                 break;
5929         case MONO_TYPE_I2:
5930                 *(gint16*)addr = decode_int (buf, &buf, limit);
5931                 break;
5932         case MONO_TYPE_U2:
5933                 *(guint16*)addr = decode_int (buf, &buf, limit);
5934                 break;
5935         case MONO_TYPE_I4:
5936                 *(gint32*)addr = decode_int (buf, &buf, limit);
5937                 break;
5938         case MONO_TYPE_U4:
5939                 *(guint32*)addr = decode_int (buf, &buf, limit);
5940                 break;
5941         case MONO_TYPE_I8:
5942                 *(gint64*)addr = decode_long (buf, &buf, limit);
5943                 break;
5944         case MONO_TYPE_U8:
5945                 *(guint64*)addr = decode_long (buf, &buf, limit);
5946                 break;
5947         case MONO_TYPE_R4:
5948                 *(guint32*)addr = decode_int (buf, &buf, limit);
5949                 break;
5950         case MONO_TYPE_R8:
5951                 *(guint64*)addr = decode_long (buf, &buf, limit);
5952                 break;
5953         case MONO_TYPE_PTR:
5954                 /* We send these as I8, so we get them back as such */
5955                 g_assert (type == MONO_TYPE_I8);
5956                 *(gssize*)addr = decode_long (buf, &buf, limit);
5957                 break;
5958         case MONO_TYPE_GENERICINST:
5959                 if (MONO_TYPE_ISSTRUCT (t)) {
5960                         /* The client sends these as a valuetype */
5961                         goto handle_vtype;
5962                 } else {
5963                         goto handle_ref;
5964                 }
5965                 break;
5966         case MONO_TYPE_I:
5967         case MONO_TYPE_U:
5968                 /* We send these as vtypes, so we get them back as such */
5969                 g_assert (type == MONO_TYPE_VALUETYPE);
5970                 /* Fall through */
5971                 handle_vtype:
5972         case MONO_TYPE_VALUETYPE:
5973                 if (type == MONO_TYPE_OBJECT) {
5974                         /* Boxed vtype */
5975                         int objid = decode_objid (buf, &buf, limit);
5976                         int err;
5977                         MonoObject *obj;
5978
5979                         err = get_object (objid, (MonoObject**)&obj);
5980                         if (err)
5981                                 return err;
5982                         if (!obj)
5983                                 return ERR_INVALID_ARGUMENT;
5984                         if (obj->vtable->klass != mono_class_from_mono_type (t)) {
5985                                 DEBUG_PRINTF (1, "Expected type '%s', got object '%s'\n", mono_type_full_name (t), obj->vtable->klass->name);
5986                                 return ERR_INVALID_ARGUMENT;
5987                         }
5988                         memcpy (addr, mono_object_unbox (obj), mono_class_value_size (obj->vtable->klass, NULL));
5989                 } else {
5990                         err = decode_vtype (t, domain, addr, buf, &buf, limit);
5991                         if (err)
5992                                 return err;
5993                 }
5994                 break;
5995         handle_ref:
5996         default:
5997                 if (MONO_TYPE_IS_REFERENCE (t)) {
5998                         if (type == MONO_TYPE_OBJECT) {
5999                                 int objid = decode_objid (buf, &buf, limit);
6000                                 int err;
6001                                 MonoObject *obj;
6002
6003                                 err = get_object (objid, (MonoObject**)&obj);
6004                                 if (err)
6005                                         return err;
6006
6007                                 if (obj) {
6008                                         if (!obj_is_of_type (obj, t)) {
6009                                                 DEBUG_PRINTF (1, "Expected type '%s', got '%s'\n", mono_type_full_name (t), obj->vtable->klass->name);
6010                                                 return ERR_INVALID_ARGUMENT;
6011                                         }
6012                                 }
6013                                 if (obj && obj->vtable->domain != domain)
6014                                         return ERR_INVALID_ARGUMENT;
6015
6016                                 mono_gc_wbarrier_generic_store (addr, obj);
6017                         } else if (type == VALUE_TYPE_ID_NULL) {
6018                                 *(MonoObject**)addr = NULL;
6019                         } else if (type == MONO_TYPE_VALUETYPE) {
6020                                 guint8 *buf2;
6021                                 gboolean is_enum;
6022                                 MonoClass *klass;
6023                                 MonoDomain *d;
6024                                 guint8 *vtype_buf;
6025                                 int vtype_buf_size;
6026
6027                                 /* This can happen when round-tripping boxed vtypes */
6028                                 /*
6029                                  * Obtain vtype class.
6030                                  * Same as the beginning of the handle_vtype case above.
6031                                  */
6032                                 buf2 = buf;
6033                                 is_enum = decode_byte (buf, &buf, limit);
6034                                 if (is_enum)
6035                                         return ERR_NOT_IMPLEMENTED;
6036                                 klass = decode_typeid (buf, &buf, limit, &d, &err);
6037                                 if (err)
6038                                         return err;
6039
6040                                 /* Decode the vtype into a temporary buffer, then box it. */
6041                                 vtype_buf_size = mono_class_value_size (klass, NULL);
6042                                 vtype_buf = g_malloc0 (vtype_buf_size);
6043                                 g_assert (vtype_buf);
6044
6045                                 buf = buf2;
6046                                 err = decode_vtype (NULL, domain, vtype_buf, buf, &buf, limit);
6047                                 if (err) {
6048                                         g_free (vtype_buf);
6049                                         return err;
6050                                 }
6051                                 *(MonoObject**)addr = mono_value_box (d, klass, vtype_buf);
6052                                 g_free (vtype_buf);
6053                         } else {
6054                                 char *name = mono_type_full_name (t);
6055                                 DEBUG_PRINTF (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer)GetCurrentThreadId (), name, type);
6056                                 g_free (name);
6057                                 return ERR_INVALID_ARGUMENT;
6058                         }
6059                 } else {
6060                         NOT_IMPLEMENTED;
6061                 }
6062                 break;
6063         }
6064
6065         *endbuf = buf;
6066
6067         return 0;
6068 }
6069
6070 static ErrorCode
6071 decode_value (MonoType *t, MonoDomain *domain, guint8 *addr, guint8 *buf, guint8 **endbuf, guint8 *limit)
6072 {
6073         int err;
6074         int type = decode_byte (buf, &buf, limit);
6075
6076         if (t->type == MONO_TYPE_GENERICINST && mono_class_is_nullable (mono_class_from_mono_type (t))) {
6077                 MonoType *targ = t->data.generic_class->context.class_inst->type_argv [0];
6078                 guint8 *nullable_buf;
6079
6080                 /*
6081                  * First try decoding it as a Nullable`1
6082                  */
6083                 err = decode_value_internal (t, type, domain, addr, buf, endbuf, limit);
6084                 if (!err)
6085                         return err;
6086
6087                 /*
6088                  * Then try decoding as a primitive value or null.
6089                  */
6090                 if (targ->type == type) {
6091                         nullable_buf = g_malloc (mono_class_instance_size (mono_class_from_mono_type (targ)));
6092                         err = decode_value_internal (targ, type, domain, nullable_buf, buf, endbuf, limit);
6093                         if (err) {
6094                                 g_free (nullable_buf);
6095                                 return err;
6096                         }
6097                         mono_nullable_init (addr, mono_value_box (domain, mono_class_from_mono_type (targ), nullable_buf), mono_class_from_mono_type (t));
6098                         g_free (nullable_buf);
6099                         *endbuf = buf;
6100                         return ERR_NONE;
6101                 } else if (type == VALUE_TYPE_ID_NULL) {
6102                         mono_nullable_init (addr, NULL, mono_class_from_mono_type (t));
6103                         *endbuf = buf;
6104                         return ERR_NONE;
6105                 }
6106         }
6107
6108         return decode_value_internal (t, type, domain, addr, buf, endbuf, limit);
6109 }
6110
6111 static void
6112 add_var (Buffer *buf, MonoDebugMethodJitInfo *jit, MonoType *t, MonoDebugVarInfo *var, MonoContext *ctx, MonoDomain *domain, gboolean as_vtype)
6113 {
6114         guint32 flags;
6115         int reg;
6116         guint8 *addr, *gaddr;
6117         mgreg_t reg_val;
6118
6119         flags = var->index & MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS;
6120         reg = var->index & ~MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS;
6121
6122         switch (flags) {
6123         case MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER:
6124                 reg_val = mono_arch_context_get_int_reg (ctx, reg);
6125
6126                 buffer_add_value_full (buf, t, &reg_val, domain, as_vtype, NULL);
6127                 break;
6128         case MONO_DEBUG_VAR_ADDRESS_MODE_REGOFFSET:
6129                 addr = (gpointer)mono_arch_context_get_int_reg (ctx, reg);
6130                 addr += (gint32)var->offset;
6131
6132                 //printf ("[R%d+%d] = %p\n", reg, var->offset, addr);
6133
6134                 buffer_add_value_full (buf, t, addr, domain, as_vtype, NULL);
6135                 break;
6136         case MONO_DEBUG_VAR_ADDRESS_MODE_DEAD:
6137                 NOT_IMPLEMENTED;
6138                 break;
6139         case MONO_DEBUG_VAR_ADDRESS_MODE_REGOFFSET_INDIR:
6140         case MONO_DEBUG_VAR_ADDRESS_MODE_VTADDR:
6141                 /* Same as regoffset, but with an indirection */
6142                 addr = (gpointer)mono_arch_context_get_int_reg (ctx, reg);
6143                 addr += (gint32)var->offset;
6144
6145                 gaddr = *(gpointer*)addr;
6146                 g_assert (gaddr);
6147                 buffer_add_value_full (buf, t, gaddr, domain, as_vtype, NULL);
6148                 break;
6149         case MONO_DEBUG_VAR_ADDRESS_MODE_GSHAREDVT_LOCAL: {
6150                 MonoDebugVarInfo *info_var = jit->gsharedvt_info_var;
6151                 MonoDebugVarInfo *locals_var = jit->gsharedvt_locals_var;
6152                 MonoGSharedVtMethodRuntimeInfo *info;
6153                 guint8 *locals;
6154                 int idx;
6155
6156                 idx = reg;
6157
6158                 g_assert (info_var);
6159                 g_assert (locals_var);
6160
6161                 flags = info_var->index & MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS;
6162                 reg = info_var->index & ~MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS;
6163                 if (flags == MONO_DEBUG_VAR_ADDRESS_MODE_REGOFFSET) {
6164                         addr = (gpointer)mono_arch_context_get_int_reg (ctx, reg);
6165                         addr += (gint32)info_var->offset;
6166                         info = *(gpointer*)addr;
6167                 } else if (flags == MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER) {
6168                         info = (gpointer)mono_arch_context_get_int_reg (ctx, reg);
6169                 } else {
6170                         g_assert_not_reached ();
6171                 }
6172                 g_assert (info);
6173
6174                 flags = locals_var->index & MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS;
6175                 reg = locals_var->index & ~MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS;
6176                 if (flags == MONO_DEBUG_VAR_ADDRESS_MODE_REGOFFSET) {
6177                         addr = (gpointer)mono_arch_context_get_int_reg (ctx, reg);
6178                         addr += (gint32)locals_var->offset;
6179                         locals = *(gpointer*)addr;
6180                 } else if (flags == MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER) {
6181                         locals = (gpointer)mono_arch_context_get_int_reg (ctx, reg);
6182                 } else {
6183                         g_assert_not_reached ();
6184                 }
6185                 g_assert (locals);
6186
6187                 addr = locals + GPOINTER_TO_INT (info->entries [idx]);
6188
6189                 buffer_add_value_full (buf, t, addr, domain, as_vtype, NULL);
6190                 break;
6191         }
6192
6193         default:
6194                 g_assert_not_reached ();
6195         }
6196 }
6197
6198 static void
6199 set_var (MonoType *t, MonoDebugVarInfo *var, MonoContext *ctx, MonoDomain *domain, guint8 *val, mgreg_t **reg_locations, MonoContext *restore_ctx)
6200 {
6201         guint32 flags;
6202         int reg, size;
6203         guint8 *addr, *gaddr;
6204
6205         flags = var->index & MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS;
6206         reg = var->index & ~MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS;
6207
6208         if (MONO_TYPE_IS_REFERENCE (t))
6209                 size = sizeof (gpointer);
6210         else
6211                 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
6212
6213         switch (flags) {
6214         case MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER: {
6215 #ifdef MONO_ARCH_HAVE_CONTEXT_SET_INT_REG
6216                 mgreg_t v;
6217                 gboolean is_signed = FALSE;
6218
6219                 if (t->byref) {
6220                         addr = (gpointer)mono_arch_context_get_int_reg (ctx, reg);
6221
6222                         if (addr) {
6223                                 // FIXME: Write barriers
6224                                 mono_gc_memmove_atomic (addr, val, size);
6225                         }
6226                         break;
6227                 }
6228
6229                 if (!t->byref && (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2 || t->type == MONO_TYPE_I4 || t->type == MONO_TYPE_I8))
6230                         is_signed = TRUE;
6231
6232                 switch (size) {
6233                 case 1:
6234                         v = is_signed ? *(gint8*)val : *(guint8*)val;
6235                         break;
6236                 case 2:
6237                         v = is_signed ? *(gint16*)val : *(guint16*)val;
6238                         break;
6239                 case 4:
6240                         v = is_signed ? *(gint32*)val : *(guint32*)val;
6241                         break;
6242                 case 8:
6243                         v = is_signed ? *(gint64*)val : *(guint64*)val;
6244                         break;
6245                 default:
6246                         g_assert_not_reached ();
6247                 }
6248
6249                 /* Set value on the stack or in the return ctx */
6250                 if (reg_locations [reg]) {
6251                         /* Saved on the stack */
6252                         DEBUG_PRINTF (1, "[dbg] Setting stack location %p for reg %x to %p.\n", reg_locations [reg], reg, (gpointer)v);
6253                         *(reg_locations [reg]) = v;
6254                 } else {
6255                         /* Not saved yet */
6256                         DEBUG_PRINTF (1, "[dbg] Setting context location for reg %x to %p.\n", reg, (gpointer)v);
6257                         mono_arch_context_set_int_reg (restore_ctx, reg, v);
6258                 }                       
6259
6260                 // FIXME: Move these to mono-context.h/c.
6261                 mono_arch_context_set_int_reg (ctx, reg, v);
6262 #else
6263                 // FIXME: Can't set registers, so we disable linears
6264                 NOT_IMPLEMENTED;
6265 #endif
6266                 break;
6267         }
6268         case MONO_DEBUG_VAR_ADDRESS_MODE_REGOFFSET:
6269                 addr = (gpointer)mono_arch_context_get_int_reg (ctx, reg);
6270                 addr += (gint32)var->offset;
6271
6272                 //printf ("[R%d+%d] = %p\n", reg, var->offset, addr);
6273
6274                 if (t->byref) {
6275                         addr = *(guint8**)addr;
6276
6277                         if (!addr)
6278                                 break;
6279                 }
6280                         
6281                 // FIXME: Write barriers
6282                 mono_gc_memmove_atomic (addr, val, size);
6283                 break;
6284         case MONO_DEBUG_VAR_ADDRESS_MODE_REGOFFSET_INDIR:
6285                 /* Same as regoffset, but with an indirection */
6286                 addr = (gpointer)mono_arch_context_get_int_reg (ctx, reg);
6287                 addr += (gint32)var->offset;
6288
6289                 gaddr = *(gpointer*)addr;
6290                 g_assert (gaddr);
6291                 // FIXME: Write barriers
6292                 mono_gc_memmove_atomic (gaddr, val, size);
6293                 break;
6294         case MONO_DEBUG_VAR_ADDRESS_MODE_DEAD:
6295                 NOT_IMPLEMENTED;
6296                 break;
6297         default:
6298                 g_assert_not_reached ();
6299         }
6300 }
6301
6302 static void
6303 clear_event_request (int req_id, int etype)
6304 {
6305         int i;
6306
6307         mono_loader_lock ();
6308         for (i = 0; i < event_requests->len; ++i) {
6309                 EventRequest *req = g_ptr_array_index (event_requests, i);
6310
6311                 if (req->id == req_id && req->event_kind == etype) {
6312                         if (req->event_kind == EVENT_KIND_BREAKPOINT)
6313                                 clear_breakpoint (req->info);
6314                         if (req->event_kind == EVENT_KIND_STEP)
6315                                 ss_destroy (req->info);
6316                         if (req->event_kind == EVENT_KIND_METHOD_ENTRY)
6317                                 clear_breakpoint (req->info);
6318                         if (req->event_kind == EVENT_KIND_METHOD_EXIT)
6319                                 clear_breakpoint (req->info);
6320                         g_ptr_array_remove_index_fast (event_requests, i);
6321                         g_free (req);
6322                         break;
6323                 }
6324         }
6325         mono_loader_unlock ();
6326 }
6327
6328 static void
6329 clear_assembly_from_modifier (EventRequest *req, Modifier *m, MonoAssembly *assembly)
6330 {
6331         int i;
6332
6333         if (m->kind == MOD_KIND_EXCEPTION_ONLY && m->data.exc_class && m->data.exc_class->image->assembly == assembly)
6334                 m->kind = MOD_KIND_NONE;
6335         if (m->kind == MOD_KIND_ASSEMBLY_ONLY && m->data.assemblies) {
6336                 int count = 0, match_count = 0, pos;
6337                 MonoAssembly **newassemblies;
6338
6339                 for (i = 0; m->data.assemblies [i]; ++i) {
6340                         count ++;
6341                         if (m->data.assemblies [i] == assembly)
6342                                 match_count ++;
6343                 }
6344
6345                 if (match_count) {
6346                         newassemblies = g_new0 (MonoAssembly*, count - match_count);
6347
6348                         pos = 0;
6349                         for (i = 0; i < count; ++i)
6350                                 if (m->data.assemblies [i] != assembly)
6351                                         newassemblies [pos ++] = m->data.assemblies [i];
6352                         g_assert (pos == count - match_count);
6353                         g_free (m->data.assemblies);
6354                         m->data.assemblies = newassemblies;
6355                 }
6356         }
6357 }
6358
6359 static void
6360 clear_assembly_from_modifiers (EventRequest *req, MonoAssembly *assembly)
6361 {
6362         int i;
6363
6364         for (i = 0; i < req->nmodifiers; ++i) {
6365                 Modifier *m = &req->modifiers [i];
6366
6367                 clear_assembly_from_modifier (req, m, assembly);
6368         }
6369 }
6370
6371 /*
6372  * clear_event_requests_for_assembly:
6373  *
6374  *   Clear all events requests which reference ASSEMBLY.
6375  */
6376 static void
6377 clear_event_requests_for_assembly (MonoAssembly *assembly)
6378 {
6379         int i;
6380         gboolean found;
6381
6382         mono_loader_lock ();
6383         found = TRUE;
6384         while (found) {
6385                 found = FALSE;
6386                 for (i = 0; i < event_requests->len; ++i) {
6387                         EventRequest *req = g_ptr_array_index (event_requests, i);
6388
6389                         clear_assembly_from_modifiers (req, assembly);
6390
6391                         if (req->event_kind == EVENT_KIND_BREAKPOINT && breakpoint_matches_assembly (req->info, assembly)) {
6392                                 clear_event_request (req->id, req->event_kind);
6393                                 found = TRUE;
6394                                 break;
6395                         }
6396
6397                         if (req->event_kind == EVENT_KIND_STEP)
6398                                 ss_clear_for_assembly (req->info, assembly);
6399                 }
6400         }
6401         mono_loader_unlock ();
6402 }
6403
6404 /*
6405  * type_comes_from_assembly:
6406  *
6407  *   GHRFunc that returns TRUE if klass comes from assembly
6408  */
6409 static gboolean
6410 type_comes_from_assembly (gpointer klass, gpointer also_klass, gpointer assembly)
6411 {
6412         return (mono_class_get_image ((MonoClass*)klass) == mono_assembly_get_image ((MonoAssembly*)assembly));
6413 }
6414
6415 /*
6416  * clear_types_for_assembly:
6417  *
6418  *   Clears types from loaded_classes for a given assembly
6419  */
6420 static void
6421 clear_types_for_assembly (MonoAssembly *assembly)
6422 {
6423         MonoDomain *domain = mono_domain_get ();
6424         AgentDomainInfo *info = NULL;
6425
6426         if (!domain || !domain_jit_info (domain))
6427                 /* Can happen during shutdown */
6428                 return;
6429
6430         info = get_agent_domain_info (domain);
6431
6432         mono_loader_lock ();
6433         g_hash_table_foreach_remove (info->loaded_classes, type_comes_from_assembly, assembly);
6434         mono_loader_unlock ();
6435 }
6436
6437 static void
6438 add_thread (gpointer key, gpointer value, gpointer user_data)
6439 {
6440         MonoInternalThread *thread = value;
6441         Buffer *buf = user_data;
6442
6443         buffer_add_objid (buf, (MonoObject*)thread);
6444 }
6445
6446 static ErrorCode
6447 do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 *p, guint8 **endp)
6448 {
6449         guint8 *end = invoke->endp;
6450         MonoMethod *m;
6451         int i, err, nargs;
6452         MonoMethodSignature *sig;
6453         guint8 **arg_buf;
6454         void **args;
6455         MonoObject *this_arg, *res, *exc;
6456         MonoDomain *domain;
6457         guint8 *this_buf;
6458 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
6459         MonoLMFExt ext;
6460 #endif
6461         MonoStopwatch watch;
6462
6463         if (invoke->method) {
6464                 /* 
6465                  * Invoke this method directly, currently only Environment.Exit () is supported.
6466                  */
6467                 this_arg = NULL;
6468                 DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (invoke->method, TRUE), this_arg ? this_arg->vtable->klass->name : "<null>");
6469                 mono_runtime_invoke (invoke->method, NULL, invoke->args, &exc);
6470                 g_assert_not_reached ();
6471         }
6472
6473         m = decode_methodid (p, &p, end, &domain, &err);
6474         if (err)
6475                 return err;
6476         sig = mono_method_signature (m);
6477
6478         if (m->klass->valuetype)
6479                 this_buf = g_alloca (mono_class_instance_size (m->klass));
6480         else
6481                 this_buf = g_alloca (sizeof (MonoObject*));
6482         if (m->klass->valuetype && (m->flags & METHOD_ATTRIBUTE_STATIC)) {
6483                 /* Should be null */
6484                 int type = decode_byte (p, &p, end);
6485                 if (type != VALUE_TYPE_ID_NULL) {
6486                         DEBUG_PRINTF (1, "[%p] Error: Static vtype method invoked with this argument.\n", (gpointer)GetCurrentThreadId ());
6487                         return ERR_INVALID_ARGUMENT;
6488                 }
6489                 memset (this_buf, 0, mono_class_instance_size (m->klass));
6490         } else if (m->klass->valuetype && !strcmp (m->name, ".ctor")) {
6491                         /* Could be null */
6492                         guint8 *tmp_p;
6493
6494                         int type = decode_byte (p, &tmp_p, end);
6495                         if (type == VALUE_TYPE_ID_NULL) {
6496                                 memset (this_buf, 0, mono_class_instance_size (m->klass));
6497                                 p = tmp_p;
6498                         } else {
6499                                 err = decode_value (&m->klass->byval_arg, domain, this_buf, p, &p, end);
6500                                 if (err)
6501                                         return err;
6502                         }
6503         } else {
6504                 err = decode_value (&m->klass->byval_arg, domain, this_buf, p, &p, end);
6505                 if (err)
6506                         return err;
6507         }
6508
6509         if (!m->klass->valuetype)
6510                 this_arg = *(MonoObject**)this_buf;
6511         else
6512                 this_arg = NULL;
6513
6514         if (MONO_CLASS_IS_INTERFACE (m->klass)) {
6515                 if (!this_arg) {
6516                         DEBUG_PRINTF (1, "[%p] Error: Interface method invoked without this argument.\n", (gpointer)GetCurrentThreadId ());
6517                         return ERR_INVALID_ARGUMENT;
6518                 }
6519                 m = mono_object_get_virtual_method (this_arg, m);
6520                 /* Transform this to the format the rest of the code expects it to be */
6521                 if (m->klass->valuetype) {
6522                         this_buf = g_alloca (mono_class_instance_size (m->klass));
6523                         memcpy (this_buf, mono_object_unbox (this_arg), mono_class_instance_size (m->klass));
6524                 }
6525         } else if ((m->flags & METHOD_ATTRIBUTE_VIRTUAL) && !m->klass->valuetype && invoke->flags & INVOKE_FLAG_VIRTUAL) {
6526                 if (!this_arg) {
6527                         DEBUG_PRINTF (1, "[%p] Error: invoke with INVOKE_FLAG_VIRTUAL flag set without this argument.\n", (gpointer)GetCurrentThreadId ());
6528                         return ERR_INVALID_ARGUMENT;
6529                 }
6530                 m = mono_object_get_virtual_method (this_arg, m);
6531                 if (m->klass->valuetype) {
6532                         this_buf = g_alloca (mono_class_instance_size (m->klass));
6533                         memcpy (this_buf, mono_object_unbox (this_arg), mono_class_instance_size (m->klass));
6534                 }
6535         }
6536
6537         DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (m, TRUE), this_arg ? this_arg->vtable->klass->name : "<null>");
6538
6539         if (this_arg && this_arg->vtable->domain != domain)
6540                 NOT_IMPLEMENTED;
6541
6542         if (!m->klass->valuetype && !(m->flags & METHOD_ATTRIBUTE_STATIC) && !this_arg) {
6543                 if (!strcmp (m->name, ".ctor")) {
6544                         if (m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT)
6545                                 return ERR_INVALID_ARGUMENT;
6546                         else
6547                                 this_arg = mono_object_new (domain, m->klass);
6548                 } else {
6549                         return ERR_INVALID_ARGUMENT;
6550                 }
6551         }
6552
6553         if (this_arg && !obj_is_of_type (this_arg, &m->klass->byval_arg))
6554                 return ERR_INVALID_ARGUMENT;
6555
6556         nargs = decode_int (p, &p, end);
6557         if (nargs != sig->param_count)
6558                 return ERR_INVALID_ARGUMENT;
6559         /* Use alloca to get gc tracking */
6560         arg_buf = g_alloca (nargs * sizeof (gpointer));
6561         memset (arg_buf, 0, nargs * sizeof (gpointer));
6562         args = g_alloca (nargs * sizeof (gpointer));
6563         for (i = 0; i < nargs; ++i) {
6564                 if (MONO_TYPE_IS_REFERENCE (sig->params [i])) {
6565                         err = decode_value (sig->params [i], domain, (guint8*)&args [i], p, &p, end);
6566                         if (err)
6567                                 break;
6568                         if (args [i] && ((MonoObject*)args [i])->vtable->domain != domain)
6569                                 NOT_IMPLEMENTED;
6570
6571                         if (sig->params [i]->byref) {
6572                                 arg_buf [i] = g_alloca (sizeof (mgreg_t));
6573                                 *(gpointer*)arg_buf [i] = args [i];
6574                                 args [i] = arg_buf [i];
6575                         }
6576                 } else {
6577                         arg_buf [i] = g_alloca (mono_class_instance_size (mono_class_from_mono_type (sig->params [i])));
6578                         err = decode_value (sig->params [i], domain, arg_buf [i], p, &p, end);
6579                         if (err)
6580                                 break;
6581                         args [i] = arg_buf [i];
6582                 }
6583         }
6584
6585         if (i < nargs)
6586                 return err;
6587
6588         if (invoke->flags & INVOKE_FLAG_DISABLE_BREAKPOINTS)
6589                 tls->disable_breakpoints = TRUE;
6590         else
6591                 tls->disable_breakpoints = FALSE;
6592
6593         /* 
6594          * Add an LMF frame to link the stack frames on the invoke method with our caller.
6595          */
6596 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
6597         if (invoke->has_ctx) {
6598                 MonoLMF **lmf_addr;
6599
6600                 lmf_addr = mono_get_lmf_addr ();
6601
6602                 /* Setup our lmf */
6603                 memset (&ext, 0, sizeof (ext));
6604                 mono_arch_init_lmf_ext (&ext, *lmf_addr);
6605
6606                 ext.debugger_invoke = TRUE;
6607                 memcpy (&ext.ctx, &invoke->ctx, sizeof (MonoContext));
6608
6609                 mono_set_lmf ((MonoLMF*)&ext);
6610         }
6611 #endif
6612
6613         mono_stopwatch_start (&watch);
6614         if (m->klass->valuetype)
6615                 res = mono_runtime_invoke (m, this_buf, args, &exc);
6616         else
6617                 res = mono_runtime_invoke (m, this_arg, args, &exc);
6618         mono_stopwatch_stop (&watch);
6619         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));
6620         if (exc) {
6621                 buffer_add_byte (buf, 0);
6622                 buffer_add_value (buf, &mono_defaults.object_class->byval_arg, &exc, domain);
6623         } else {
6624                 gboolean out_this = FALSE;
6625                 gboolean out_args = FALSE;
6626
6627                 if ((invoke->flags & INVOKE_FLAG_RETURN_OUT_THIS) && CHECK_PROTOCOL_VERSION (2, 35))
6628                         out_this = TRUE;
6629                 if ((invoke->flags & INVOKE_FLAG_RETURN_OUT_ARGS) && CHECK_PROTOCOL_VERSION (2, 35))
6630                         out_args = TRUE;
6631                 buffer_add_byte (buf, 1 + (out_this ? 2 : 0) + (out_args ? 4 : 0));
6632                 if (sig->ret->type == MONO_TYPE_VOID) {
6633                         if (!strcmp (m->name, ".ctor")) {
6634                                 if (!m->klass->valuetype)
6635                                         buffer_add_value (buf, &mono_defaults.object_class->byval_arg, &this_arg, domain);
6636                                 else
6637                                         buffer_add_value (buf, &m->klass->byval_arg, this_buf, domain);
6638                         } else {
6639                                 buffer_add_value (buf, &mono_defaults.void_class->byval_arg, NULL, domain);
6640                         }
6641                 } else if (MONO_TYPE_IS_REFERENCE (sig->ret)) {
6642                         buffer_add_value (buf, sig->ret, &res, domain);
6643                 } else if (mono_class_from_mono_type (sig->ret)->valuetype || sig->ret->type == MONO_TYPE_PTR || sig->ret->type == MONO_TYPE_FNPTR) {
6644                         if (mono_class_is_nullable (mono_class_from_mono_type (sig->ret))) {
6645                                 MonoClass *k = mono_class_from_mono_type (sig->ret);
6646                                 guint8 *nullable_buf = g_alloca (mono_class_value_size (k, NULL));
6647
6648                                 g_assert (nullable_buf);
6649                                 mono_nullable_init (nullable_buf, res, k);
6650                                 buffer_add_value (buf, sig->ret, nullable_buf, domain);
6651                         } else {
6652                                 g_assert (res);
6653                                 buffer_add_value (buf, sig->ret, mono_object_unbox (res), domain);
6654                         }
6655                 } else {
6656                         NOT_IMPLEMENTED;
6657                 }
6658                 if (out_this)
6659                         /* Return the new value of the receiver after the call */
6660                         buffer_add_value (buf, &m->klass->byval_arg, this_buf, domain);
6661                 if (out_args) {
6662                         buffer_add_int (buf, nargs);
6663                         for (i = 0; i < nargs; ++i) {
6664                                 if (MONO_TYPE_IS_REFERENCE (sig->params [i]))
6665                                         buffer_add_value (buf, sig->params [i], &args [i], domain);
6666                                 else if (sig->params [i]->byref)
6667                                         /* add_value () does an indirection */
6668                                         buffer_add_value (buf, sig->params [i], &arg_buf [i], domain);
6669                                 else
6670                                         buffer_add_value (buf, sig->params [i], arg_buf [i], domain);
6671                         }
6672                 }
6673         }
6674
6675         tls->disable_breakpoints = FALSE;
6676
6677 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
6678         if (invoke->has_ctx)
6679                 mono_set_lmf ((gpointer)(((gssize)ext.lmf.previous_lmf) & ~3));
6680 #endif
6681
6682         *endp = p;
6683         // FIXME: byref arguments
6684         // FIXME: varargs
6685         return ERR_NONE;
6686 }
6687
6688 /*
6689  * invoke_method:
6690  *
6691  *   Invoke the method given by tls->pending_invoke in the current thread.
6692  */
6693 static void
6694 invoke_method (void)
6695 {
6696         DebuggerTlsData *tls;
6697         InvokeData *invoke;
6698         int id;
6699         int i, err, mindex;
6700         Buffer buf;
6701         MonoContext restore_ctx;
6702         guint8 *p;
6703
6704         tls = mono_native_tls_get_value (debugger_tls_id);
6705         g_assert (tls);
6706
6707         /*
6708          * Store the `InvokeData *' in `tls->invoke' until we're done with
6709          * the invocation, so CMD_VM_ABORT_INVOKE can check it.
6710          */
6711
6712         mono_loader_lock ();
6713
6714         invoke = tls->pending_invoke;
6715         g_assert (invoke);
6716         tls->pending_invoke = NULL;
6717
6718         invoke->last_invoke = tls->invoke;
6719         tls->invoke = invoke;
6720
6721         mono_loader_unlock ();
6722
6723         tls->frames_up_to_date = FALSE;
6724
6725         id = invoke->id;
6726
6727         p = invoke->p;
6728         err = 0;
6729         for (mindex = 0; mindex < invoke->nmethods; ++mindex) {
6730                 buffer_init (&buf, 128);
6731
6732                 if (err) {
6733                         /* Fail the other invokes as well */
6734                 } else {
6735                         err = do_invoke_method (tls, &buf, invoke, p, &p);
6736                 }
6737
6738                 /* Start suspending before sending the reply */
6739                 if (mindex == invoke->nmethods - 1) {
6740                         if (!(invoke->flags & INVOKE_FLAG_SINGLE_THREADED)) {
6741                                 for (i = 0; i < invoke->suspend_count; ++i)
6742                                         suspend_vm ();
6743                         }
6744                 }
6745
6746                 send_reply_packet (id, err, &buf);
6747         
6748                 buffer_free (&buf);
6749         }
6750
6751         memcpy (&restore_ctx, &invoke->ctx, sizeof (MonoContext));
6752
6753         if (invoke->has_ctx)
6754                 save_thread_context (&restore_ctx);
6755
6756         if (invoke->flags & INVOKE_FLAG_SINGLE_THREADED) {
6757                 g_assert (tls->resume_count);
6758                 tls->resume_count -= invoke->suspend_count;
6759         }
6760
6761         DEBUG_PRINTF (1, "[%p] Invoke finished (%d), resume_count = %d.\n", (gpointer)GetCurrentThreadId (), err, tls->resume_count);
6762
6763         /*
6764          * Take the loader lock to avoid race conditions with CMD_VM_ABORT_INVOKE:
6765          *
6766          * It is possible that ves_icall_System_Threading_Thread_Abort () was called
6767          * after the mono_runtime_invoke() already returned, but it doesn't matter
6768          * because we reset the abort here.
6769          */
6770
6771         mono_loader_lock ();
6772
6773         if (tls->abort_requested)
6774                 mono_thread_internal_reset_abort (tls->thread);
6775
6776         tls->invoke = tls->invoke->last_invoke;
6777         tls->abort_requested = FALSE;
6778
6779         mono_loader_unlock ();
6780
6781         g_free (invoke->p);
6782         g_free (invoke);
6783
6784         suspend_current ();
6785 }
6786
6787 static gboolean
6788 is_really_suspended (gpointer key, gpointer value, gpointer user_data)
6789 {
6790         MonoThread *thread = value;
6791         DebuggerTlsData *tls;
6792         gboolean res;
6793
6794         mono_loader_lock ();
6795         tls = mono_g_hash_table_lookup (thread_to_tls, thread);
6796         g_assert (tls);
6797         res = tls->really_suspended;
6798         mono_loader_unlock ();
6799
6800         return res;
6801 }
6802
6803 static GPtrArray*
6804 get_source_files_for_type (MonoClass *klass)
6805 {
6806         gpointer iter = NULL;
6807         MonoMethod *method;
6808         MonoDebugSourceInfo *sinfo;
6809         GPtrArray *files;
6810         int i, j;
6811
6812         files = g_ptr_array_new ();
6813
6814         while ((method = mono_class_get_methods (klass, &iter))) {
6815                 MonoDebugMethodInfo *minfo = mono_debug_lookup_method (method);
6816                 GPtrArray *source_file_list;
6817
6818                 if (minfo) {
6819                         mono_debug_get_seq_points (minfo, NULL, &source_file_list, NULL, NULL, NULL);
6820                         for (j = 0; j < source_file_list->len; ++j) {
6821                                 sinfo = g_ptr_array_index (source_file_list, j);
6822                                 for (i = 0; i < files->len; ++i)
6823                                         if (!strcmp (g_ptr_array_index (files, i), sinfo->source_file))
6824                                                 break;
6825                                 if (i == files->len)
6826                                         g_ptr_array_add (files, g_strdup (sinfo->source_file));
6827                         }
6828                         g_ptr_array_free (source_file_list, TRUE);
6829                 }
6830         }
6831
6832         return files;
6833 }
6834
6835 static ErrorCode
6836 vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
6837 {
6838         switch (command) {
6839         case CMD_VM_VERSION: {
6840                 char *build_info, *version;
6841
6842                 build_info = mono_get_runtime_build_info ();
6843                 version = g_strdup_printf ("mono %s", build_info);
6844
6845                 buffer_add_string (buf, version); /* vm version */
6846                 buffer_add_int (buf, MAJOR_VERSION);
6847                 buffer_add_int (buf, MINOR_VERSION);
6848                 g_free (build_info);
6849                 g_free (version);
6850                 break;
6851         }
6852         case CMD_VM_SET_PROTOCOL_VERSION: {
6853                 major_version = decode_int (p, &p, end);
6854                 minor_version = decode_int (p, &p, end);
6855                 protocol_version_set = TRUE;
6856                 DEBUG_PRINTF (1, "[dbg] Protocol version %d.%d, client protocol version %d.%d.\n", MAJOR_VERSION, MINOR_VERSION, major_version, minor_version);
6857                 break;
6858         }
6859         case CMD_VM_ALL_THREADS: {
6860                 // FIXME: Domains
6861                 mono_loader_lock ();
6862                 buffer_add_int (buf, mono_g_hash_table_size (tid_to_thread_obj));
6863                 mono_g_hash_table_foreach (tid_to_thread_obj, add_thread, buf);
6864                 mono_loader_unlock ();
6865                 break;
6866         }
6867         case CMD_VM_SUSPEND:
6868                 suspend_vm ();
6869                 wait_for_suspend ();
6870                 break;
6871         case CMD_VM_RESUME:
6872                 if (suspend_count == 0)
6873                         return ERR_NOT_SUSPENDED;
6874                 resume_vm ();
6875                 clear_suspended_objs ();
6876                 break;
6877         case CMD_VM_DISPOSE:
6878                 /* Clear all event requests */
6879                 mono_loader_lock ();
6880                 while (event_requests->len > 0) {
6881                         EventRequest *req = g_ptr_array_index (event_requests, 0);
6882
6883                         clear_event_request (req->id, req->event_kind);
6884                 }
6885                 mono_loader_unlock ();
6886
6887                 while (suspend_count > 0)
6888                         resume_vm ();
6889                 disconnected = TRUE;
6890                 vm_start_event_sent = FALSE;
6891                 break;
6892         case CMD_VM_EXIT: {
6893                 MonoInternalThread *thread;
6894                 DebuggerTlsData *tls;
6895 #ifdef TRY_MANAGED_SYSTEM_ENVIRONMENT_EXIT
6896                 MonoClass *env_class;
6897 #endif
6898                 MonoMethod *exit_method = NULL;
6899                 gpointer *args;
6900                 int exit_code;
6901
6902                 exit_code = decode_int (p, &p, end);
6903
6904                 // FIXME: What if there is a VM_DEATH event request with SUSPEND_ALL ?
6905
6906                 /* Have to send a reply before exiting */
6907                 send_reply_packet (id, 0, buf);
6908
6909                 /* Clear all event requests */
6910                 mono_loader_lock ();
6911                 while (event_requests->len > 0) {
6912                         EventRequest *req = g_ptr_array_index (event_requests, 0);
6913
6914                         clear_event_request (req->id, req->event_kind);
6915                 }
6916                 mono_loader_unlock ();
6917
6918                 /*
6919                  * The JDWP documentation says that the shutdown is not orderly. It doesn't
6920                  * specify whenever a VM_DEATH event is sent. We currently do an orderly
6921                  * shutdown by hijacking a thread to execute Environment.Exit (). This is
6922                  * better than doing the shutdown ourselves, since it avoids various races.
6923                  */
6924
6925                 suspend_vm ();
6926                 wait_for_suspend ();
6927
6928 #ifdef TRY_MANAGED_SYSTEM_ENVIRONMENT_EXIT
6929                 env_class = mono_class_from_name (mono_defaults.corlib, "System", "Environment");
6930                 if (env_class)
6931                         exit_method = mono_class_get_method_from_name (env_class, "Exit", 1);
6932 #endif
6933
6934                 mono_loader_lock ();
6935                 thread = mono_g_hash_table_find (tid_to_thread, is_really_suspended, NULL);
6936                 mono_loader_unlock ();
6937
6938                 if (thread && exit_method) {
6939                         mono_loader_lock ();
6940                         tls = mono_g_hash_table_lookup (thread_to_tls, thread);
6941                         mono_loader_unlock ();
6942
6943                         args = g_new0 (gpointer, 1);
6944                         args [0] = g_malloc (sizeof (int));
6945                         *(int*)(args [0]) = exit_code;
6946
6947                         tls->pending_invoke = g_new0 (InvokeData, 1);
6948                         tls->pending_invoke->method = exit_method;
6949                         tls->pending_invoke->args = args;
6950                         tls->pending_invoke->nmethods = 1;
6951
6952                         while (suspend_count > 0)
6953                                 resume_vm ();
6954                 } else {
6955                         /* 
6956                          * No thread found, do it ourselves.
6957                          * FIXME: This can race with normal shutdown etc.
6958                          */
6959                         while (suspend_count > 0)
6960                                 resume_vm ();
6961
6962                         if (!mono_runtime_try_shutdown ())
6963                                 break;
6964
6965                         mono_environment_exitcode_set (exit_code);
6966
6967                         /* Suspend all managed threads since the runtime is going away */
6968                         DEBUG_PRINTF (1, "Suspending all threads...\n");
6969                         mono_thread_suspend_all_other_threads ();
6970                         DEBUG_PRINTF (1, "Shutting down the runtime...\n");
6971                         mono_runtime_quit ();
6972                         transport_close2 ();
6973                         DEBUG_PRINTF (1, "Exiting...\n");
6974
6975                         exit (exit_code);
6976                 }
6977                 break;
6978         }               
6979         case CMD_VM_INVOKE_METHOD:
6980         case CMD_VM_INVOKE_METHODS: {
6981                 int objid = decode_objid (p, &p, end);
6982                 MonoThread *thread;
6983                 DebuggerTlsData *tls;
6984                 int i, count, err, flags, nmethods;
6985
6986                 err = get_object (objid, (MonoObject**)&thread);
6987                 if (err)
6988                         return err;
6989
6990                 flags = decode_int (p, &p, end);
6991
6992                 if (command == CMD_VM_INVOKE_METHODS)
6993                         nmethods = decode_int (p, &p, end);
6994                 else
6995                         nmethods = 1;
6996
6997                 // Wait for suspending if it already started
6998                 if (suspend_count)
6999                         wait_for_suspend ();
7000                 if (!is_suspended ())
7001                         return ERR_NOT_SUSPENDED;
7002
7003                 mono_loader_lock ();
7004                 tls = mono_g_hash_table_lookup (thread_to_tls, THREAD_TO_INTERNAL (thread));
7005                 mono_loader_unlock ();
7006                 g_assert (tls);
7007
7008                 if (!tls->really_suspended)
7009                         /* The thread is still running native code, can't do invokes */
7010                         return ERR_NOT_SUSPENDED;
7011
7012                 /* 
7013                  * Store the invoke data into tls, the thread will execute it after it is
7014                  * resumed.
7015                  */
7016                 if (tls->pending_invoke || tls->invoke)
7017                         return ERR_NOT_SUSPENDED;
7018                 tls->pending_invoke = g_new0 (InvokeData, 1);
7019                 tls->pending_invoke->id = id;
7020                 tls->pending_invoke->flags = flags;
7021                 tls->pending_invoke->p = g_malloc (end - p);
7022                 memcpy (tls->pending_invoke->p, p, end - p);
7023                 tls->pending_invoke->endp = tls->pending_invoke->p + (end - p);
7024                 tls->pending_invoke->suspend_count = suspend_count;
7025                 tls->pending_invoke->nmethods = nmethods;
7026
7027                 if (flags & INVOKE_FLAG_SINGLE_THREADED) {
7028                         resume_thread (THREAD_TO_INTERNAL (thread));
7029                 }
7030                 else {
7031                         count = suspend_count;
7032                         for (i = 0; i < count; ++i)
7033                                 resume_vm ();
7034                 }
7035                 break;
7036         }
7037         case CMD_VM_ABORT_INVOKE: {
7038                 int objid = decode_objid (p, &p, end);
7039                 MonoThread *thread;
7040                 DebuggerTlsData *tls;
7041                 int invoke_id, err;
7042
7043                 err = get_object (objid, (MonoObject**)&thread);
7044                 if (err)
7045                         return err;
7046
7047                 invoke_id = decode_int (p, &p, end);
7048
7049                 mono_loader_lock ();
7050                 tls = mono_g_hash_table_lookup (thread_to_tls, THREAD_TO_INTERNAL (thread));
7051                 g_assert (tls);
7052
7053                 if (tls->abort_requested) {
7054                         mono_loader_unlock ();
7055                         break;
7056                 }
7057
7058                 /*
7059                  * Check whether we're still inside the mono_runtime_invoke() and that it's
7060                  * actually the correct invocation.
7061                  *
7062                  * Careful, we do not stop the thread that's doing the invocation, so we can't
7063                  * inspect its stack.  However, invoke_method() also acquires the loader lock
7064                  * when it's done, so we're safe here.
7065                  *
7066                  */
7067
7068                 if (!tls->invoke || (tls->invoke->id != invoke_id)) {
7069                         mono_loader_unlock ();
7070                         return ERR_NO_INVOCATION;
7071                 }
7072
7073                 tls->abort_requested = TRUE;
7074
7075                 ves_icall_System_Threading_Thread_Abort (THREAD_TO_INTERNAL (thread), NULL);
7076                 mono_loader_unlock ();
7077                 break;
7078         }
7079
7080         case CMD_VM_SET_KEEPALIVE: {
7081                 int timeout = decode_int (p, &p, end);
7082                 agent_config.keepalive = timeout;
7083                 // FIXME:
7084 #ifndef DISABLE_SOCKET_TRANSPORT
7085                 set_keepalive ();
7086 #else
7087                 NOT_IMPLEMENTED;
7088 #endif
7089                 break;
7090         }
7091         case CMD_VM_GET_TYPES_FOR_SOURCE_FILE: {
7092                 GHashTableIter iter, kiter;
7093                 MonoDomain *domain;
7094                 MonoClass *klass;
7095                 GPtrArray *files;
7096                 int i;
7097                 char *fname, *basename;
7098                 gboolean ignore_case;
7099                 GSList *class_list, *l;
7100                 GPtrArray *res_classes, *res_domains;
7101
7102                 fname = decode_string (p, &p, end);
7103                 ignore_case = decode_byte (p, &p, end);
7104
7105                 basename = dbg_path_get_basename (fname);
7106
7107                 res_classes = g_ptr_array_new ();
7108                 res_domains = g_ptr_array_new ();
7109
7110                 mono_loader_lock ();
7111                 g_hash_table_iter_init (&iter, domains);
7112                 while (g_hash_table_iter_next (&iter, NULL, (void**)&domain)) {
7113                         AgentDomainInfo *info = domain_jit_info (domain)->agent_info;
7114
7115                         /* Update 'source_file_to_class' cache */
7116                         g_hash_table_iter_init (&kiter, info->loaded_classes);
7117                         while (g_hash_table_iter_next (&kiter, NULL, (void**)&klass)) {
7118                                 if (!g_hash_table_lookup (info->source_files, klass)) {
7119                                         files = get_source_files_for_type (klass);
7120                                         g_hash_table_insert (info->source_files, klass, files);
7121
7122                                         for (i = 0; i < files->len; ++i) {
7123                                                 char *s = g_ptr_array_index (files, i);
7124                                                 char *s2 = dbg_path_get_basename (s);
7125                                                 char *s3;
7126
7127                                                 class_list = g_hash_table_lookup (info->source_file_to_class, s2);
7128                                                 if (!class_list) {
7129                                                         class_list = g_slist_prepend (class_list, klass);
7130                                                         g_hash_table_insert (info->source_file_to_class, g_strdup (s2), class_list);
7131                                                 } else {
7132                                                         class_list = g_slist_prepend (class_list, klass);
7133                                                         g_hash_table_insert (info->source_file_to_class, s2, class_list);
7134                                                 }
7135
7136                                                 /* The _ignorecase hash contains the lowercase path */
7137                                                 s3 = strdup_tolower (s2);
7138                                                 class_list = g_hash_table_lookup (info->source_file_to_class_ignorecase, s3);
7139                                                 if (!class_list) {
7140                                                         class_list = g_slist_prepend (class_list, klass);
7141                                                         g_hash_table_insert (info->source_file_to_class_ignorecase, g_strdup (s3), class_list);
7142                                                 } else {
7143                                                         class_list = g_slist_prepend (class_list, klass);
7144                                                         g_hash_table_insert (info->source_file_to_class_ignorecase, s3, class_list);
7145                                                 }
7146
7147                                                 g_free (s2);
7148                                                 g_free (s3);
7149                                         }
7150                                 }
7151                         }
7152
7153                         if (ignore_case) {
7154                                 char *s;
7155
7156                                 s = strdup_tolower (basename);
7157                                 class_list = g_hash_table_lookup (info->source_file_to_class_ignorecase, s);
7158                                 g_free (s);
7159                         } else {
7160                                 class_list = g_hash_table_lookup (info->source_file_to_class, basename);
7161                         }
7162
7163                         for (l = class_list; l; l = l->next) {
7164                                 klass = l->data;
7165
7166                                 g_ptr_array_add (res_classes, klass);
7167                                 g_ptr_array_add (res_domains, domain);
7168                         }
7169                 }
7170                 mono_loader_unlock ();
7171
7172                 g_free (fname);
7173                 g_free (basename);
7174
7175                 buffer_add_int (buf, res_classes->len);
7176                 for (i = 0; i < res_classes->len; ++i)
7177                         buffer_add_typeid (buf, g_ptr_array_index (res_domains, i), g_ptr_array_index (res_classes, i));
7178                 g_ptr_array_free (res_classes, TRUE);
7179                 g_ptr_array_free (res_domains, TRUE);
7180                 break;
7181         }
7182         case CMD_VM_GET_TYPES: {
7183                 GHashTableIter iter;
7184                 MonoDomain *domain;
7185                 int i;
7186                 char *name;
7187                 gboolean ignore_case;
7188                 GPtrArray *res_classes, *res_domains;
7189                 MonoTypeNameParse info;
7190
7191                 name = decode_string (p, &p, end);
7192                 ignore_case = decode_byte (p, &p, end);
7193
7194                 if (!mono_reflection_parse_type (name, &info)) {
7195                         g_free (name);
7196                         mono_reflection_free_type_info (&info);
7197                         return ERR_INVALID_ARGUMENT;
7198                 }
7199
7200                 res_classes = g_ptr_array_new ();
7201                 res_domains = g_ptr_array_new ();
7202
7203                 mono_loader_lock ();
7204                 g_hash_table_iter_init (&iter, domains);
7205                 while (g_hash_table_iter_next (&iter, NULL, (void**)&domain)) {
7206                         MonoAssembly *ass;
7207                         gboolean type_resolve;
7208                         MonoType *t;
7209                         GSList *tmp;
7210
7211                         mono_domain_assemblies_lock (domain);
7212                         for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) {
7213                                 ass = tmp->data;
7214
7215                                 if (ass->image) {
7216                                         type_resolve = TRUE;
7217                                         t = mono_reflection_get_type (ass->image, &info, ignore_case, &type_resolve);
7218                                         if (t) {
7219                                                 g_ptr_array_add (res_classes, mono_type_get_class (t));
7220                                                 g_ptr_array_add (res_domains, domain);
7221                                         }
7222                                 }
7223                         }
7224                         mono_domain_assemblies_unlock (domain);
7225                 }
7226                 mono_loader_unlock ();
7227
7228                 g_free (name);
7229                 mono_reflection_free_type_info (&info);
7230
7231                 buffer_add_int (buf, res_classes->len);
7232                 for (i = 0; i < res_classes->len; ++i)
7233                         buffer_add_typeid (buf, g_ptr_array_index (res_domains, i), g_ptr_array_index (res_classes, i));
7234                 g_ptr_array_free (res_classes, TRUE);
7235                 g_ptr_array_free (res_domains, TRUE);
7236                 break;
7237         }
7238         case CMD_VM_START_BUFFERING:
7239         case CMD_VM_STOP_BUFFERING:
7240                 /* Handled in the main loop */
7241                 break;
7242         default:
7243                 return ERR_NOT_IMPLEMENTED;
7244         }
7245
7246         return ERR_NONE;
7247 }
7248
7249 static ErrorCode
7250 event_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
7251 {
7252         int err;
7253         MonoError error;
7254
7255         switch (command) {
7256         case CMD_EVENT_REQUEST_SET: {
7257                 EventRequest *req;
7258                 int i, event_kind, suspend_policy, nmodifiers, mod;
7259                 MonoMethod *method;
7260                 long location = 0;
7261                 MonoThread *step_thread;
7262                 int size = 0, depth = 0, filter = 0, step_thread_id = 0;
7263                 MonoDomain *domain;
7264                 Modifier *modifier;
7265
7266                 event_kind = decode_byte (p, &p, end);
7267                 suspend_policy = decode_byte (p, &p, end);
7268                 nmodifiers = decode_byte (p, &p, end);
7269
7270                 req = g_malloc0 (sizeof (EventRequest) + (nmodifiers * sizeof (Modifier)));
7271                 req->id = InterlockedIncrement (&event_request_id);
7272                 req->event_kind = event_kind;
7273                 req->suspend_policy = suspend_policy;
7274                 req->nmodifiers = nmodifiers;
7275
7276                 method = NULL;
7277                 for (i = 0; i < nmodifiers; ++i) {
7278                         mod = decode_byte (p, &p, end);
7279
7280                         req->modifiers [i].kind = mod;
7281                         if (mod == MOD_KIND_COUNT) {
7282                                 req->modifiers [i].data.count = decode_int (p, &p, end);
7283                         } else if (mod == MOD_KIND_LOCATION_ONLY) {
7284                                 method = decode_methodid (p, &p, end, &domain, &err);
7285                                 if (err)
7286                                         return err;
7287                                 location = decode_long (p, &p, end);
7288                         } else if (mod == MOD_KIND_STEP) {
7289                                 step_thread_id = decode_id (p, &p, end);
7290                                 size = decode_int (p, &p, end);
7291                                 depth = decode_int (p, &p, end);
7292                                 if (CHECK_PROTOCOL_VERSION (2, 16))
7293                                         filter = decode_int (p, &p, end);
7294                                 req->modifiers [i].data.filter = filter;
7295                                 if (!CHECK_PROTOCOL_VERSION (2, 26) && (req->modifiers [i].data.filter & STEP_FILTER_DEBUGGER_HIDDEN))
7296                                         /* Treat STEP_THOUGH the same as HIDDEN */
7297                                         req->modifiers [i].data.filter |= STEP_FILTER_DEBUGGER_STEP_THROUGH;
7298                         } else if (mod == MOD_KIND_THREAD_ONLY) {
7299                                 int id = decode_id (p, &p, end);
7300
7301                                 err = get_object (id, (MonoObject**)&req->modifiers [i].data.thread);
7302                                 if (err) {
7303                                         g_free (req);
7304                                         return err;
7305                                 }
7306                         } else if (mod == MOD_KIND_EXCEPTION_ONLY) {
7307                                 MonoClass *exc_class = decode_typeid (p, &p, end, &domain, &err);
7308
7309                                 if (err)
7310                                         return err;
7311                                 req->modifiers [i].caught = decode_byte (p, &p, end);
7312                                 req->modifiers [i].uncaught = decode_byte (p, &p, end);
7313                                 if (CHECK_PROTOCOL_VERSION (2, 25))
7314                                         req->modifiers [i].subclasses = decode_byte (p, &p, end);
7315                                 else
7316                                         req->modifiers [i].subclasses = TRUE;
7317                                 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" : "");
7318                                 if (exc_class) {
7319                                         req->modifiers [i].data.exc_class = exc_class;
7320
7321                                         if (!mono_class_is_assignable_from (mono_defaults.exception_class, exc_class)) {
7322                                                 g_free (req);
7323                                                 return ERR_INVALID_ARGUMENT;
7324                                         }
7325                                 }
7326                         } else if (mod == MOD_KIND_ASSEMBLY_ONLY) {
7327                                 int n = decode_int (p, &p, end);
7328                                 int j;
7329
7330                                 req->modifiers [i].data.assemblies = g_new0 (MonoAssembly*, n);
7331                                 for (j = 0; j < n; ++j) {
7332                                         req->modifiers [i].data.assemblies [j] = decode_assemblyid (p, &p, end, &domain, &err);
7333                                         if (err) {
7334                                                 g_free (req->modifiers [i].data.assemblies);
7335                                                 return err;
7336                                         }
7337                                 }
7338                         } else if (mod == MOD_KIND_SOURCE_FILE_ONLY) {
7339                                 int n = decode_int (p, &p, end);
7340                                 int j;
7341
7342                                 modifier = &req->modifiers [i];
7343                                 modifier->data.source_files = g_hash_table_new (g_str_hash, g_str_equal);
7344                                 for (j = 0; j < n; ++j) {
7345                                         char *s = decode_string (p, &p, end);
7346                                         char *s2;
7347
7348                                         if (s) {
7349                                                 s2 = strdup_tolower (s);
7350                                                 g_hash_table_insert (modifier->data.source_files, s2, s2);
7351                                                 g_free (s);
7352                                         }
7353                                 }
7354                         } else if (mod == MOD_KIND_TYPE_NAME_ONLY) {
7355                                 int n = decode_int (p, &p, end);
7356                                 int j;
7357
7358                                 modifier = &req->modifiers [i];
7359                                 modifier->data.type_names = g_hash_table_new (g_str_hash, g_str_equal);
7360                                 for (j = 0; j < n; ++j) {
7361                                         char *s = decode_string (p, &p, end);
7362
7363                                         if (s)
7364                                                 g_hash_table_insert (modifier->data.type_names, s, s);
7365                                 }
7366                         } else {
7367                                 g_free (req);
7368                                 return ERR_NOT_IMPLEMENTED;
7369                         }
7370                 }
7371
7372                 if (req->event_kind == EVENT_KIND_BREAKPOINT) {
7373                         g_assert (method);
7374
7375                         req->info = set_breakpoint (method, location, req, &error);
7376                         if (!mono_error_ok (&error)) {
7377                                 g_free (req);
7378                                 DEBUG_PRINTF (1, "[dbg] Failed to set breakpoint: %s\n", mono_error_get_message (&error));
7379                                 mono_error_cleanup (&error);
7380                                 return ERR_NO_SEQ_POINT_AT_IL_OFFSET;
7381                         }
7382                 } else if (req->event_kind == EVENT_KIND_STEP) {
7383                         g_assert (step_thread_id);
7384
7385                         err = get_object (step_thread_id, (MonoObject**)&step_thread);
7386                         if (err) {
7387                                 g_free (req);
7388                                 return err;
7389                         }
7390
7391                         err = ss_create (THREAD_TO_INTERNAL (step_thread), size, depth, filter, req);
7392                         if (err) {
7393                                 g_free (req);
7394                                 return err;
7395                         }
7396                 } else if (req->event_kind == EVENT_KIND_METHOD_ENTRY) {
7397                         req->info = set_breakpoint (NULL, METHOD_ENTRY_IL_OFFSET, req, NULL);
7398                 } else if (req->event_kind == EVENT_KIND_METHOD_EXIT) {
7399                         req->info = set_breakpoint (NULL, METHOD_EXIT_IL_OFFSET, req, NULL);
7400                 } else if (req->event_kind == EVENT_KIND_EXCEPTION) {
7401                 } else if (req->event_kind == EVENT_KIND_TYPE_LOAD) {
7402                 } else {
7403                         if (req->nmodifiers) {
7404                                 g_free (req);
7405                                 return ERR_NOT_IMPLEMENTED;
7406                         }
7407                 }
7408
7409                 mono_loader_lock ();
7410                 g_ptr_array_add (event_requests, req);
7411                 
7412                 if (agent_config.defer) {
7413                         /* Transmit cached data to the client on receipt of the event request */
7414                         switch (req->event_kind) {
7415                         case EVENT_KIND_APPDOMAIN_CREATE:
7416                                 /* Emit load events for currently loaded domains */
7417                                 g_hash_table_foreach (domains, emit_appdomain_load, NULL);
7418                                 break;
7419                         case EVENT_KIND_ASSEMBLY_LOAD:
7420                                 /* Emit load events for currently loaded assemblies */
7421                                 mono_assembly_foreach (emit_assembly_load, NULL);
7422                                 break;
7423                         case EVENT_KIND_THREAD_START:
7424                                 /* Emit start events for currently started threads */
7425                                 mono_g_hash_table_foreach (tid_to_thread, emit_thread_start, NULL);
7426                                 break;
7427                         case EVENT_KIND_TYPE_LOAD:
7428                                 /* Emit type load events for currently loaded types */
7429                                 mono_domain_foreach (send_types_for_domain, NULL);
7430                                 break;
7431                         default:
7432                                 break;
7433                         }
7434                 }
7435                 mono_loader_unlock ();
7436
7437                 buffer_add_int (buf, req->id);
7438                 break;
7439         }
7440         case CMD_EVENT_REQUEST_CLEAR: {
7441                 int etype = decode_byte (p, &p, end);
7442                 int req_id = decode_int (p, &p, end);
7443
7444                 // FIXME: Make a faster mapping from req_id to request
7445                 mono_loader_lock ();
7446                 clear_event_request (req_id, etype);
7447                 mono_loader_unlock ();
7448                 break;
7449         }
7450         case CMD_EVENT_REQUEST_CLEAR_ALL_BREAKPOINTS: {
7451                 int i;
7452
7453                 mono_loader_lock ();
7454                 i = 0;
7455                 while (i < event_requests->len) {
7456                         EventRequest *req = g_ptr_array_index (event_requests, i);
7457
7458                         if (req->event_kind == EVENT_KIND_BREAKPOINT) {
7459                                 clear_breakpoint (req->info);
7460
7461                                 g_ptr_array_remove_index_fast (event_requests, i);
7462                                 g_free (req);
7463                         } else {
7464                                 i ++;
7465                         }
7466                 }
7467                 mono_loader_unlock ();
7468                 break;
7469         }
7470         default:
7471                 return ERR_NOT_IMPLEMENTED;
7472         }
7473
7474         return ERR_NONE;
7475 }
7476
7477 static ErrorCode
7478 domain_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
7479 {
7480         int err;
7481         MonoDomain *domain;
7482
7483         switch (command) {
7484         case CMD_APPDOMAIN_GET_ROOT_DOMAIN: {
7485                 buffer_add_domainid (buf, mono_get_root_domain ());
7486                 break;
7487         }
7488         case CMD_APPDOMAIN_GET_FRIENDLY_NAME: {
7489                 domain = decode_domainid (p, &p, end, NULL, &err);
7490                 if (err)
7491                         return err;
7492                 buffer_add_string (buf, domain->friendly_name);
7493                 break;
7494         }
7495         case CMD_APPDOMAIN_GET_ASSEMBLIES: {
7496                 GSList *tmp;
7497                 MonoAssembly *ass;
7498                 int count;
7499
7500                 domain = decode_domainid (p, &p, end, NULL, &err);
7501                 if (err)
7502                         return err;
7503                 mono_loader_lock ();
7504                 count = 0;
7505                 for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) {
7506                         count ++;
7507                 }
7508                 buffer_add_int (buf, count);
7509                 for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) {
7510                         ass = tmp->data;
7511                         buffer_add_assemblyid (buf, domain, ass);
7512                 }
7513                 mono_loader_unlock ();
7514                 break;
7515         }
7516         case CMD_APPDOMAIN_GET_ENTRY_ASSEMBLY: {
7517                 domain = decode_domainid (p, &p, end, NULL, &err);
7518                 if (err)
7519                         return err;
7520
7521                 buffer_add_assemblyid (buf, domain, domain->entry_assembly);
7522                 break;
7523         }
7524         case CMD_APPDOMAIN_GET_CORLIB: {
7525                 domain = decode_domainid (p, &p, end, NULL, &err);
7526                 if (err)
7527                         return err;
7528
7529                 buffer_add_assemblyid (buf, domain, domain->domain->mbr.obj.vtable->klass->image->assembly);
7530                 break;
7531         }
7532         case CMD_APPDOMAIN_CREATE_STRING: {
7533                 char *s;
7534                 MonoString *o;
7535
7536                 domain = decode_domainid (p, &p, end, NULL, &err);
7537                 if (err)
7538                         return err;
7539                 s = decode_string (p, &p, end);
7540
7541                 o = mono_string_new (domain, s);
7542                 buffer_add_objid (buf, (MonoObject*)o);
7543                 break;
7544         }
7545         case CMD_APPDOMAIN_CREATE_BOXED_VALUE: {
7546                 MonoClass *klass;
7547                 MonoDomain *domain2;
7548                 MonoObject *o;
7549
7550                 domain = decode_domainid (p, &p, end, NULL, &err);
7551                 if (err)
7552                         return err;
7553                 klass = decode_typeid (p, &p, end, &domain2, &err);
7554                 if (err)
7555                         return err;
7556
7557                 // FIXME:
7558                 g_assert (domain == domain2);
7559
7560                 o = mono_object_new (domain, klass);
7561
7562                 err = decode_value (&klass->byval_arg, domain, mono_object_unbox (o), p, &p, end);
7563                 if (err)
7564                         return err;
7565
7566                 buffer_add_objid (buf, o);
7567                 break;
7568         }
7569         default:
7570                 return ERR_NOT_IMPLEMENTED;
7571         }
7572
7573         return ERR_NONE;
7574 }
7575
7576 static ErrorCode
7577 assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
7578 {
7579         int err;
7580         MonoAssembly *ass;
7581         MonoDomain *domain;
7582
7583         ass = decode_assemblyid (p, &p, end, &domain, &err);
7584         if (err)
7585                 return err;
7586
7587         switch (command) {
7588         case CMD_ASSEMBLY_GET_LOCATION: {
7589                 buffer_add_string (buf, mono_image_get_filename (ass->image));
7590                 break;                  
7591         }
7592         case CMD_ASSEMBLY_GET_ENTRY_POINT: {
7593                 guint32 token;
7594                 MonoMethod *m;
7595
7596                 if (ass->image->dynamic) {
7597                         buffer_add_id (buf, 0);
7598                 } else {
7599                         token = mono_image_get_entry_point (ass->image);
7600                         if (token == 0) {
7601                                 buffer_add_id (buf, 0);
7602                         } else {
7603                                 m = mono_get_method (ass->image, token, NULL);
7604                                 buffer_add_methodid (buf, domain, m);
7605                         }
7606                 }
7607                 break;                  
7608         }
7609         case CMD_ASSEMBLY_GET_MANIFEST_MODULE: {
7610                 buffer_add_moduleid (buf, domain, ass->image);
7611                 break;
7612         }
7613         case CMD_ASSEMBLY_GET_OBJECT: {
7614                 MonoObject *o = (MonoObject*)mono_assembly_get_object (domain, ass);
7615                 buffer_add_objid (buf, o);
7616                 break;
7617         }
7618         case CMD_ASSEMBLY_GET_TYPE: {
7619                 char *s = decode_string (p, &p, end);
7620                 gboolean ignorecase = decode_byte (p, &p, end);
7621                 MonoTypeNameParse info;
7622                 MonoType *t;
7623                 gboolean type_resolve, res;
7624                 MonoDomain *d = mono_domain_get ();
7625
7626                 /* This is needed to be able to find referenced assemblies */
7627                 res = mono_domain_set (domain, FALSE);
7628                 g_assert (res);
7629
7630                 if (!mono_reflection_parse_type (s, &info)) {
7631                         t = NULL;
7632                 } else {
7633                         if (info.assembly.name)
7634                                 NOT_IMPLEMENTED;
7635                         t = mono_reflection_get_type (ass->image, &info, ignorecase, &type_resolve);
7636                 }
7637                 buffer_add_typeid (buf, domain, t ? mono_class_from_mono_type (t) : NULL);
7638                 mono_reflection_free_type_info (&info);
7639                 g_free (s);
7640
7641                 mono_domain_set (d, TRUE);
7642
7643                 break;
7644         }
7645         case CMD_ASSEMBLY_GET_NAME: {
7646                 gchar *name;
7647                 MonoAssembly *mass = ass;
7648
7649                 name = g_strdup_printf (
7650                   "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
7651                   mass->aname.name,
7652                   mass->aname.major, mass->aname.minor, mass->aname.build, mass->aname.revision,
7653                   mass->aname.culture && *mass->aname.culture? mass->aname.culture: "neutral",
7654                   mass->aname.public_key_token [0] ? (char *)mass->aname.public_key_token : "null",
7655                   (mass->aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : "");
7656
7657                 buffer_add_string (buf, name);
7658                 g_free (name);
7659                 break;
7660         }
7661         default:
7662                 return ERR_NOT_IMPLEMENTED;
7663         }
7664
7665         return ERR_NONE;
7666 }
7667
7668 static ErrorCode
7669 module_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
7670 {
7671         int err;
7672         MonoDomain *domain;
7673
7674         switch (command) {
7675         case CMD_MODULE_GET_INFO: {
7676                 MonoImage *image = decode_moduleid (p, &p, end, &domain, &err);
7677                 char *basename;
7678
7679                 basename = g_path_get_basename (image->name);
7680                 buffer_add_string (buf, basename); // name
7681                 buffer_add_string (buf, image->module_name); // scopename
7682                 buffer_add_string (buf, image->name); // fqname
7683                 buffer_add_string (buf, mono_image_get_guid (image)); // guid
7684                 buffer_add_assemblyid (buf, domain, image->assembly); // assembly
7685                 g_free (basename);
7686                 break;                  
7687         }
7688         default:
7689                 return ERR_NOT_IMPLEMENTED;
7690         }
7691
7692         return ERR_NONE;
7693 }
7694
7695 static ErrorCode
7696 field_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
7697 {
7698         int err;
7699         MonoDomain *domain;
7700
7701         switch (command) {
7702         case CMD_FIELD_GET_INFO: {
7703                 MonoClassField *f = decode_fieldid (p, &p, end, &domain, &err);
7704
7705                 buffer_add_string (buf, f->name);
7706                 buffer_add_typeid (buf, domain, f->parent);
7707                 buffer_add_typeid (buf, domain, mono_class_from_mono_type (f->type));
7708                 buffer_add_int (buf, f->type->attrs);
7709                 break;
7710         }
7711         default:
7712                 return ERR_NOT_IMPLEMENTED;
7713         }
7714
7715         return ERR_NONE;
7716 }
7717
7718 static void
7719 buffer_add_cattr_arg (Buffer *buf, MonoType *t, MonoDomain *domain, MonoObject *val)
7720 {
7721         if (val && val->vtable->klass == mono_defaults.monotype_class) {
7722                 /* Special case these so the client doesn't have to handle Type objects */
7723                 
7724                 buffer_add_byte (buf, VALUE_TYPE_ID_TYPE);
7725                 buffer_add_typeid (buf, domain, mono_class_from_mono_type (((MonoReflectionType*)val)->type));
7726         } else if (MONO_TYPE_IS_REFERENCE (t))
7727                 buffer_add_value (buf, t, &val, domain);
7728         else
7729                 buffer_add_value (buf, t, mono_object_unbox (val), domain);
7730 }
7731
7732 static int
7733 buffer_add_cattrs (Buffer *buf, MonoDomain *domain, MonoImage *image, MonoClass *attr_klass, MonoCustomAttrInfo *cinfo)
7734 {
7735         int i, j;
7736         int nattrs = 0;
7737
7738         if (!cinfo) {
7739                 buffer_add_int (buf, 0);
7740                 return ERR_NONE;
7741         }
7742
7743         for (i = 0; i < cinfo->num_attrs; ++i) {
7744                 if (!attr_klass || mono_class_has_parent (cinfo->attrs [i].ctor->klass, attr_klass))
7745                         nattrs ++;
7746         }
7747         buffer_add_int (buf, nattrs);
7748
7749         for (i = 0; i < cinfo->num_attrs; ++i) {
7750                 MonoCustomAttrEntry *attr = &cinfo->attrs [i];
7751                 if (!attr_klass || mono_class_has_parent (attr->ctor->klass, attr_klass)) {
7752                         MonoArray *typed_args, *named_args;
7753                         MonoType *t;
7754                         CattrNamedArg *arginfo = NULL;
7755                         MonoError error;
7756
7757                         mono_reflection_create_custom_attr_data_args (image, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &arginfo, &error);
7758                         if (!mono_error_ok (&error)) {
7759                                 DEBUG_PRINTF (2, "[dbg] mono_reflection_create_custom_attr_data_args () failed with: '%s'\n", mono_error_get_message (&error));
7760                                 mono_error_cleanup (&error);
7761                                 return ERR_LOADER_ERROR;
7762                         }
7763
7764                         buffer_add_methodid (buf, domain, attr->ctor);
7765
7766                         /* Ctor args */
7767                         if (typed_args) {
7768                                 buffer_add_int (buf, mono_array_length (typed_args));
7769                                 for (j = 0; j < mono_array_length (typed_args); ++j) {
7770                                         MonoObject *val = mono_array_get (typed_args, MonoObject*, j);
7771
7772                                         t = mono_method_signature (attr->ctor)->params [j];
7773
7774                                         buffer_add_cattr_arg (buf, t, domain, val);
7775                                 }
7776                         } else {
7777                                 buffer_add_int (buf, 0);
7778                         }
7779
7780                         /* Named args */
7781                         if (named_args) {
7782                                 buffer_add_int (buf, mono_array_length (named_args));
7783
7784                                 for (j = 0; j < mono_array_length (named_args); ++j) {
7785                                         MonoObject *val = mono_array_get (named_args, MonoObject*, j);
7786
7787                                         if (arginfo [j].prop) {
7788                                                 buffer_add_byte (buf, 0x54);
7789                                                 buffer_add_propertyid (buf, domain, arginfo [j].prop);
7790                                         } else if (arginfo [j].field) {
7791                                                 buffer_add_byte (buf, 0x53);
7792                                                 buffer_add_fieldid (buf, domain, arginfo [j].field);
7793                                         } else {
7794                                                 g_assert_not_reached ();
7795                                         }
7796
7797                                         buffer_add_cattr_arg (buf, arginfo [j].type, domain, val);
7798                                 }
7799                         } else {
7800                                 buffer_add_int (buf, 0);
7801                         }
7802                         g_free (arginfo);
7803                 }
7804         }
7805
7806         return ERR_NONE;
7807 }
7808
7809 /* FIXME: Code duplication with icall.c */
7810 static void
7811 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
7812 {
7813         int i;
7814         MonoClass *ic;
7815
7816         mono_class_setup_interfaces (klass, error);
7817         if (!mono_error_ok (error))
7818                 return;
7819
7820         for (i = 0; i < klass->interface_count; i++) {
7821                 ic = klass->interfaces [i];
7822                 g_hash_table_insert (ifaces, ic, ic);
7823
7824                 collect_interfaces (ic, ifaces, error);
7825                 if (!mono_error_ok (error))
7826                         return;
7827         }
7828 }
7829
7830 static ErrorCode
7831 type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint8 *p, guint8 *end, Buffer *buf)
7832 {
7833         MonoClass *nested;
7834         MonoType *type;
7835         gpointer iter;
7836         guint8 b;
7837         int err, nnested;
7838         char *name;
7839
7840         switch (command) {
7841         case CMD_TYPE_GET_INFO: {
7842                 buffer_add_string (buf, klass->name_space);
7843                 buffer_add_string (buf, klass->name);
7844                 // FIXME: byref
7845                 name = mono_type_get_name_full (&klass->byval_arg, MONO_TYPE_NAME_FORMAT_FULL_NAME);
7846                 buffer_add_string (buf, name);
7847                 g_free (name);
7848                 buffer_add_assemblyid (buf, domain, klass->image->assembly);
7849                 buffer_add_moduleid (buf, domain, klass->image);
7850                 buffer_add_typeid (buf, domain, klass->parent);
7851                 if (klass->rank || klass->byval_arg.type == MONO_TYPE_PTR)
7852                         buffer_add_typeid (buf, domain, klass->element_class);
7853                 else
7854                         buffer_add_id (buf, 0);
7855                 buffer_add_int (buf, klass->type_token);
7856                 buffer_add_byte (buf, klass->rank);
7857                 buffer_add_int (buf, klass->flags);
7858                 b = 0;
7859                 type = &klass->byval_arg;
7860                 // FIXME: Can't decide whenever a class represents a byref type
7861                 if (FALSE)
7862                         b |= (1 << 0);
7863                 if (type->type == MONO_TYPE_PTR)
7864                         b |= (1 << 1);
7865                 if (!type->byref && (((type->type >= MONO_TYPE_BOOLEAN) && (type->type <= MONO_TYPE_R8)) || (type->type == MONO_TYPE_I) || (type->type == MONO_TYPE_U)))
7866                         b |= (1 << 2);
7867                 if (type->type == MONO_TYPE_VALUETYPE)
7868                         b |= (1 << 3);
7869                 if (klass->enumtype)
7870                         b |= (1 << 4);
7871                 if (klass->generic_container)
7872                         b |= (1 << 5);
7873                 if (klass->generic_container || klass->generic_class)
7874                         b |= (1 << 6);
7875                 buffer_add_byte (buf, b);
7876                 nnested = 0;
7877                 iter = NULL;
7878                 while ((nested = mono_class_get_nested_types (klass, &iter)))
7879                         nnested ++;
7880                 buffer_add_int (buf, nnested);
7881                 iter = NULL;
7882                 while ((nested = mono_class_get_nested_types (klass, &iter)))
7883                         buffer_add_typeid (buf, domain, nested);
7884                 if (CHECK_PROTOCOL_VERSION (2, 12)) {
7885                         if (klass->generic_container)
7886                                 buffer_add_typeid (buf, domain, klass);
7887                         else if (klass->generic_class)
7888                                 buffer_add_typeid (buf, domain, klass->generic_class->container_class);
7889                         else
7890                                 buffer_add_id (buf, 0);
7891                 }
7892                 if (CHECK_PROTOCOL_VERSION (2, 15)) {
7893                         int count, i;
7894
7895                         if (klass->generic_class) {
7896                                 MonoGenericInst *inst = klass->generic_class->context.class_inst;
7897
7898                                 count = inst->type_argc;
7899                                 buffer_add_int (buf, count);
7900                                 for (i = 0; i < count; i++)
7901                                         buffer_add_typeid (buf, domain, mono_class_from_mono_type (inst->type_argv [i]));
7902                         } else if (klass->generic_container) {
7903                                 MonoGenericContainer *container = klass->generic_container;
7904                                 MonoClass *pklass;
7905
7906                                 count = container->type_argc;
7907                                 buffer_add_int (buf, count);
7908                                 for (i = 0; i < count; i++) {
7909                                         pklass = mono_class_from_generic_parameter (mono_generic_container_get_param (container, i), klass->image, FALSE);
7910                                         buffer_add_typeid (buf, domain, pklass);
7911                                 }
7912                         } else {
7913                                 buffer_add_int (buf, 0);
7914                         }
7915                 }
7916                 break;
7917         }
7918         case CMD_TYPE_GET_METHODS: {
7919                 int nmethods;
7920                 int i = 0;
7921                 gpointer iter = NULL;
7922                 MonoMethod *m;
7923
7924                 mono_class_setup_methods (klass);
7925
7926                 nmethods = mono_class_num_methods (klass);
7927
7928                 buffer_add_int (buf, nmethods);
7929
7930                 while ((m = mono_class_get_methods (klass, &iter))) {
7931                         buffer_add_methodid (buf, domain, m);
7932                         i ++;
7933                 }
7934                 g_assert (i == nmethods);
7935                 break;
7936         }
7937         case CMD_TYPE_GET_FIELDS: {
7938                 int nfields;
7939                 int i = 0;
7940                 gpointer iter = NULL;
7941                 MonoClassField *f;
7942
7943                 nfields = mono_class_num_fields (klass);
7944
7945                 buffer_add_int (buf, nfields);
7946
7947                 while ((f = mono_class_get_fields (klass, &iter))) {
7948                         buffer_add_fieldid (buf, domain, f);
7949                         buffer_add_string (buf, f->name);
7950                         buffer_add_typeid (buf, domain, mono_class_from_mono_type (f->type));
7951                         buffer_add_int (buf, f->type->attrs);
7952                         i ++;
7953                 }
7954                 g_assert (i == nfields);
7955                 break;
7956         }
7957         case CMD_TYPE_GET_PROPERTIES: {
7958                 int nprops;
7959                 int i = 0;
7960                 gpointer iter = NULL;
7961                 MonoProperty *p;
7962
7963                 nprops = mono_class_num_properties (klass);
7964
7965                 buffer_add_int (buf, nprops);
7966
7967                 while ((p = mono_class_get_properties (klass, &iter))) {
7968                         buffer_add_propertyid (buf, domain, p);
7969                         buffer_add_string (buf, p->name);
7970                         buffer_add_methodid (buf, domain, p->get);
7971                         buffer_add_methodid (buf, domain, p->set);
7972                         buffer_add_int (buf, p->attrs);
7973                         i ++;
7974                 }
7975                 g_assert (i == nprops);
7976                 break;
7977         }
7978         case CMD_TYPE_GET_CATTRS: {
7979                 MonoClass *attr_klass;
7980                 MonoCustomAttrInfo *cinfo;
7981
7982                 attr_klass = decode_typeid (p, &p, end, NULL, &err);
7983                 /* attr_klass can be NULL */
7984                 if (err)
7985                         return err;
7986
7987                 cinfo = mono_custom_attrs_from_class (klass);
7988
7989                 err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
7990                 if (err)
7991                         return err;
7992                 break;
7993         }
7994         case CMD_TYPE_GET_FIELD_CATTRS: {
7995                 MonoClass *attr_klass;
7996                 MonoCustomAttrInfo *cinfo;
7997                 MonoClassField *field;
7998
7999                 field = decode_fieldid (p, &p, end, NULL, &err);
8000                 if (err)
8001                         return err;
8002                 attr_klass = decode_typeid (p, &p, end, NULL, &err);
8003                 if (err)
8004                         return err;
8005
8006                 cinfo = mono_custom_attrs_from_field (klass, field);
8007
8008                 err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
8009                 if (err)
8010                         return err;
8011                 break;
8012         }
8013         case CMD_TYPE_GET_PROPERTY_CATTRS: {
8014                 MonoClass *attr_klass;
8015                 MonoCustomAttrInfo *cinfo;
8016                 MonoProperty *prop;
8017
8018                 prop = decode_propertyid (p, &p, end, NULL, &err);
8019                 if (err)
8020                         return err;
8021                 attr_klass = decode_typeid (p, &p, end, NULL, &err);
8022                 if (err)
8023                         return err;
8024
8025                 cinfo = mono_custom_attrs_from_property (klass, prop);
8026
8027                 err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
8028                 if (err)
8029                         return err;
8030                 break;
8031         }
8032         case CMD_TYPE_GET_VALUES:
8033         case CMD_TYPE_GET_VALUES_2: {
8034                 guint8 *val;
8035                 MonoClassField *f;
8036                 MonoVTable *vtable;
8037                 MonoClass *k;
8038                 int len, i;
8039                 gboolean found;
8040                 MonoThread *thread_obj;
8041                 MonoInternalThread *thread = NULL;
8042                 guint32 special_static_type;
8043
8044                 if (command == CMD_TYPE_GET_VALUES_2) {
8045                         int objid = decode_objid (p, &p, end);
8046                         int err;
8047
8048                         err = get_object (objid, (MonoObject**)&thread_obj);
8049                         if (err)
8050                                 return err;
8051
8052                         thread = THREAD_TO_INTERNAL (thread_obj);
8053                 }
8054
8055                 len = decode_int (p, &p, end);
8056                 for (i = 0; i < len; ++i) {
8057                         f = decode_fieldid (p, &p, end, NULL, &err);
8058                         if (err)
8059                                 return err;
8060
8061                         if (!(f->type->attrs & FIELD_ATTRIBUTE_STATIC))
8062                                 return ERR_INVALID_FIELDID;
8063                         special_static_type = mono_class_field_get_special_static_type (f);
8064                         if (special_static_type != SPECIAL_STATIC_NONE) {
8065                                 if (!(thread && special_static_type == SPECIAL_STATIC_THREAD))
8066                                         return ERR_INVALID_FIELDID;
8067                         }
8068
8069                         /* Check that the field belongs to the object */
8070                         found = FALSE;
8071                         for (k = klass; k; k = k->parent) {
8072                                 if (k == f->parent) {
8073                                         found = TRUE;
8074                                         break;
8075                                 }
8076                         }
8077                         if (!found)
8078                                 return ERR_INVALID_FIELDID;
8079
8080                         vtable = mono_class_vtable (domain, f->parent);
8081                         val = g_malloc (mono_class_instance_size (mono_class_from_mono_type (f->type)));
8082                         mono_field_static_get_value_for_thread (thread ? thread : mono_thread_internal_current (), vtable, f, val);
8083                         buffer_add_value (buf, f->type, val, domain);
8084                         g_free (val);
8085                 }
8086                 break;
8087         }
8088         case CMD_TYPE_SET_VALUES: {
8089                 guint8 *val;
8090                 MonoClassField *f;
8091                 MonoVTable *vtable;
8092                 MonoClass *k;
8093                 int len, i;
8094                 gboolean found;
8095
8096                 len = decode_int (p, &p, end);
8097                 for (i = 0; i < len; ++i) {
8098                         f = decode_fieldid (p, &p, end, NULL, &err);
8099                         if (err)
8100                                 return err;
8101
8102                         if (!(f->type->attrs & FIELD_ATTRIBUTE_STATIC))
8103                                 return ERR_INVALID_FIELDID;
8104                         if (mono_class_field_is_special_static (f))
8105                                 return ERR_INVALID_FIELDID;
8106
8107                         /* Check that the field belongs to the object */
8108                         found = FALSE;
8109                         for (k = klass; k; k = k->parent) {
8110                                 if (k == f->parent) {
8111                                         found = TRUE;
8112                                         break;
8113                                 }
8114                         }
8115                         if (!found)
8116                                 return ERR_INVALID_FIELDID;
8117
8118                         // FIXME: Check for literal/const
8119
8120                         vtable = mono_class_vtable (domain, f->parent);
8121                         val = g_malloc (mono_class_instance_size (mono_class_from_mono_type (f->type)));
8122                         err = decode_value (f->type, domain, val, p, &p, end);
8123                         if (err) {
8124                                 g_free (val);
8125                                 return err;
8126                         }
8127                         if (MONO_TYPE_IS_REFERENCE (f->type))
8128                                 mono_field_static_set_value (vtable, f, *(gpointer*)val);
8129                         else
8130                                 mono_field_static_set_value (vtable, f, val);
8131                         g_free (val);
8132                 }
8133                 break;
8134         }
8135         case CMD_TYPE_GET_OBJECT: {
8136                 MonoObject *o = (MonoObject*)mono_type_get_object (domain, &klass->byval_arg);
8137                 buffer_add_objid (buf, o);
8138                 break;
8139         }
8140         case CMD_TYPE_GET_SOURCE_FILES:
8141         case CMD_TYPE_GET_SOURCE_FILES_2: {
8142                 char *source_file, *base;
8143                 GPtrArray *files;
8144                 int i;
8145
8146                 files = get_source_files_for_type (klass);
8147
8148                 buffer_add_int (buf, files->len);
8149                 for (i = 0; i < files->len; ++i) {
8150                         source_file = g_ptr_array_index (files, i);
8151                         if (command == CMD_TYPE_GET_SOURCE_FILES_2) {
8152                                 buffer_add_string (buf, source_file);
8153                         } else {
8154                                 base = dbg_path_get_basename (source_file);
8155                                 buffer_add_string (buf, base);
8156                                 g_free (base);
8157                         }
8158                         g_free (source_file);
8159                 }
8160                 g_ptr_array_free (files, TRUE);
8161                 break;
8162         }
8163         case CMD_TYPE_IS_ASSIGNABLE_FROM: {
8164                 MonoClass *oklass = decode_typeid (p, &p, end, NULL, &err);
8165
8166                 if (err)
8167                         return err;
8168                 if (mono_class_is_assignable_from (klass, oklass))
8169                         buffer_add_byte (buf, 1);
8170                 else
8171                         buffer_add_byte (buf, 0);
8172                 break;
8173         }
8174         case CMD_TYPE_GET_METHODS_BY_NAME_FLAGS: {
8175                 char *name = decode_string (p, &p, end);
8176                 int i, flags = decode_int (p, &p, end);
8177                 MonoException *ex = NULL;
8178                 GPtrArray *array = mono_class_get_methods_by_name (klass, name, flags & ~BINDING_FLAGS_IGNORE_CASE, (flags & BINDING_FLAGS_IGNORE_CASE) != 0, TRUE, &ex);
8179
8180                 if (!array)
8181                         return ERR_LOADER_ERROR;
8182                 buffer_add_int (buf, array->len);
8183                 for (i = 0; i < array->len; ++i) {
8184                         MonoMethod *method = g_ptr_array_index (array, i);
8185                         buffer_add_methodid (buf, domain, method);
8186                 }
8187
8188                 g_ptr_array_free (array, TRUE);
8189                 g_free (name);
8190                 break;
8191         }
8192         case CMD_TYPE_GET_INTERFACES: {
8193                 MonoClass *parent;
8194                 GHashTable *iface_hash = g_hash_table_new (NULL, NULL);
8195                 MonoError error;
8196                 MonoClass *tclass, *iface;
8197                 GHashTableIter iter;
8198
8199                 tclass = klass;
8200
8201                 for (parent = tclass; parent; parent = parent->parent) {
8202                         mono_class_setup_interfaces (parent, &error);
8203                         if (!mono_error_ok (&error))
8204                                 return ERR_LOADER_ERROR;
8205                         collect_interfaces (parent, iface_hash, &error);
8206                         if (!mono_error_ok (&error))
8207                                 return ERR_LOADER_ERROR;
8208                 }
8209
8210                 buffer_add_int (buf, g_hash_table_size (iface_hash));
8211
8212                 g_hash_table_iter_init (&iter, iface_hash);
8213                 while (g_hash_table_iter_next (&iter, NULL, (void**)&iface))
8214                         buffer_add_typeid (buf, domain, iface);
8215                 g_hash_table_destroy (iface_hash);
8216                 break;
8217         }
8218         case CMD_TYPE_GET_INTERFACE_MAP: {
8219                 int tindex, ioffset;
8220                 gboolean variance_used;
8221                 MonoClass *iclass;
8222                 int len, nmethods, i;
8223                 gpointer iter;
8224                 MonoMethod *method;
8225
8226                 len = decode_int (p, &p, end);
8227                 mono_class_setup_vtable (klass);
8228
8229                 for (tindex = 0; tindex < len; ++tindex) {
8230                         iclass = decode_typeid (p, &p, end, NULL, &err);
8231                         if (err)
8232                                 return err;
8233
8234                         ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
8235                         if (ioffset == -1)
8236                                 return ERR_INVALID_ARGUMENT;
8237
8238                         nmethods = mono_class_num_methods (iclass);
8239                         buffer_add_int (buf, nmethods);
8240
8241                         iter = NULL;
8242                         while ((method = mono_class_get_methods (iclass, &iter))) {
8243                                 buffer_add_methodid (buf, domain, method);
8244                         }
8245                         for (i = 0; i < nmethods; ++i)
8246                                 buffer_add_methodid (buf, domain, klass->vtable [i + ioffset]);
8247                 }
8248                 break;
8249         }
8250         case CMD_TYPE_IS_INITIALIZED: {
8251                 MonoVTable *vtable = mono_class_vtable (domain, klass);
8252
8253                 if (vtable)
8254                         buffer_add_int (buf, (vtable->initialized || vtable->init_failed) ? 1 : 0);
8255                 else
8256                         buffer_add_int (buf, 0);
8257                 break;
8258         }
8259         case CMD_TYPE_CREATE_INSTANCE: {
8260                 MonoObject *obj;
8261
8262                 obj = mono_object_new (domain, klass);
8263                 buffer_add_objid (buf, obj);
8264                 break;
8265         }
8266         default:
8267                 return ERR_NOT_IMPLEMENTED;
8268         }
8269
8270         return ERR_NONE;
8271 }
8272
8273 static ErrorCode
8274 type_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
8275 {
8276         MonoClass *klass;
8277         MonoDomain *old_domain;
8278         MonoDomain *domain;
8279         int err;
8280
8281         klass = decode_typeid (p, &p, end, &domain, &err);
8282         if (err)
8283                 return err;
8284
8285         old_domain = mono_domain_get ();
8286
8287         mono_domain_set (domain, TRUE);
8288
8289         err = type_commands_internal (command, klass, domain, p, end, buf);
8290
8291         mono_domain_set (old_domain, TRUE);
8292
8293         return err;
8294 }
8295
8296 static ErrorCode
8297 method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, guint8 *p, guint8 *end, Buffer *buf)
8298 {
8299         MonoMethodHeader *header;
8300         int err;
8301
8302         switch (command) {
8303         case CMD_METHOD_GET_NAME: {
8304                 buffer_add_string (buf, method->name);
8305                 break;                  
8306         }
8307         case CMD_METHOD_GET_DECLARING_TYPE: {
8308                 buffer_add_typeid (buf, domain, method->klass);
8309                 break;
8310         }
8311         case CMD_METHOD_GET_DEBUG_INFO: {
8312                 MonoDebugMethodInfo *minfo;
8313                 char *source_file;
8314                 int i, j, n_il_offsets;
8315                 int *source_files;
8316                 GPtrArray *source_file_list;
8317                 MonoSymSeqPoint *sym_seq_points;
8318
8319                 header = mono_method_get_header (method);
8320                 if (!header) {
8321                         buffer_add_int (buf, 0);
8322                         buffer_add_string (buf, "");
8323                         buffer_add_int (buf, 0);
8324                         break;
8325                 }
8326
8327                 minfo = mono_debug_lookup_method (method);
8328                 if (!minfo) {
8329                         buffer_add_int (buf, header->code_size);
8330                         buffer_add_string (buf, "");
8331                         buffer_add_int (buf, 0);
8332                         mono_metadata_free_mh (header);
8333                         break;
8334                 }
8335
8336                 mono_debug_get_seq_points (minfo, &source_file, &source_file_list, &source_files, &sym_seq_points, &n_il_offsets);
8337                 buffer_add_int (buf, header->code_size);
8338                 if (CHECK_PROTOCOL_VERSION (2, 13)) {
8339                         buffer_add_int (buf, source_file_list->len);
8340                         for (i = 0; i < source_file_list->len; ++i) {
8341                                 MonoDebugSourceInfo *sinfo = g_ptr_array_index (source_file_list, i);
8342                                 buffer_add_string (buf, sinfo->source_file);
8343                                 if (CHECK_PROTOCOL_VERSION (2, 14)) {
8344                                         for (j = 0; j < 16; ++j)
8345                                                 buffer_add_byte (buf, sinfo->hash [j]);
8346                                 }
8347                         }
8348                 } else {
8349                         buffer_add_string (buf, source_file);
8350                 }
8351                 buffer_add_int (buf, n_il_offsets);
8352                 DEBUG_PRINTF (10, "Line number table for method %s:\n", mono_method_full_name (method,  TRUE));
8353                 for (i = 0; i < n_il_offsets; ++i) {
8354                         MonoSymSeqPoint *sp = &sym_seq_points [i];
8355                         const char *srcfile = "";
8356
8357                         if (source_files [i] != -1) {
8358                                 MonoDebugSourceInfo *sinfo = g_ptr_array_index (source_file_list, source_files [i]);
8359                                 srcfile = sinfo->source_file;
8360                         }
8361                         DEBUG_PRINTF (10, "IL%x -> %s:%d %d %d %d\n", sp->il_offset, srcfile, sp->line, sp->column, sp->end_line, sp->end_column);
8362                         buffer_add_int (buf, sp->il_offset);
8363                         buffer_add_int (buf, sp->line);
8364                         if (CHECK_PROTOCOL_VERSION (2, 13))
8365                                 buffer_add_int (buf, source_files [i]);
8366                         if (CHECK_PROTOCOL_VERSION (2, 19))
8367                                 buffer_add_int (buf, sp->column);
8368                         if (CHECK_PROTOCOL_VERSION (2, 32)) {
8369                                 buffer_add_int (buf, sp->end_line);
8370                                 buffer_add_int (buf, sp->end_column);
8371                         }
8372                 }
8373                 g_free (source_file);
8374                 g_free (source_files);
8375                 g_free (sym_seq_points);
8376                 g_ptr_array_free (source_file_list, TRUE);
8377                 mono_metadata_free_mh (header);
8378                 break;
8379         }
8380         case CMD_METHOD_GET_PARAM_INFO: {
8381                 MonoMethodSignature *sig = mono_method_signature (method);
8382                 guint32 i;
8383                 char **names;
8384
8385                 /* FIXME: mono_class_from_mono_type () and byrefs */
8386
8387                 /* FIXME: Use a smaller encoding */
8388                 buffer_add_int (buf, sig->call_convention);
8389                 buffer_add_int (buf, sig->param_count);
8390                 buffer_add_int (buf, sig->generic_param_count);
8391                 buffer_add_typeid (buf, domain, mono_class_from_mono_type (sig->ret));
8392                 for (i = 0; i < sig->param_count; ++i) {
8393                         /* FIXME: vararg */
8394                         buffer_add_typeid (buf, domain, mono_class_from_mono_type (sig->params [i]));
8395                 }
8396
8397                 /* Emit parameter names */
8398                 names = g_new (char *, sig->param_count);
8399                 mono_method_get_param_names (method, (const char **) names);
8400                 for (i = 0; i < sig->param_count; ++i)
8401                         buffer_add_string (buf, names [i]);
8402                 g_free (names);
8403
8404                 break;
8405         }
8406         case CMD_METHOD_GET_LOCALS_INFO: {
8407                 int i, j, num_locals;
8408                 MonoDebugLocalsInfo *locals;
8409                 int *locals_map = NULL;
8410
8411                 header = mono_method_get_header (method);
8412                 if (!header)
8413                         return ERR_INVALID_ARGUMENT;
8414
8415                 locals = mono_debug_lookup_locals (method);
8416                 if (!locals) {
8417                         buffer_add_int (buf, header->num_locals);
8418                         /* Types */
8419                         for (i = 0; i < header->num_locals; ++i) {
8420                                 buffer_add_typeid (buf, domain, mono_class_from_mono_type (header->locals [i]));
8421                         }
8422                         /* Names */
8423                         for (i = 0; i < header->num_locals; ++i) {
8424                                 char lname [128];
8425                                 sprintf (lname, "V_%d", i);
8426                                 buffer_add_string (buf, lname);
8427                         }
8428                         /* Scopes */
8429                         for (i = 0; i < header->num_locals; ++i) {
8430                                 buffer_add_int (buf, 0);
8431                                 buffer_add_int (buf, header->code_size);
8432                         }
8433                 } else {
8434                         /* Maps between the IL locals index and the index in locals->locals */
8435                         locals_map = g_new0 (int, header->num_locals);
8436                         for (i = 0; i < header->num_locals; ++i)
8437                                 locals_map [i] = -1;
8438                         num_locals = locals->num_locals;
8439                         for (i = 0; i < num_locals; ++i) {
8440                                 g_assert (locals->locals [i].index < header->num_locals);
8441                                 locals_map [locals->locals [i].index] = i;
8442                         }
8443                         buffer_add_int (buf, num_locals);
8444
8445                         /* Types */
8446                         for (i = 0; i < header->num_locals; ++i) {
8447                                 if (locals_map [i] != -1)
8448                                         buffer_add_typeid (buf, domain, mono_class_from_mono_type (header->locals [i]));
8449                         }
8450
8451                         /* Names */
8452                         for (i = 0; i < header->num_locals; ++i) {
8453                                 if (locals_map [i] != -1)
8454                                         buffer_add_string (buf, locals->locals [locals_map [i]].name);
8455                         }
8456
8457                         /* Scopes */
8458                         for (i = 0; i < header->num_locals; ++i) {
8459                                 if (locals_map [i] != -1) {
8460                                         j = locals_map [i];
8461                                         if (locals->locals [j].block) {
8462                                                 buffer_add_int (buf, locals->locals [j].block->start_offset);
8463                                                 buffer_add_int (buf, locals->locals [j].block->end_offset);
8464                                         } else {
8465                                                 buffer_add_int (buf, 0);
8466                                                 buffer_add_int (buf, header->code_size);
8467                                         }
8468                                 }
8469                         }
8470                 }
8471                 mono_metadata_free_mh (header);
8472
8473                 if (locals)
8474                         mono_debug_free_locals (locals);
8475                 g_free (locals_map);
8476
8477                 break;
8478         }
8479         case CMD_METHOD_GET_INFO:
8480                 buffer_add_int (buf, method->flags);
8481                 buffer_add_int (buf, method->iflags);
8482                 buffer_add_int (buf, method->token);
8483                 if (CHECK_PROTOCOL_VERSION (2, 12)) {
8484                         guint8 attrs = 0;
8485                         if (method->is_generic)
8486                                 attrs |= (1 << 0);
8487                         if (mono_method_signature (method)->generic_param_count)
8488                                 attrs |= (1 << 1);
8489                         buffer_add_byte (buf, attrs);
8490                         if (method->is_generic || method->is_inflated) {
8491                                 MonoMethod *result;
8492
8493                                 if (method->is_generic) {
8494                                         result = method;
8495                                 } else {
8496                                         MonoMethodInflated *imethod = (MonoMethodInflated *)method;
8497                                         
8498                                         result = imethod->declaring;
8499                                         if (imethod->context.class_inst) {
8500                                                 MonoClass *klass = ((MonoMethod *) imethod)->klass;
8501                                                 /*Generic methods gets the context of the GTD.*/
8502                                                 if (mono_class_get_context (klass)) {
8503                                                         MonoError error;
8504                                                         result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
8505                                                         g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
8506                                                 }
8507                                         }
8508                                 }
8509
8510                                 buffer_add_methodid (buf, domain, result);
8511                         } else {
8512                                 buffer_add_id (buf, 0);
8513                         }
8514                         if (CHECK_PROTOCOL_VERSION (2, 15)) {
8515                                 if (mono_method_signature (method)->generic_param_count) {
8516                                         int count, i;
8517
8518                                         if (method->is_inflated) {
8519                                                 MonoGenericInst *inst = mono_method_get_context (method)->method_inst;
8520                                                 if (inst) {
8521                                                         count = inst->type_argc;
8522                                                         buffer_add_int (buf, count);
8523
8524                                                         for (i = 0; i < count; i++)
8525                                                                 buffer_add_typeid (buf, domain, mono_class_from_mono_type (inst->type_argv [i]));
8526                                                 } else {
8527                                                         buffer_add_int (buf, 0);
8528                                                 }
8529                                         } else if (method->is_generic) {
8530                                                 MonoGenericContainer *container = mono_method_get_generic_container (method);
8531
8532                                                 count = mono_method_signature (method)->generic_param_count;
8533                                                 buffer_add_int (buf, count);
8534                                                 for (i = 0; i < count; i++) {
8535                                                         MonoGenericParam *param = mono_generic_container_get_param (container, i);
8536                                                         MonoClass *pklass = mono_class_from_generic_parameter (param, method->klass->image, TRUE);
8537                                                         buffer_add_typeid (buf, domain, pklass);
8538                                                 }
8539                                         } else {
8540                                                 buffer_add_int (buf, 0);
8541                                         }
8542                                 } else {
8543                                         buffer_add_int (buf, 0);
8544                                 }
8545                         }
8546                 }
8547                 break;
8548         case CMD_METHOD_GET_BODY: {
8549                 int i;
8550
8551                 header = mono_method_get_header (method);
8552                 if (!header) {
8553                         buffer_add_int (buf, 0);
8554
8555                         if (CHECK_PROTOCOL_VERSION (2, 18))
8556                                 buffer_add_int (buf, 0);
8557                 } else {
8558                         buffer_add_int (buf, header->code_size);
8559                         for (i = 0; i < header->code_size; ++i)
8560                                 buffer_add_byte (buf, header->code [i]);
8561
8562                         if (CHECK_PROTOCOL_VERSION (2, 18)) {
8563                                 buffer_add_int (buf, header->num_clauses);
8564                                 for (i = 0; i < header->num_clauses; ++i) {
8565                                         MonoExceptionClause *clause = &header->clauses [i];
8566
8567                                         buffer_add_int (buf, clause->flags);
8568                                         buffer_add_int (buf, clause->try_offset);
8569                                         buffer_add_int (buf, clause->try_len);
8570                                         buffer_add_int (buf, clause->handler_offset);
8571                                         buffer_add_int (buf, clause->handler_len);
8572                                         if (clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
8573                                                 buffer_add_typeid (buf, domain, clause->data.catch_class);
8574                                         else if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER)
8575                                                 buffer_add_int (buf, clause->data.filter_offset);
8576                                 }
8577                         }
8578
8579                         mono_metadata_free_mh (header);
8580                 }
8581
8582                 break;
8583         }
8584         case CMD_METHOD_RESOLVE_TOKEN: {
8585                 guint32 token = decode_int (p, &p, end);
8586
8587                 // FIXME: Generics
8588                 switch (mono_metadata_token_code (token)) {
8589                 case MONO_TOKEN_STRING: {
8590                         MonoString *s;
8591                         char *s2;
8592
8593                         s = mono_ldstr (domain, method->klass->image, mono_metadata_token_index (token));
8594                         g_assert (s);
8595
8596                         s2 = mono_string_to_utf8 (s);
8597
8598                         buffer_add_byte (buf, TOKEN_TYPE_STRING);
8599                         buffer_add_string (buf, s2);
8600                         g_free (s2);
8601                         break;
8602                 }
8603                 default: {
8604                         gpointer val;
8605                         MonoClass *handle_class;
8606
8607                         if (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD) {
8608                                 val = mono_method_get_wrapper_data (method, token);
8609                                 handle_class = mono_method_get_wrapper_data (method, token + 1);
8610
8611                                 if (handle_class == NULL) {
8612                                         // Can't figure out the token type
8613                                         buffer_add_byte (buf, TOKEN_TYPE_UNKNOWN);
8614                                         break;
8615                                 }
8616                         } else {
8617                                 MonoError error;
8618                                 val = mono_ldtoken_checked (method->klass->image, token, &handle_class, NULL, &error);
8619                                 if (!val)
8620                                         g_error ("Could not load token due to %s", mono_error_get_message (&error));
8621                         }
8622
8623                         if (handle_class == mono_defaults.typehandle_class) {
8624                                 buffer_add_byte (buf, TOKEN_TYPE_TYPE);
8625                                 if (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD)
8626                                         buffer_add_typeid (buf, domain, (MonoClass *) val);
8627                                 else
8628                                         buffer_add_typeid (buf, domain, mono_class_from_mono_type ((MonoType*)val));
8629                         } else if (handle_class == mono_defaults.fieldhandle_class) {
8630                                 buffer_add_byte (buf, TOKEN_TYPE_FIELD);
8631                                 buffer_add_fieldid (buf, domain, val);
8632                         } else if (handle_class == mono_defaults.methodhandle_class) {
8633                                 buffer_add_byte (buf, TOKEN_TYPE_METHOD);
8634                                 buffer_add_methodid (buf, domain, val);
8635                         } else if (handle_class == mono_defaults.string_class) {
8636                                 char *s;
8637
8638                                 s = mono_string_to_utf8 (val);
8639                                 buffer_add_byte (buf, TOKEN_TYPE_STRING);
8640                                 buffer_add_string (buf, s);
8641                                 g_free (s);
8642                         } else {
8643                                 g_assert_not_reached ();
8644                         }
8645                         break;
8646                 }
8647                 }
8648                 break;
8649         }
8650         case CMD_METHOD_GET_CATTRS: {
8651                 MonoClass *attr_klass;
8652                 MonoCustomAttrInfo *cinfo;
8653
8654                 attr_klass = decode_typeid (p, &p, end, NULL, &err);
8655                 /* attr_klass can be NULL */
8656                 if (err)
8657                         return err;
8658
8659                 cinfo = mono_custom_attrs_from_method (method);
8660
8661                 err = buffer_add_cattrs (buf, domain, method->klass->image, attr_klass, cinfo);
8662                 if (err)
8663                         return err;
8664                 break;
8665         }
8666         case CMD_METHOD_MAKE_GENERIC_METHOD: {
8667                 MonoError error;
8668                 MonoType **type_argv;
8669                 int i, type_argc;
8670                 MonoDomain *d;
8671                 MonoClass *klass;
8672                 MonoGenericInst *ginst;
8673                 MonoGenericContext tmp_context;
8674                 MonoMethod *inflated;
8675
8676                 type_argc = decode_int (p, &p, end);
8677                 type_argv = g_new0 (MonoType*, type_argc);
8678                 for (i = 0; i < type_argc; ++i) {
8679                         klass = decode_typeid (p, &p, end, &d, &err);
8680                         if (err) {
8681                                 g_free (type_argv);
8682                                 return err;
8683                         }
8684                         if (domain != d) {
8685                                 g_free (type_argv);
8686                                 return ERR_INVALID_ARGUMENT;
8687                         }
8688                         type_argv [i] = &klass->byval_arg;
8689                 }
8690                 ginst = mono_metadata_get_generic_inst (type_argc, type_argv);
8691                 g_free (type_argv);
8692                 tmp_context.class_inst = method->klass->generic_class ? method->klass->generic_class->context.class_inst : NULL;
8693                 tmp_context.method_inst = ginst;
8694
8695                 inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, &error);
8696                 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
8697                 if (!mono_verifier_is_method_valid_generic_instantiation (inflated))
8698                         return ERR_INVALID_ARGUMENT;
8699                 buffer_add_methodid (buf, domain, inflated);
8700                 break;
8701         }
8702         default:
8703                 return ERR_NOT_IMPLEMENTED;
8704         }
8705
8706         return ERR_NONE;
8707 }
8708
8709 static ErrorCode
8710 method_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
8711 {
8712         int err;
8713         MonoDomain *old_domain;
8714         MonoDomain *domain;
8715         MonoMethod *method;
8716
8717         method = decode_methodid (p, &p, end, &domain, &err);
8718         if (err)
8719                 return err;
8720
8721         old_domain = mono_domain_get ();
8722
8723         mono_domain_set (domain, TRUE);
8724
8725         err = method_commands_internal (command, method, domain, p, end, buf);
8726
8727         mono_domain_set (old_domain, TRUE);
8728
8729         return err;
8730 }
8731
8732 static ErrorCode
8733 thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
8734 {
8735         int objid = decode_objid (p, &p, end);
8736         int err;
8737         MonoThread *thread_obj;
8738         MonoInternalThread *thread;
8739
8740         err = get_object (objid, (MonoObject**)&thread_obj);
8741         if (err)
8742                 return err;
8743
8744         thread = THREAD_TO_INTERNAL (thread_obj);
8745            
8746         switch (command) {
8747         case CMD_THREAD_GET_NAME: {
8748                 guint32 name_len;
8749                 gunichar2 *s = mono_thread_get_name (thread, &name_len);
8750
8751                 if (!s) {
8752                         buffer_add_int (buf, 0);
8753                 } else {
8754                         char *name;
8755                         glong len;
8756
8757                         name = g_utf16_to_utf8 (s, name_len, NULL, &len, NULL);
8758                         g_assert (name);
8759                         buffer_add_int (buf, len);
8760                         buffer_add_data (buf, (guint8*)name, len);
8761                         g_free (s);
8762                 }
8763                 break;
8764         }
8765         case CMD_THREAD_GET_FRAME_INFO: {
8766                 DebuggerTlsData *tls;
8767                 int i, start_frame, length;
8768
8769                 // Wait for suspending if it already started
8770                 // FIXME: Races with suspend_count
8771                 while (!is_suspended ()) {
8772                         if (suspend_count)
8773                                 wait_for_suspend ();
8774                 }
8775                 /*
8776                 if (suspend_count)
8777                         wait_for_suspend ();
8778                 if (!is_suspended ())
8779                         return ERR_NOT_SUSPENDED;
8780                 */
8781
8782                 start_frame = decode_int (p, &p, end);
8783                 length = decode_int (p, &p, end);
8784
8785                 if (start_frame != 0 || length != -1)
8786                         return ERR_NOT_IMPLEMENTED;
8787
8788                 mono_loader_lock ();
8789                 tls = mono_g_hash_table_lookup (thread_to_tls, thread);
8790                 mono_loader_unlock ();
8791                 g_assert (tls);
8792
8793                 compute_frame_info (thread, tls);
8794
8795                 buffer_add_int (buf, tls->frame_count);
8796                 for (i = 0; i < tls->frame_count; ++i) {
8797                         buffer_add_int (buf, tls->frames [i]->id);
8798                         buffer_add_methodid (buf, tls->frames [i]->domain, tls->frames [i]->actual_method);
8799                         buffer_add_int (buf, tls->frames [i]->il_offset);
8800                         /*
8801                          * Instead of passing the frame type directly to the client, we associate
8802                          * it with the previous frame using a set of flags. This avoids lots of
8803                          * conditional code in the client, since a frame whose type isn't 
8804                          * FRAME_TYPE_MANAGED has no method, location, etc.
8805                          */
8806                         buffer_add_byte (buf, tls->frames [i]->flags);
8807                 }
8808
8809                 break;
8810         }
8811         case CMD_THREAD_GET_STATE:
8812                 buffer_add_int (buf, thread->state);
8813                 break;
8814         case CMD_THREAD_GET_INFO:
8815                 buffer_add_byte (buf, thread->threadpool_thread);
8816                 break;
8817         case CMD_THREAD_GET_ID:
8818                 buffer_add_long (buf, (guint64)(gsize)thread);
8819                 break;
8820         case CMD_THREAD_GET_TID:
8821                 buffer_add_long (buf, (guint64)thread->tid);
8822                 break;
8823         case CMD_THREAD_SET_IP: {
8824                 DebuggerTlsData *tls;
8825                 MonoMethod *method;
8826                 MonoDomain *domain;
8827                 MonoSeqPointInfo *seq_points;
8828                 SeqPoint sp;
8829                 gboolean found_sp;
8830                 gint64 il_offset;
8831
8832                 method = decode_methodid (p, &p, end, &domain, &err);
8833                 if (err)
8834                         return err;
8835                 il_offset = decode_long (p, &p, end);
8836
8837                 while (!is_suspended ()) {
8838                         if (suspend_count)
8839                                 wait_for_suspend ();
8840                 }
8841
8842                 mono_loader_lock ();
8843                 tls = mono_g_hash_table_lookup (thread_to_tls, thread);
8844                 mono_loader_unlock ();
8845                 g_assert (tls);
8846
8847                 compute_frame_info (thread, tls);
8848                 if (tls->frame_count == 0 || tls->frames [0]->actual_method != method)
8849                         return ERR_INVALID_ARGUMENT;
8850
8851                 found_sp = mono_find_seq_point (domain, method, il_offset, &seq_points, &sp);
8852
8853                 g_assert (seq_points);
8854
8855                 if (!found_sp)
8856                         return ERR_INVALID_ARGUMENT;
8857
8858                 // FIXME: Check that the ip change is safe
8859
8860                 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);
8861                 MONO_CONTEXT_SET_IP (&tls->restore_state.ctx, (guint8*)tls->frames [0]->ji->code_start + sp.native_offset);
8862                 break;
8863         }
8864         default:
8865                 return ERR_NOT_IMPLEMENTED;
8866         }
8867
8868         return ERR_NONE;
8869 }
8870
8871 static ErrorCode
8872 frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
8873 {
8874         int objid;
8875         int err;
8876         MonoThread *thread_obj;
8877         MonoInternalThread *thread;
8878         int pos, i, len, frame_idx;
8879         DebuggerTlsData *tls;
8880         StackFrame *frame;
8881         MonoDebugMethodJitInfo *jit;
8882         MonoMethodSignature *sig;
8883         gssize id;
8884         MonoMethodHeader *header;
8885
8886         objid = decode_objid (p, &p, end);
8887         err = get_object (objid, (MonoObject**)&thread_obj);
8888         if (err)
8889                 return err;
8890
8891         thread = THREAD_TO_INTERNAL (thread_obj);
8892
8893         id = decode_id (p, &p, end);
8894
8895         mono_loader_lock ();
8896         tls = mono_g_hash_table_lookup (thread_to_tls, thread);
8897         mono_loader_unlock ();
8898         g_assert (tls);
8899
8900         for (i = 0; i < tls->frame_count; ++i) {
8901                 if (tls->frames [i]->id == id)
8902                         break;
8903         }
8904         if (i == tls->frame_count)
8905                 return ERR_INVALID_FRAMEID;
8906
8907         frame_idx = i;
8908         frame = tls->frames [frame_idx];
8909
8910         /* This is supported for frames without has_ctx etc. set */
8911         if (command == CMD_STACK_FRAME_GET_DOMAIN) {
8912                 if (CHECK_PROTOCOL_VERSION (2, 38))
8913                         buffer_add_domainid (buf, frame->domain);
8914                 return ERR_NONE;
8915         }
8916
8917         if (!frame->has_ctx)
8918                 return ERR_ABSENT_INFORMATION;
8919
8920         if (!frame->jit) {
8921                 frame->jit = mono_debug_find_method (frame->api_method, frame->domain);
8922                 if (!frame->jit && frame->api_method->is_inflated)
8923                         frame->jit = mono_debug_find_method (mono_method_get_declaring_generic_method (frame->api_method), frame->domain);
8924                 if (!frame->jit) {
8925                         char *s;
8926
8927                         /* This could happen for aot images with no jit debug info */
8928                         s = mono_method_full_name (frame->api_method, TRUE);
8929                         DEBUG_PRINTF (1, "[dbg] No debug information found for '%s'.\n", s);
8930                         g_free (s);
8931                         return ERR_ABSENT_INFORMATION;
8932                 }
8933         }
8934         jit = frame->jit;
8935
8936         sig = mono_method_signature (frame->actual_method);
8937
8938         if (!mono_get_seq_points (frame->domain, frame->actual_method))
8939                 /*
8940                  * The method is probably from an aot image compiled without soft-debug, variables might be dead, etc.
8941                  */
8942                 return ERR_ABSENT_INFORMATION;
8943
8944         switch (command) {
8945         case CMD_STACK_FRAME_GET_VALUES: {
8946                 len = decode_int (p, &p, end);
8947                 header = mono_method_get_header (frame->actual_method);
8948
8949                 for (i = 0; i < len; ++i) {
8950                         pos = decode_int (p, &p, end);
8951
8952                         if (pos < 0) {
8953                                 pos = - pos - 1;
8954
8955                                 DEBUG_PRINTF (4, "[dbg]   send arg %d.\n", pos);
8956
8957                                 g_assert (pos >= 0 && pos < jit->num_params);
8958
8959                                 add_var (buf, jit, sig->params [pos], &jit->params [pos], &frame->ctx, frame->domain, FALSE);
8960                         } else {
8961                                 MonoDebugLocalsInfo *locals;
8962
8963                                 locals = mono_debug_lookup_locals (frame->method);
8964                                 if (locals) {
8965                                         g_assert (pos < locals->num_locals);
8966                                         pos = locals->locals [pos].index;
8967                                         mono_debug_free_locals (locals);
8968                                 }
8969                                 g_assert (pos >= 0 && pos < jit->num_locals);
8970
8971                                 DEBUG_PRINTF (4, "[dbg]   send local %d.\n", pos);
8972
8973                                 add_var (buf, jit, header->locals [pos], &jit->locals [pos], &frame->ctx, frame->domain, FALSE);
8974                         }
8975                 }
8976                 mono_metadata_free_mh (header);
8977                 break;
8978         }
8979         case CMD_STACK_FRAME_GET_THIS: {
8980                 if (frame->api_method->klass->valuetype) {
8981                         if (!sig->hasthis) {
8982                                 MonoObject *p = NULL;
8983                                 buffer_add_value (buf, &mono_defaults.object_class->byval_arg, &p, frame->domain);
8984                         } else {
8985                                 add_var (buf, jit, &frame->actual_method->klass->this_arg, jit->this_var, &frame->ctx, frame->domain, TRUE);
8986                         }
8987                 } else {
8988                         if (!sig->hasthis) {
8989                                 MonoObject *p = NULL;
8990                                 buffer_add_value (buf, &frame->actual_method->klass->byval_arg, &p, frame->domain);
8991                         } else {
8992                                 add_var (buf, jit, &frame->api_method->klass->byval_arg, jit->this_var, &frame->ctx, frame->domain, TRUE);
8993                         }
8994                 }
8995                 break;
8996         }
8997         case CMD_STACK_FRAME_SET_VALUES: {
8998                 guint8 *val_buf;
8999                 MonoType *t;
9000                 MonoDebugVarInfo *var;
9001
9002                 len = decode_int (p, &p, end);
9003                 header = mono_method_get_header (frame->actual_method);
9004
9005                 for (i = 0; i < len; ++i) {
9006                         pos = decode_int (p, &p, end);
9007
9008                         if (pos < 0) {
9009                                 pos = - pos - 1;
9010
9011                                 g_assert (pos >= 0 && pos < jit->num_params);
9012
9013                                 t = sig->params [pos];
9014                                 var = &jit->params [pos];
9015                         } else {
9016                                 MonoDebugLocalsInfo *locals;
9017
9018                                 locals = mono_debug_lookup_locals (frame->method);
9019                                 if (locals) {
9020                                         g_assert (pos < locals->num_locals);
9021                                         pos = locals->locals [pos].index;
9022                                         mono_debug_free_locals (locals);
9023                                 }
9024                                 g_assert (pos >= 0 && pos < jit->num_locals);
9025
9026                                 t = header->locals [pos];
9027                                 var = &jit->locals [pos];
9028                         }
9029
9030                         if (MONO_TYPE_IS_REFERENCE (t))
9031                                 val_buf = g_alloca (sizeof (MonoObject*));
9032                         else
9033                                 val_buf = g_alloca (mono_class_instance_size (mono_class_from_mono_type (t)));
9034                         err = decode_value (t, frame->domain, val_buf, p, &p, end);
9035                         if (err)
9036                                 return err;
9037
9038                         set_var (t, var, &frame->ctx, frame->domain, val_buf, frame->reg_locations, &tls->restore_state.ctx);
9039                 }
9040                 mono_metadata_free_mh (header);
9041                 break;
9042         }
9043         case CMD_STACK_FRAME_GET_DOMAIN: {
9044                 if (CHECK_PROTOCOL_VERSION (2, 38))
9045                         buffer_add_domainid (buf, frame->domain);
9046                 break;
9047         }
9048         default:
9049                 return ERR_NOT_IMPLEMENTED;
9050         }
9051
9052         return ERR_NONE;
9053 }
9054
9055 static ErrorCode
9056 array_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
9057 {
9058         MonoArray *arr;
9059         int objid, err, index, len, i, esize;
9060         gpointer elem;
9061
9062         objid = decode_objid (p, &p, end);
9063         err = get_object (objid, (MonoObject**)&arr);
9064         if (err)
9065                 return err;
9066
9067         switch (command) {
9068         case CMD_ARRAY_REF_GET_LENGTH:
9069                 buffer_add_int (buf, arr->obj.vtable->klass->rank);
9070                 if (!arr->bounds) {
9071                         buffer_add_int (buf, arr->max_length);
9072                         buffer_add_int (buf, 0);
9073                 } else {
9074                         for (i = 0; i < arr->obj.vtable->klass->rank; ++i) {
9075                                 buffer_add_int (buf, arr->bounds [i].length);
9076                                 buffer_add_int (buf, arr->bounds [i].lower_bound);
9077                         }
9078                 }
9079                 break;
9080         case CMD_ARRAY_REF_GET_VALUES:
9081                 index = decode_int (p, &p, end);
9082                 len = decode_int (p, &p, end);
9083
9084                 g_assert (index >= 0 && len >= 0);
9085                 // Reordered to avoid integer overflow
9086                 g_assert (!(index > arr->max_length - len));
9087
9088                 esize = mono_array_element_size (arr->obj.vtable->klass);
9089                 for (i = index; i < index + len; ++i) {
9090                         elem = (gpointer*)((char*)arr->vector + (i * esize));
9091                         buffer_add_value (buf, &arr->obj.vtable->klass->element_class->byval_arg, elem, arr->obj.vtable->domain);
9092                 }
9093                 break;
9094         case CMD_ARRAY_REF_SET_VALUES:
9095                 index = decode_int (p, &p, end);
9096                 len = decode_int (p, &p, end);
9097
9098                 g_assert (index >= 0 && len >= 0);
9099                 // Reordered to avoid integer overflow
9100                 g_assert (!(index > arr->max_length - len));
9101
9102                 esize = mono_array_element_size (arr->obj.vtable->klass);
9103                 for (i = index; i < index + len; ++i) {
9104                         elem = (gpointer*)((char*)arr->vector + (i * esize));
9105
9106                         decode_value (&arr->obj.vtable->klass->element_class->byval_arg, arr->obj.vtable->domain, elem, p, &p, end);
9107                 }
9108                 break;
9109         default:
9110                 return ERR_NOT_IMPLEMENTED;
9111         }
9112
9113         return ERR_NONE;
9114 }
9115
9116 static ErrorCode
9117 string_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
9118 {
9119         int objid, err;
9120         MonoString *str;
9121         char *s;
9122         int i, index, length;
9123         gunichar2 *c;
9124         gboolean use_utf16 = FALSE;
9125
9126         objid = decode_objid (p, &p, end);
9127         err = get_object (objid, (MonoObject**)&str);
9128         if (err)
9129                 return err;
9130
9131         switch (command) {
9132         case CMD_STRING_REF_GET_VALUE:
9133                 if (CHECK_PROTOCOL_VERSION (2, 41)) {
9134                         for (i = 0; i < mono_string_length (str); ++i)
9135                                 if (mono_string_chars (str)[i] == 0)
9136                                         use_utf16 = TRUE;
9137                         buffer_add_byte (buf, use_utf16 ? 1 : 0);
9138                 }
9139                 if (use_utf16) {
9140                         buffer_add_int (buf, mono_string_length (str) * 2);
9141                         buffer_add_data (buf, (guint8*)mono_string_chars (str), mono_string_length (str) * 2);
9142                 } else {
9143                         s = mono_string_to_utf8 (str);
9144                         buffer_add_string (buf, s);
9145                         g_free (s);
9146                 }
9147                 break;
9148         case CMD_STRING_REF_GET_LENGTH:
9149                 buffer_add_long (buf, mono_string_length (str));
9150                 break;
9151         case CMD_STRING_REF_GET_CHARS:
9152                 index = decode_long (p, &p, end);
9153                 length = decode_long (p, &p, end);
9154                 if (index > mono_string_length (str) - length)
9155                         return ERR_INVALID_ARGUMENT;
9156                 c = mono_string_chars (str) + index;
9157                 for (i = 0; i < length; ++i)
9158                         buffer_add_short (buf, c [i]);
9159                 break;
9160         default:
9161                 return ERR_NOT_IMPLEMENTED;
9162         }
9163
9164         return ERR_NONE;
9165 }
9166
9167 static ErrorCode
9168 object_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
9169 {
9170         int objid, err;
9171         MonoObject *obj;
9172         int len, i;
9173         MonoClassField *f;
9174         MonoClass *k;
9175         gboolean found;
9176
9177         if (command == CMD_OBJECT_REF_IS_COLLECTED) {
9178                 objid = decode_objid (p, &p, end);
9179                 err = get_object (objid, &obj);
9180                 if (err)
9181                         buffer_add_int (buf, 1);
9182                 else
9183                         buffer_add_int (buf, 0);
9184                 return 0;
9185         }
9186
9187         objid = decode_objid (p, &p, end);
9188         err = get_object (objid, &obj);
9189         if (err)
9190                 return err;
9191
9192         MonoClass *obj_type;
9193
9194         obj_type = obj->vtable->klass;
9195         if (mono_class_is_transparent_proxy (obj_type))
9196                 obj_type = ((MonoTransparentProxy *)obj)->remote_class->proxy_class;
9197
9198         g_assert (obj_type);
9199
9200         switch (command) {
9201         case CMD_OBJECT_REF_GET_TYPE:
9202                 /* This handles transparent proxies too */
9203                 buffer_add_typeid (buf, obj->vtable->domain, mono_class_from_mono_type (((MonoReflectionType*)obj->vtable->type)->type));
9204                 break;
9205         case CMD_OBJECT_REF_GET_VALUES:
9206                 len = decode_int (p, &p, end);
9207
9208                 for (i = 0; i < len; ++i) {
9209                         MonoClassField *f = decode_fieldid (p, &p, end, NULL, &err);
9210                         if (err)
9211                                 return err;
9212
9213                         /* Check that the field belongs to the object */
9214                         found = FALSE;
9215                         for (k = obj_type; k; k = k->parent) {
9216                                 if (k == f->parent) {
9217                                         found = TRUE;
9218                                         break;
9219                                 }
9220                         }
9221                         if (!found)
9222                                 return ERR_INVALID_FIELDID;
9223
9224                         if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) {
9225                                 guint8 *val;
9226                                 MonoVTable *vtable;
9227
9228                                 if (mono_class_field_is_special_static (f))
9229                                         return ERR_INVALID_FIELDID;
9230
9231                                 g_assert (f->type->attrs & FIELD_ATTRIBUTE_STATIC);
9232                                 vtable = mono_class_vtable (obj->vtable->domain, f->parent);
9233                                 val = g_malloc (mono_class_instance_size (mono_class_from_mono_type (f->type)));
9234                                 mono_field_static_get_value (vtable, f, val);
9235                                 buffer_add_value (buf, f->type, val, obj->vtable->domain);
9236                                 g_free (val);
9237                         } else {
9238                                 buffer_add_value (buf, f->type, (guint8*)obj + f->offset, obj->vtable->domain);
9239                         }
9240                 }
9241                 break;
9242         case CMD_OBJECT_REF_SET_VALUES:
9243                 len = decode_int (p, &p, end);
9244
9245                 for (i = 0; i < len; ++i) {
9246                         f = decode_fieldid (p, &p, end, NULL, &err);
9247                         if (err)
9248                                 return err;
9249
9250                         /* Check that the field belongs to the object */
9251                         found = FALSE;
9252                         for (k = obj_type; k; k = k->parent) {
9253                                 if (k == f->parent) {
9254                                         found = TRUE;
9255                                         break;
9256                                 }
9257                         }
9258                         if (!found)
9259                                 return ERR_INVALID_FIELDID;
9260
9261                         if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) {
9262                                 guint8 *val;
9263                                 MonoVTable *vtable;
9264
9265                                 if (mono_class_field_is_special_static (f))
9266                                         return ERR_INVALID_FIELDID;
9267
9268                                 g_assert (f->type->attrs & FIELD_ATTRIBUTE_STATIC);
9269                                 vtable = mono_class_vtable (obj->vtable->domain, f->parent);
9270
9271                                 val = g_malloc (mono_class_instance_size (mono_class_from_mono_type (f->type)));
9272                                 err = decode_value (f->type, obj->vtable->domain, val, p, &p, end);
9273                                 if (err) {
9274                                         g_free (val);
9275                                         return err;
9276                                 }
9277                                 mono_field_static_set_value (vtable, f, val);
9278                                 g_free (val);
9279                         } else {
9280                                 err = decode_value (f->type, obj->vtable->domain, (guint8*)obj + f->offset, p, &p, end);
9281                                 if (err)
9282                                         return err;
9283                         }
9284                 }
9285                 break;
9286         case CMD_OBJECT_REF_GET_ADDRESS:
9287                 buffer_add_long (buf, (gssize)obj);
9288                 break;
9289         case CMD_OBJECT_REF_GET_DOMAIN:
9290                 buffer_add_domainid (buf, obj->vtable->domain);
9291                 break;
9292         case CMD_OBJECT_REF_GET_INFO:
9293                 buffer_add_typeid (buf, obj->vtable->domain, mono_class_from_mono_type (((MonoReflectionType*)obj->vtable->type)->type));
9294                 buffer_add_domainid (buf, obj->vtable->domain);
9295                 break;
9296         default:
9297                 return ERR_NOT_IMPLEMENTED;
9298         }
9299
9300         return ERR_NONE;
9301 }
9302
9303 static const char*
9304 command_set_to_string (CommandSet command_set)
9305 {
9306         switch (command_set) {
9307         case CMD_SET_VM:
9308                 return "VM";
9309         case CMD_SET_OBJECT_REF:
9310                 return "OBJECT_REF";
9311         case CMD_SET_STRING_REF:
9312                 return "STRING_REF";
9313         case CMD_SET_THREAD:
9314                 return "THREAD";
9315         case CMD_SET_ARRAY_REF:
9316                 return "ARRAY_REF";
9317         case CMD_SET_EVENT_REQUEST:
9318                 return "EVENT_REQUEST";
9319         case CMD_SET_STACK_FRAME:
9320                 return "STACK_FRAME";
9321         case CMD_SET_APPDOMAIN:
9322                 return "APPDOMAIN";
9323         case CMD_SET_ASSEMBLY:
9324                 return "ASSEMBLY";
9325         case CMD_SET_METHOD:
9326                 return "METHOD";
9327         case CMD_SET_TYPE:
9328                 return "TYPE";
9329         case CMD_SET_MODULE:
9330                 return "MODULE";
9331         case CMD_SET_FIELD:
9332                 return "FIELD";
9333         case CMD_SET_EVENT:
9334                 return "EVENT";
9335         default:
9336                 return "";
9337         }
9338 }
9339
9340 static const char* vm_cmds_str [] = {
9341         "VERSION",
9342         "ALL_THREADS",
9343         "SUSPEND",
9344         "RESUME",
9345         "EXIT",
9346         "DISPOSE",
9347         "INVOKE_METHOD",
9348         "SET_PROTOCOL_VERSION",
9349         "ABORT_INVOKE",
9350         "SET_KEEPALIVE"
9351         "GET_TYPES_FOR_SOURCE_FILE",
9352         "GET_TYPES",
9353         "INVOKE_METHODS"
9354 };
9355
9356 static const char* thread_cmds_str[] = {
9357         "GET_FRAME_INFO",
9358         "GET_NAME",
9359         "GET_STATE",
9360         "GET_INFO",
9361         "GET_ID",
9362         "GET_TID",
9363         "SET_IP"
9364 };
9365
9366 static const char* event_cmds_str[] = {
9367         "REQUEST_SET",
9368         "REQUEST_CLEAR",
9369         "REQUEST_CLEAR_ALL_BREAKPOINTS"
9370 };
9371
9372 static const char* appdomain_cmds_str[] = {
9373         "GET_ROOT_DOMAIN",
9374         "GET_FRIENDLY_NAME",
9375         "GET_ASSEMBLIES",
9376         "GET_ENTRY_ASSEMBLY",
9377         "CREATE_STRING",
9378         "GET_CORLIB",
9379         "CREATE_BOXED_VALUE"
9380 };
9381
9382 static const char* assembly_cmds_str[] = {
9383         "GET_LOCATION",
9384         "GET_ENTRY_POINT",
9385         "GET_MANIFEST_MODULE",
9386         "GET_OBJECT",
9387         "GET_TYPE",
9388         "GET_NAME"
9389 };
9390
9391 static const char* module_cmds_str[] = {
9392         "GET_INFO",
9393 };
9394
9395 static const char* field_cmds_str[] = {
9396         "GET_INFO",
9397 };
9398
9399 static const char* method_cmds_str[] = {
9400         "GET_NAME",
9401         "GET_DECLARING_TYPE",
9402         "GET_DEBUG_INFO",
9403         "GET_PARAM_INFO",
9404         "GET_LOCALS_INFO",
9405         "GET_INFO",
9406         "GET_BODY",
9407         "RESOLVE_TOKEN",
9408         "GET_CATTRS ",
9409         "MAKE_GENERIC_METHOD"
9410 };
9411
9412 static const char* type_cmds_str[] = {
9413         "GET_INFO",
9414         "GET_METHODS",
9415         "GET_FIELDS",
9416         "GET_VALUES",
9417         "GET_OBJECT",
9418         "GET_SOURCE_FILES",
9419         "SET_VALUES",
9420         "IS_ASSIGNABLE_FROM",
9421         "GET_PROPERTIES ",
9422         "GET_CATTRS",
9423         "GET_FIELD_CATTRS",
9424         "GET_PROPERTY_CATTRS",
9425         "GET_SOURCE_FILES_2",
9426         "GET_VALUES_2",
9427         "GET_METHODS_BY_NAME_FLAGS",
9428         "GET_INTERFACES",
9429         "GET_INTERFACE_MAP",
9430         "IS_INITIALIZED"
9431 };
9432
9433 static const char* stack_frame_cmds_str[] = {
9434         "GET_VALUES",
9435         "GET_THIS",
9436         "SET_VALUES",
9437         "GET_DOMAIN",
9438 };
9439
9440 static const char* array_cmds_str[] = {
9441         "GET_LENGTH",
9442         "GET_VALUES",
9443         "SET_VALUES",
9444 };
9445
9446 static const char* string_cmds_str[] = {
9447         "GET_VALUE",
9448         "GET_LENGTH",
9449         "GET_CHARS"
9450 };
9451
9452 static const char* object_cmds_str[] = {
9453         "GET_TYPE",
9454         "GET_VALUES",
9455         "IS_COLLECTED",
9456         "GET_ADDRESS",
9457         "GET_DOMAIN",
9458         "SET_VALUES",
9459         "GET_INFO",
9460 };
9461
9462 static const char*
9463 cmd_to_string (CommandSet set, int command)
9464 {
9465         const char **cmds;
9466         int cmds_len = 0;
9467
9468         switch (set) {
9469         case CMD_SET_VM:
9470                 cmds = vm_cmds_str;
9471                 cmds_len = G_N_ELEMENTS (vm_cmds_str);
9472                 break;
9473         case CMD_SET_OBJECT_REF:
9474                 cmds = object_cmds_str;
9475                 cmds_len = G_N_ELEMENTS (object_cmds_str);
9476                 break;
9477         case CMD_SET_STRING_REF:
9478                 cmds = string_cmds_str;
9479                 cmds_len = G_N_ELEMENTS (string_cmds_str);
9480                 break;
9481         case CMD_SET_THREAD:
9482                 cmds = thread_cmds_str;
9483                 cmds_len = G_N_ELEMENTS (thread_cmds_str);
9484                 break;
9485         case CMD_SET_ARRAY_REF:
9486                 cmds = array_cmds_str;
9487                 cmds_len = G_N_ELEMENTS (array_cmds_str);
9488                 break;
9489         case CMD_SET_EVENT_REQUEST:
9490                 cmds = event_cmds_str;
9491                 cmds_len = G_N_ELEMENTS (event_cmds_str);
9492                 break;
9493         case CMD_SET_STACK_FRAME:
9494                 cmds = stack_frame_cmds_str;
9495                 cmds_len = G_N_ELEMENTS (stack_frame_cmds_str);
9496                 break;
9497         case CMD_SET_APPDOMAIN:
9498                 cmds = appdomain_cmds_str;
9499                 cmds_len = G_N_ELEMENTS (appdomain_cmds_str);
9500                 break;
9501         case CMD_SET_ASSEMBLY:
9502                 cmds = assembly_cmds_str;
9503                 cmds_len = G_N_ELEMENTS (assembly_cmds_str);
9504                 break;
9505         case CMD_SET_METHOD:
9506                 cmds = method_cmds_str;
9507                 cmds_len = G_N_ELEMENTS (method_cmds_str);
9508                 break;
9509         case CMD_SET_TYPE:
9510                 cmds = type_cmds_str;
9511                 cmds_len = G_N_ELEMENTS (type_cmds_str);
9512                 break;
9513         case CMD_SET_MODULE:
9514                 cmds = module_cmds_str;
9515                 cmds_len = G_N_ELEMENTS (module_cmds_str);
9516                 break;
9517         case CMD_SET_FIELD:
9518                 cmds = field_cmds_str;
9519                 cmds_len = G_N_ELEMENTS (field_cmds_str);
9520                 break;
9521         case CMD_SET_EVENT:
9522                 cmds = event_cmds_str;
9523                 cmds_len = G_N_ELEMENTS (event_cmds_str);
9524                 break;
9525         default:
9526                 return NULL;
9527         }
9528         if (command > 0 && command <= cmds_len)
9529                 return cmds [command - 1];
9530         else
9531                 return NULL;
9532 }
9533
9534 static gboolean
9535 wait_for_attach (void)
9536 {
9537 #ifndef DISABLE_SOCKET_TRANSPORT
9538         if (listen_fd == -1) {
9539                 DEBUG_PRINTF (1, "[dbg] Invalid listening socket\n");
9540                 return FALSE;
9541         }
9542
9543         /* Block and wait for client connection */
9544         MONO_PREPARE_BLOCKING;
9545         conn_fd = socket_transport_accept (listen_fd);
9546         MONO_FINISH_BLOCKING;
9547
9548         DEBUG_PRINTF (1, "Accepted connection on %d\n", conn_fd);
9549         if (conn_fd == -1) {
9550                 DEBUG_PRINTF (1, "[dbg] Bad client connection\n");
9551                 return FALSE;
9552         }
9553 #else
9554         g_assert_not_reached ();
9555 #endif
9556
9557         /* Handshake */
9558         disconnected = !transport_handshake ();
9559         if (disconnected) {
9560                 DEBUG_PRINTF (1, "Transport handshake failed!\n");
9561                 return FALSE;
9562         }
9563         
9564         return TRUE;
9565 }
9566
9567 /*
9568  * debugger_thread:
9569  *
9570  *   This thread handles communication with the debugger client using a JDWP
9571  * like protocol.
9572  */
9573 static guint32 WINAPI
9574 debugger_thread (void *arg)
9575 {
9576         int res, len, id, flags, command_set = 0, command = 0;
9577         guint8 header [HEADER_LENGTH];
9578         guint8 *data, *p, *end;
9579         Buffer buf;
9580         ErrorCode err;
9581         gboolean no_reply;
9582         gboolean attach_failed = FALSE;
9583
9584         DEBUG_PRINTF (1, "[dbg] Agent thread started, pid=%p\n", (gpointer)GetCurrentThreadId ());
9585
9586         debugger_thread_id = GetCurrentThreadId ();
9587
9588         mono_jit_thread_attach (mono_get_root_domain ());
9589
9590         mono_thread_internal_current ()->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
9591
9592         mono_set_is_debugger_attached (TRUE);
9593         
9594         if (agent_config.defer) {
9595                 if (!wait_for_attach ()) {
9596                         DEBUG_PRINTF (1, "[dbg] Can't attach, aborting debugger thread.\n");
9597                         attach_failed = TRUE; // Don't abort process when we can't listen
9598                 } else {
9599                         /* Send start event to client */
9600                         process_profiler_event (EVENT_KIND_VM_START, mono_thread_get_main ());
9601                 }
9602         }
9603         
9604         while (!attach_failed) {
9605                 MONO_PREPARE_BLOCKING;
9606                 res = transport_recv (header, HEADER_LENGTH);
9607                 MONO_FINISH_BLOCKING;
9608
9609                 /* This will break if the socket is closed during shutdown too */
9610                 if (res != HEADER_LENGTH) {
9611                         DEBUG_PRINTF (1, "[dbg] transport_recv () returned %d, expected %d.\n", res, HEADER_LENGTH);
9612                         break;
9613                 }
9614
9615                 p = header;
9616                 end = header + HEADER_LENGTH;
9617
9618                 len = decode_int (p, &p, end);
9619                 id = decode_int (p, &p, end);
9620                 flags = decode_byte (p, &p, end);
9621                 command_set = decode_byte (p, &p, end);
9622                 command = decode_byte (p, &p, end);
9623
9624                 g_assert (flags == 0);
9625
9626                 if (log_level) {
9627                         const char *cmd_str;
9628                         char cmd_num [256];
9629
9630                         cmd_str = cmd_to_string (command_set, command);
9631                         if (!cmd_str) {
9632                                 sprintf (cmd_num, "%d", command);
9633                                 cmd_str = cmd_num;
9634                         }
9635                         
9636                         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);
9637                 }
9638
9639                 data = g_malloc (len - HEADER_LENGTH);
9640                 if (len - HEADER_LENGTH > 0)
9641                 {
9642                         MONO_PREPARE_BLOCKING;
9643                         res = transport_recv (data, len - HEADER_LENGTH);
9644                         MONO_FINISH_BLOCKING;
9645                         if (res != len - HEADER_LENGTH) {
9646                                 DEBUG_PRINTF (1, "[dbg] transport_recv () returned %d, expected %d.\n", res, len - HEADER_LENGTH);
9647                                 break;
9648                         }
9649                 }
9650
9651                 p = data;
9652                 end = data + (len - HEADER_LENGTH);
9653
9654                 buffer_init (&buf, 128);
9655
9656                 err = ERR_NONE;
9657                 no_reply = FALSE;
9658
9659                 /* Process the request */
9660                 switch (command_set) {
9661                 case CMD_SET_VM:
9662                         err = vm_commands (command, id, p, end, &buf);
9663                         if (!err && command == CMD_VM_INVOKE_METHOD)
9664                                 /* Sent after the invoke is complete */
9665                                 no_reply = TRUE;
9666                         break;
9667                 case CMD_SET_EVENT_REQUEST:
9668                         err = event_commands (command, p, end, &buf);
9669                         break;
9670                 case CMD_SET_APPDOMAIN:
9671                         err = domain_commands (command, p, end, &buf);
9672                         break;
9673                 case CMD_SET_ASSEMBLY:
9674                         err = assembly_commands (command, p, end, &buf);
9675                         break;
9676                 case CMD_SET_MODULE:
9677                         err = module_commands (command, p, end, &buf);
9678                         break;
9679                 case CMD_SET_FIELD:
9680                         err = field_commands (command, p, end, &buf);
9681                         break;
9682                 case CMD_SET_TYPE:
9683                         err = type_commands (command, p, end, &buf);
9684                         break;
9685                 case CMD_SET_METHOD:
9686                         err = method_commands (command, p, end, &buf);
9687                         break;
9688                 case CMD_SET_THREAD:
9689                         err = thread_commands (command, p, end, &buf);
9690                         break;
9691                 case CMD_SET_STACK_FRAME:
9692                         err = frame_commands (command, p, end, &buf);
9693                         break;
9694                 case CMD_SET_ARRAY_REF:
9695                         err = array_commands (command, p, end, &buf);
9696                         break;
9697                 case CMD_SET_STRING_REF:
9698                         err = string_commands (command, p, end, &buf);
9699                         break;
9700                 case CMD_SET_OBJECT_REF:
9701                         err = object_commands (command, p, end, &buf);
9702                         break;
9703                 default:
9704                         err = ERR_NOT_IMPLEMENTED;
9705                 }               
9706
9707                 if (command_set == CMD_SET_VM && command == CMD_VM_START_BUFFERING) {
9708                         buffer_replies = TRUE;
9709                 }
9710
9711                 if (!no_reply) {
9712                         if (buffer_replies) {
9713                                 buffer_reply_packet (id, err, &buf);
9714                         } else {
9715                                 send_reply_packet (id, err, &buf);
9716                                 //DEBUG_PRINTF (1, "[dbg] Sent reply to %d [at=%lx].\n", id, (long)mono_100ns_ticks () / 10000);
9717                         }
9718                 }
9719
9720                 if (!err && command_set == CMD_SET_VM && command == CMD_VM_STOP_BUFFERING) {
9721                         send_buffered_reply_packets ();
9722                         buffer_replies = FALSE;
9723                 }
9724
9725                 g_free (data);
9726                 buffer_free (&buf);
9727
9728                 if (command_set == CMD_SET_VM && (command == CMD_VM_DISPOSE || command == CMD_VM_EXIT))
9729                         break;
9730         }
9731
9732         mono_set_is_debugger_attached (FALSE);
9733         
9734         MONO_TRY_BLOCKING;
9735         mono_mutex_lock (&debugger_thread_exited_mutex);
9736         debugger_thread_exited = TRUE;
9737         mono_cond_signal (&debugger_thread_exited_cond);
9738         mono_mutex_unlock (&debugger_thread_exited_mutex);
9739         MONO_FINISH_TRY_BLOCKING;
9740
9741         DEBUG_PRINTF (1, "[dbg] Debugger thread exited.\n");
9742         
9743         if (!attach_failed && command_set == CMD_SET_VM && command == CMD_VM_DISPOSE && !(vm_death_event_sent || mono_runtime_is_shutting_down ())) {
9744                 DEBUG_PRINTF (2, "[dbg] Detached - restarting clean debugger thread.\n");
9745                 start_debugger_thread ();
9746         }
9747         
9748         return 0;
9749 }
9750
9751 #else /* DISABLE_DEBUGGER_AGENT */
9752
9753 void
9754 mono_debugger_agent_parse_options (char *options)
9755 {
9756         g_error ("This runtime is configured with the debugger agent disabled.");
9757 }
9758
9759 void
9760 mono_debugger_agent_init (void)
9761 {
9762 }
9763
9764 void
9765 mono_debugger_agent_breakpoint_hit (void *sigctx)
9766 {
9767 }
9768
9769 void
9770 mono_debugger_agent_single_step_event (void *sigctx)
9771 {
9772 }
9773
9774 void
9775 mono_debugger_agent_free_domain_info (MonoDomain *domain)
9776 {
9777 }
9778
9779 void
9780 mono_debugger_agent_handle_exception (MonoException *ext, MonoContext *throw_ctx,
9781                                                                           MonoContext *catch_ctx)
9782 {
9783 }
9784
9785 void
9786 mono_debugger_agent_begin_exception_filter (MonoException *exc, MonoContext *ctx, MonoContext *orig_ctx)
9787 {
9788 }
9789
9790 void
9791 mono_debugger_agent_end_exception_filter (MonoException *exc, MonoContext *ctx, MonoContext *orig_ctx)
9792 {
9793 }
9794
9795 void
9796 mono_debugger_agent_user_break (void)
9797 {
9798         G_BREAKPOINT ();
9799 }
9800
9801 void
9802 mono_debugger_agent_debug_log (int level, MonoString *category, MonoString *message)
9803 {
9804 }
9805
9806 gboolean
9807 mono_debugger_agent_debug_log_is_enabled (void)
9808 {
9809         return FALSE;
9810 }
9811
9812 void
9813 mono_debugger_agent_unhandled_exception (MonoException *exc)
9814 {
9815         g_assert_not_reached ();
9816 }
9817
9818 void
9819 debugger_agent_single_step_from_context (MonoContext *ctx)
9820 {
9821         g_assert_not_reached ();
9822 }
9823
9824 void
9825 debugger_agent_breakpoint_from_context (MonoContext *ctx)
9826 {
9827         g_assert_not_reached ();
9828 }
9829
9830 #endif