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