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