[sdb] Implement a SetIP () method in ThreadMirror which can be used to implement...
[mono.git] / mcs / class / Mono.Debugger.Soft / Mono.Debugger.Soft / ThreadMirror.cs
index 65e0c0f62ac2bd4344cd7d5aa2bb3a2761b9a900..89adc857fea257209719b7775d16a31062c35fd1 100644 (file)
@@ -1,5 +1,6 @@
 using System;
 using System.Threading;
+using System.Collections.Generic;
 
 namespace Mono.Debugger.Soft
 {
@@ -10,18 +11,24 @@ namespace Mono.Debugger.Soft
                internal ThreadMirror (VirtualMachine vm, long id) : base (vm, id) {
                }
 
+               internal ThreadMirror (VirtualMachine vm, long id, TypeMirror type, AppDomainMirror domain) : base (vm, id, type, domain) {
+               }
+
                // FIXME: Cache, invalidate when the thread/runtime is resumed
                public StackFrame[] GetFrames () {
                        FrameInfo[] frame_info = vm.conn.Thread_GetFrameInfo (id, 0, -1);
 
-                       StackFrame[] frames = new StackFrame [frame_info.Length];
+                       var frames = new List<StackFrame> ();
+
                        for (int i = 0; i < frame_info.Length; ++i) {
                                FrameInfo info = (FrameInfo)frame_info [i];
                                MethodMirror method = vm.GetMethod (info.method);
-                               frames [i] = new StackFrame (vm, info.id, this, method, info.il_offset, info.flags);
+                               var f = new StackFrame (vm, info.id, this, method, info.il_offset, info.flags);
+                               if (!(f.IsNativeTransition && !NativeTransitions))
+                                       frames.Add (f);
                        }
 
-                       return frames;
+                       return frames.ToArray ();
            }
 
                public string Name {
@@ -51,5 +58,61 @@ namespace Mono.Debugger.Soft
                                return info.is_thread_pool;
                        }
                }
+
+               long? thread_id;
+               /*
+                * Return a unique identifier for this thread, multiple ThreadMirror objects
+                * may have the same ThreadId because of appdomains.
+                */
+               public long ThreadId {
+                       get {
+                               if (thread_id == null)
+                                       thread_id = vm.conn.Thread_GetId (id);
+                               return (long)thread_id;
+                       }
+               }
+
+               /*
+                * Return the system thread id (TID) for this thread, this id is not unique since
+                * a newly started thread might reuse a dead thread's id.
+                */
+               public long TID {
+                       get {
+                               return vm.conn.Thread_GetTID (id);
+                       }
+               }
+
+               /*
+                * Get/set whenever GetFrames () should return frames for managed-to-native
+                * transitions, i.e frames whose IsNativeTransition property is set.
+                * This is needed because some clients might not be able to deal with those
+                * frames.
+                */
+               public static bool NativeTransitions {
+                       get; set;
+               }
+
+               /*
+                * Set the location where execution will return when this thread is
+                * resumed.
+                * Throws:
+                * ArgumentException - if L doesn't refer to a location in the
+                * current method of this thread.
+                * NotSupportedException - if continuing at L is not supported
+                * for any other reason.
+                * Since protocol version 29.
+                */
+               public void SetIP (Location loc) {
+                       if (loc == null)
+                               throw new ArgumentNullException ("loc");
+                       try {
+                               vm.conn.Thread_SetIP (id, loc.Method.Id, loc.ILOffset);
+                       } catch (CommandException ex) {
+                               if (ex.ErrorCode == ErrorCode.INVALID_ARGUMENT)
+                                       throw new ArgumentException ("loc doesn't refer to a location in the current method of this thread.", "loc");
+                               else
+                                       throw;
+                       }
+               }
     }
 }