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