/// <summary>
 /// Try to get a thread by it's id.
 /// </summary>
 public bool TryGet(ThreadId id, out DalvikThread thread)
 {
     lock (threadsLock)
     {
         return(threads.TryGetValue(id, out thread));
     }
 }
 /// <summary>
 /// Try to get a thread by it's id.
 /// </summary>
 public bool TryGet(ThreadId id, out DalvikThread thread)
 {
     lock (threadsLock)
     {
         return threads.TryGetValue(id, out thread);
     }
 }
Beispiel #3
0
 protected override void OnThreadEnd(DalvikThread thread)
 {
     base.OnThreadEnd(thread);
     if (thread == Dot42Debugger.Instance.CurrentThread) {
         Dot42Debugger.Instance.CurrentThread = null;
     }
 }
        /// <summary>
        /// Process the given exception event.
        /// </summary>
        protected internal virtual void OnExceptionEvent(Events.Jdwp.Exception @event, DalvikThread thread)
        {
            // Log
            DLog.Debug(DContext.VSDebuggerEvent, "OnExceptionEvent location: {0}", @event.Location);

            // Save exception in thread
            thread.CurrentException = @event.ExceptionObject;
        }
 /// <summary>
 /// Refresh the thread list and notify all threads that's we've justed suspended the process.
 /// </summary>
 /// <param name="reason">The reason the VM is suspended</param>
 /// <param name="thread">The thread involved in the suspend. This can be null depending on the reason.</param>
 internal void OnProcessSuspended(SuspendReason reason, DalvikThread thread)
 {
     // Ask all threads to cleanup
     foreach (var t in Threads)
     {
         t.OnProcessSuspended(reason, (t == thread));
     }
     // Refresh threads
     RefreshThreadsAsync().Wait();
 }
Beispiel #6
0
        /// <summary>
        /// Process the given exception event.
        /// </summary>
        protected override void OnExceptionEvent(DebuggerLib.Events.Jdwp.Exception @event, DalvikThread thread)
        {
            base.OnExceptionEvent(@event, thread);

            // Get information about the exception
            var exceptionTypeId = Debugger.ObjectReference.ReferenceTypeAsync(@event.ExceptionObject.Object).Await(DalvikProcess.VmTimeout);
            var exceptionType = Process.ReferenceTypeManager[exceptionTypeId];

            // Prepare VS event
            var info = new EXCEPTION_INFO();
            info.bstrExceptionName = exceptionType.GetNameAsync().Await(DalvikProcess.VmTimeout);
            var caught = @event.IsCaught;
            info.dwState = caught
                               ? enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE
                               : enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT;
            program.GetName(out info.bstrProgramName);
            info.pProgram = program;
            info.guidType = GuidList.Guids.guidDot42DebuggerId;

            // Send VS event
            var vsEvent = new ExceptionEvent(info, info.bstrExceptionName, false);
            Send((DebugThread) thread, vsEvent);
        }
Beispiel #7
0
 /// <summary>
 /// Notify listeners that we're suspended.
 /// </summary>
 /// <param name="reason">The reason the VM is suspended</param>
 /// <param name="thread">The thread involved in the suspend. This can be null depending on the reason.</param>
 /// <returns>True if the suspend is performed, false if execution is continued.</returns>
 protected internal virtual bool OnSuspended(SuspendReason reason, DalvikThread thread)
 {
     if ((reason == SuspendReason.SingleStep) && (thread != null))
     {
         // Make sure we're are a location where we have a source.
         thread.OnProcessSuspended(reason, true);
         var topFrame = thread.GetCallStack().FirstOrDefault();
         if (topFrame != null)
         {
             var location = topFrame.GetDocumentLocationAsync().Await(VmTimeout);
             if (location.Document == null)
             {
                 // Not my code
                 StepOutLastRequestAsync();
                 return(false);
             }
         }
     }
     ThreadManager.OnProcessSuspended(reason, thread);
     ReferenceTypeManager.OnProcessSuspended(reason);
     isSuspended = true;
     IsSuspendedChanged.Fire(this);
     return(true);
 }
Beispiel #8
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public DalvikStackFrame(FrameId id, Location location, DalvikThread thread)
 {
     Id = id;
     Location = location;
     this.thread = thread;
 }
Beispiel #9
0
 /// <summary>
 /// Notify listeners that we're suspended.
 /// </summary>
 protected override bool OnSuspended(SuspendReason reason, DalvikThread thread)
 {
     var rc = base.OnSuspended(reason, thread);
     if (rc)
     {
         if (reason == SuspendReason.ProcessSuspend)
         {
             foreach (var threadx in ThreadManager.Threads)
             {
                 eventCallback.Send(threadx, new ASyncBreakCompleteEvent());
             }
         }
         if (reason == SuspendReason.SingleStep)
         {
             eventCallback.Send((DebugThread) thread, new StepCompleteEvent());
         }
     }
     return rc;
 }
Beispiel #10
0
        /// <summary>
        /// Notify listeners that we're suspended.
        /// </summary>
        /// <param name="reason">The reason the VM is suspended</param>
        /// <param name="thread">The thread involved in the suspend. This can be null depending on the reason.</param>
        /// <param name="request">A step request, if any.</param>
        /// <returns>True if the suspend is performed, false if execution is continued.</returns>
        protected internal virtual bool OnSuspended(SuspendReason reason, DalvikThread thread, StepRequest request = null)
        {
            if (reason == SuspendReason.SingleStep && thread != null && request != null && request.Thread != null)
            {
                // Make sure we're are a location where we have a source.
                thread.OnProcessSuspended(reason, true);
                var topFrame = thread.GetCallStack().FirstOrDefault();
                if (topFrame != null)
                {
                    var location = topFrame.GetDocumentLocationAsync().Await(VmTimeout);
                    if (location.SourceCode == null)
                    {
                        // Not my code
                        StepOutLastRequestAsync(request);
                        return false;
                    }

                    // check if we have a valid source code position, or if this is
                    // compiler generated code (in which case dalvik will perform single stepping)
                    if (request.StepMode != StepMode.SingleInstruction)
                    {
                        if (location.SourceCode == null || location.SourceCode.IsSpecial ||
                            location.Location.Index < (ulong)location.SourceCode.Position.MethodOffset)
                        {
                            var stepDepth = request.StepDepth == Jdwp.StepDepth.Out ? Jdwp.StepDepth.Over : request.StepDepth;
                            StepAsync(new StepRequest(request.Thread, stepDepth, request.StepMode));
                            return false;
                        }
                    }
                }
            }
            ThreadManager.OnProcessSuspended(reason, thread);
            ReferenceTypeManager.OnProcessSuspended(reason);
            isSuspended = true;
            IsSuspendedChanged.Fire(this);
            return true;
        }
        /// <summary>
        /// Process the given exception event.
        /// </summary>
        protected internal virtual void OnExceptionEvent(Events.Jdwp.Exception @event, DalvikThread thread)
        {
            // Log
            DLog.Debug(DContext.VSDebuggerEvent, "OnExceptionEvent location: {0}", @event.Location);

            // Note that Process.OnSuspended() has not been called yet, and needs to be called
            // if the implementation does not decide to continue in spite of the exception.
            Debugger.Process.OnSuspended(SuspendReason.Exception, thread);

            // Save exception in thread
            if(thread != null)
                thread.CurrentException = @event.ExceptionObject;
        }
 /// <summary>
 /// The given thread has ended.
 /// </summary>
 protected virtual void OnThreadEnd(DalvikThread thread)
 {
 }
Beispiel #13
0
        /// <summary>
        /// Process the given exception event.
        /// </summary>
        protected internal virtual void OnExceptionEvent(Events.Jdwp.Exception @event, DalvikThread thread)
        {
            // Log
            DLog.Debug(DContext.VSDebuggerEvent, "OnExceptionEvent location: {0}", @event.Location);

            // Note that Process.OnSuspended() has not been called yet, and needs to be called
            // if the implementation does not decide to continue in spite of the exception.
            Debugger.Process.OnSuspended(SuspendReason.Exception, thread);

            // Save exception in thread
            if (thread != null)
            {
                thread.CurrentException = @event.ExceptionObject;
            }
        }
Beispiel #14
0
 /// <summary>
 /// The given thread has ended.
 /// </summary>
 protected override void OnThreadEnd(DalvikThread thread)
 {
     var dthread = (DebugThread)thread;
     base.OnThreadEnd(dthread);
     eventCallback.Send(dthread, new ThreadDestroyEvent());
 }
 /// <summary>
 /// The given thread has been created.
 /// </summary>
 protected virtual void OnThreadCreated(DalvikThread thread)
 {
 }
 private static string GetThreadId(DalvikThread thread)
 {
     return thread == null ? "(none)" : thread.Id.ToString();
 }
        /// <summary>
        /// Process the given exception event.
        /// </summary>
        protected override void OnExceptionEvent(Exception @event, DalvikThread thread)
        {
            var prev = Interlocked.CompareExchange(ref processing, @event, null);
            if (prev != null)
            {
                if (@event.ExceptionObject.Equals(prev.ExceptionObject) && @event.ThreadId.Equals(prev.ThreadId))
                {
                    // the same exception is reported multiple times. just ignore.
                    Debugger.VirtualMachine.ResumeAsync();
                    return;
                }

                DLog.Error(DContext.VSDebuggerMessage,
                    "Multiple exceptions in debuggee or exceptions while retrieving exception information. "
                   +"Current Exception/Thread: {0}/{1}; previous Exception/Thread: {2}/{3} ",
                   @event.ThreadId, @event.ExceptionObject, prev.ThreadId, prev.ExceptionObject);

                Debugger.VirtualMachine.ResumeAsync();
                return;

                // This cancelling might not be neccessary any more; check this.

                //// I have no idea why we have to resume twice, but if we dont, the debuggee will hang.
                //Debugger.Process.ResumeAsync();

                //if(cancelProcessing != null)
                //    cancelProcessing.Cancel();
            }

            cancelProcessing = new CancellationTokenSource();
            var cancelToken = cancelProcessing.Token;
            bool wasThreadNull = thread == null;

            bool caught;
            string exceptionName = "(unknown)";
            string catchingClass = "(unknown)";
            string exceptionMessage = null;

            try
            {
                // Get information about the exception
                var exceptionTypeId = Debugger.ObjectReference.ReferenceTypeAsync(@event.ExceptionObject.Object)
                                                              .Await(DalvikProcess.VmTimeout, cancelToken);
                var exceptionType = Process.ReferenceTypeManager[exceptionTypeId];

                exceptionName = exceptionType.GetNameAsync()
                                             .Await(DalvikProcess.VmTimeout, cancelToken);
                caught = @event.IsCaught;

                if (!ShouldHandle(exceptionName, caught))
                {
                    DLog.Debug(DContext.VSDebuggerMessage, "not handling exception {0}", exceptionName);
                    Debugger.VirtualMachine.ResumeAsync();
                    return;
                }

                if (caught && @event.CatchLocation != null)
                {
                    // filter out internal exceptions, that are used for control flow.
                    catchingClass = Process.ReferenceTypeManager[@event.CatchLocation.Class].GetNameAsync()
                                                                  .Await(DalvikProcess.VmTimeout, cancelToken);
                    if (CaughtExceptionLocationExcludePattern.IsMatch(catchingClass))
                    {
                        DLog.Debug(DContext.VSDebuggerMessage, "not handling exception {0}, catching class={1}", exceptionName, catchingClass);
                        Debugger.VirtualMachine.ResumeAsync();
                        return;
                    }
                }

                if (wasThreadNull)
                    thread = Debugger.Process.ThreadManager.Threads.First();

                base.OnExceptionEvent(@event, thread);

                exceptionMessage = GetExceptionMessageAsync(@event.ExceptionObject).Await(DalvikProcess.VmTimeout);
            }
            catch(System.Exception ex)
            {
                DLog.Error(DContext.VSDebuggerMessage, "Exception in debugger while processing exception: {0}. involved thread: {1}; exception.object={2}; exception type: {3}; ccatching class: {4}", ex.Message, GetThreadId(thread), @event.ExceptionObject.Object, exceptionName, catchingClass);
                Debugger.VirtualMachine.ResumeAsync();
                return;
            }
            finally
            {
                Interlocked.Exchange(ref processing, null);
            }

            // Prepare VS event
            var info = new EXCEPTION_INFO();
            info.bstrExceptionName = exceptionName;
            info.dwState = caught ? enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE
                                  : enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT;
            program.GetName(out info.bstrProgramName);
            info.pProgram = program;
            info.guidType = GuidList.Guids.guidDot42DebuggerId;

            string description = info.bstrExceptionName;

            if (exceptionMessage != null)
                description += ": \"" + exceptionMessage + "\"";

            if (caught)
                description += "\n(first chance, caught by debuggee)";
            else
                description += "\n(not caught by debugee)";

            if (thread == null)
            {
                DLog.Warning(DContext.VSDebuggerEvent, "Exception without a thread: {0}. Original thread id: {1}.", exceptionName, @event.ThreadId);
                description += "\n  The exceptions thread has already died, the VS call stack window has no meaning. The exception was raised on thread "+ @event.ThreadId;
            }

            // Send VS event
            var vsEvent = new ExceptionEvent(info, description, false);
            Send((DebugThread)thread, vsEvent);
        }
Beispiel #18
0
 /// <summary>
 /// Refresh the thread list and notify all threads that's we've justed suspended the process.
 /// </summary>
 /// <param name="reason">The reason the VM is suspended</param>
 /// <param name="thread">The thread involved in the suspend. This can be null depending on the reason.</param>
 internal void OnProcessSuspended(SuspendReason reason, DalvikThread thread)
 {
     // Ask all threads to cleanup
     foreach (var t in Threads)
     {
         t.OnProcessSuspended(reason, (t == thread));
     }
     // Refresh threads
     RefreshThreadsAsync().Wait();
 }
Beispiel #19
0
 /// <summary>
 /// The given thread has been created.
 /// </summary>
 protected virtual void OnThreadCreated(DalvikThread thread)
 {
 }
Beispiel #20
0
 /// <summary>
 /// The given thread has ended.
 /// </summary>
 protected virtual void OnThreadEnd(DalvikThread thread)
 {
 }
Beispiel #21
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public DalvikStackFrame(FrameId id, Location location, DalvikThread thread)
 {
     Id          = id;
     Location    = location;
     this.thread = thread;
 }
        /// <summary>
        /// Process the given exception event.
        /// </summary>
        protected internal virtual void OnExceptionEvent(Events.Jdwp.Exception @event, DalvikThread thread)
        {
            // Log
            DLog.Debug(DContext.VSDebuggerEvent, "OnExceptionEvent location: {0}", @event.Location);

            // Save exception in thread
            thread.CurrentException = @event.ExceptionObject;
        }