Example #1
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());
        }
Example #2
0
 protected override void OnThreadEnd(DalvikThread thread)
 {
     base.OnThreadEnd(thread);
     if (thread == Dot42Debugger.Instance.CurrentThread)
     {
         Dot42Debugger.Instance.CurrentThread = null;
     }
 }
Example #3
0
        /// <summary>
        /// Notify listeners that we're suspended.
        /// </summary>
        protected override bool OnSuspended(SuspendReason reason, DalvikThread thread, StepRequest stepRequest)
        {
            var rc = base.OnSuspended(reason, thread, stepRequest);

            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);
        }
Example #4
0
 public StepRequest(DalvikThread thread, Jdwp.StepDepth stepDepth)
 {
     Thread = thread;
     StepDepth = stepDepth;
 }
        /// <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);
        }
 private static string GetThreadId(DalvikThread thread)
 {
     return(thread == null ? "(none)" : thread.Id.ToString());
 }
Example #7
0
 public StepRequest(DalvikThread thread, Jdwp.StepDepth stepDepth, StepMode stepMode = StepMode.Line)
 {
     Thread    = thread;
     StepDepth = stepDepth;
     StepMode  = stepMode;
 }
Example #8
0
 public DalvikStep(DalvikThread thread, int requestId, StepRequest stepRequest)
 {
     StepRequest = stepRequest;
     Thread = thread;
     RequestId = requestId;
 }
Example #9
0
 public DalvikStep(DalvikThread thread, int requestId)
 {
     Thread    = thread;
     RequestId = requestId;
 }
Example #10
0
 public StepRequest(DalvikThread thread, Jdwp.StepDepth stepDepth)
 {
     Thread    = thread;
     StepDepth = stepDepth;
 }
Example #11
0
 /// <summary>
 /// Notify the debug process of our suspension.
 /// </summary>
 private void HandleSuspendPolicy(Jdwp.SuspendPolicy suspendPolicy, SuspendReason reason, DalvikThread thread)
 {
     if (suspendPolicy == Jdwp.SuspendPolicy.All)
     {
         debugger.Process.OnSuspended(reason, thread);
     }
 }
Example #12
0
 public DalvikStep(DalvikThread thread, int requestId, StepRequest stepRequest)
 {
     StepRequest = stepRequest;
     Thread      = thread;
     RequestId   = requestId;
 }
Example #13
0
 public StepRequest(DalvikThread thread, Jdwp.StepDepth stepDepth, StepMode stepMode = StepMode.Line)
 {
     Thread = thread;
     StepDepth = stepDepth;
     StepMode = stepMode;
 }
Example #14
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);
        }