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