예제 #1
0
        internal static List <ClassDefinition> Hierarchicalize(List <ClassDefinition> container)
        {
            var result = new List <ClassDefinition>();
            var dex    = new DexLookup(container, false);

            foreach (var cdef in container)
            {
                int idx = cdef.Fullname.LastIndexOf(DexConsts.InnerClassMarker);

                if (idx == -1)
                {
                    result.Add(cdef);
                }
                else
                {
                    string ownerFullName = cdef.Fullname.Substring(0, idx);
                    var    owner         = dex.GetClass(ownerFullName);
                    if (owner != null)
                    {
                        owner.AddInnerClass(cdef);
                        cdef.Owner = owner;
                    }
                    else
                    {
                        DLog.Error(DContext.CompilerCodeGenerator, "owner not found for inner class {0}", cdef.Fullname);
                        result.Add(cdef);
                    }
                }
            }
            return(result);
        }
예제 #2
0
        /// <summary>
        /// Allocates the predfined number of objects within the pool
        /// </summary>
        /// <returns></returns>
        public virtual bool Allocate(string objectPath = "")
        {
            if (!this._isInitialized)
            {
                return(false);
            }

            if (this._objectLoadPolicy == null)
            {
                DLog.Error("Did you forget to set your object policy?!", DLogCategory.Loading);
                return(false);
            }

            try
            {
                for (int i = 0; i < this._sizeOfPool; i++)
                {
                    T obj = this._objectLoadPolicy.Load();
                    if (obj == null)
                    {
                        return(false);
                    }

                    this._pool.Enqueue(obj);
                }
            }
            catch (Exception ex)
            {
                DLog.Error(ex, DLogCategory.Loading);
                return(false);
            }

            return(true);
        }
예제 #3
0
        /// <summary>
        /// We're done loading the initial threads.
        /// Notify the GUI that we're good to go.
        /// </summary>
        private void OnLoadThreadsDone(Dot42.DebuggerLib.Debugger debugger, DebugProcess debugProcess)
        {
            // Notify module
            //eventCallback.Send(program, new ModuleLoadEvent(program.MainModule, "Loading module", true));
            //eventCallback.Send(program, new SymbolSearchEvent(program.MainModule, "Symbols loaded", enum_MODULE_INFO_FLAGS.MIF_SYMBOLS_LOADED));

            var mainThread = debugProcess.ThreadManager.MainThread();

            if (mainThread != null)
            {
                // Threads loaded
                // Load complete
                //eventCallback.Send(mainThread, new LoadCompleteEvent());
                //eventCallback.Send(mainThread, new EntryPointEvent());

                // Resume now
                debugger.VirtualMachine.ResumeAsync();

                // Notify SD
                Action onDebugStarted = () => {
                    if (stateUpdate != null)
                    {
                        stateUpdate(LauncherStates.Attached, string.Empty);
                        stateUpdate = null;
                    }
                    DebugStarted.Fire(this);
                };
                Dot42Addin.InvokeAsyncAndForget(onDebugStarted);
            }
            else
            {
                DLog.Error(DContext.VSDebuggerLauncher, "No main thread found");
            }
        }
예제 #4
0
        /// <summary>
        /// Returns a gameobject back to the pool. This will fail if
        /// the pool isn't initialized.
        /// </summary>
        /// <param name="obj">The gameobject to return.</param>
        override public void Return(GameObject obj)
        {
            if (!this._isInitialized)
            {
                return;
            }

            if (!this._pool.Contains(obj))
            {
                this._pool.Enqueue(obj);
            }

            obj.transform.position = Vector3.zero;
            obj.transform.rotation = this._original.transform.rotation;
            obj.SetActive(false);

            if (this._parent != null)
            {
                obj.transform.SetParent(this._parent.transform);
                obj.name = "GameObject";
            }
            else
            {
                DLog.Error("Parent is null when adding obj: " + obj.name, DLogCategory.Loading);
            }
        }
예제 #5
0
        /// <summary>
        /// Allocates a single object.
        /// </summary>
        /// <returns>The game object or null</returns>
        public override GameObject AllocateSingle()
        {
            if (!this._isInitialized)
            {
                return(null);
            }

            Assert.IsNotNull(this._original, "Please call allocate beforehand trying to allocate a new single object!");

            try
            {
                GameObject obj = UnityEngine.Object.Instantiate(_original);
                if (obj == null)
                {
                    return(null);
                }

                obj.transform.parent = this._parent.transform;
                obj.SetActive(false);
                return(obj);
            }
            catch (Exception ex)
            {
                DLog.Error(ex, DLogCategory.Loading);
                return(null);
            }
        }
예제 #6
0
 /// <summary>
 /// Notify clients of the given event.
 /// </summary>
 private void OnEventAsync(JdwpEvent @event)
 {
     Task.Factory.StartNew(() => JdwpEvent.Fire(this, @event))
     .ContinueWith(task =>
     {
         DLog.Error(DContext.DebuggerLibJdwpConnection, "OnEventAsync: Internal failure on event processing. IsCancelled={0}. Exception={1}", task.IsCanceled, task.Exception);
     },
                   TaskContinuationOptions.NotOnRanToCompletion);
 }
예제 #7
0
        /// <summary>
        /// Perform actual send
        /// </summary>
        private void Send(IDebugProcess2 process, IDebugProgram2 program, IDebugThread2 thread, BaseEvent @event)
        {
            var guid = @event.IID;

            DLog.Debug(DContext.VSDebuggerEvent, "DebugEngine Event {0} {1}", @event.GetType().Name, guid);
            var rc = callback.Event(engine, process, program, thread, @event, ref guid, (uint)@event.Attributes);

            if (!ErrorHandler.Succeeded(rc))
            {
                DLog.Error(DContext.VSDebuggerEvent, "DebugEngine Event failed {0}", rc);
            }
        }
예제 #8
0
        /// <summary>
        /// Process the output of AAPT to display property errors in VisualStudio.
        /// </summary>
        private static void ProcessAaptErrors(string output, string tempFolder, List <Tuple <string, ResourceType> > resources)
        {
#if DEBUG
            //Debugger.Launch();
#endif

            const string errorPrefix = "Error: ";
            const string errorLevel  = "error";

            var lines = output.Split(new[] { '\n', '\r' });
            var paths = resources.Select(x => Tuple.Create(x.Item1, ResourceExtensions.GetNormalizedResourcePath(tempFolder, x.Item1, x.Item2))).ToList();

            foreach (var line in lines)
            {
                var parts = SplitAaptErrorLine(line.Trim(), 4).ToArray();
                int lineNr;
                if ((parts.Length < 4) || !int.TryParse(parts[1], out lineNr))
                {
                    if (line.Length > 0)
                    {
                        Console.WriteLine(line);
                    }
                    continue;
                }

                // src:line:severity:remaining
                var msg = parts[3].Trim();
                if (msg.StartsWith(errorPrefix))
                {
                    msg = msg.Substring(errorPrefix.Length);
                }
                var url   = parts[0];
                var level = parts[2].Trim();

                var pathEntry = paths.FirstOrDefault(x => x.Item2 == url);
                url = (pathEntry != null) ? pathEntry.Item1 : url;

                switch (level.ToLowerInvariant())
                {
                case errorLevel:
                    DLog.Error(DContext.ResourceCompilerAaptError, url, 0, lineNr, msg);
                    break;

                default:
                    DLog.Warning(DContext.ResourceCompilerAaptError, url, 0, lineNr, msg);
                    break;
                }

                //Console.WriteLine(line); // DEBUG PURPOSES
            }
        }
예제 #9
0
        /// <summary>
        /// Takes care of allocating the pool objects at a specific path.
        /// </summary>
        /// <param name="objectPath">The path of the object.</param>
        /// <returns>True or false depending on the result of the loading process</returns>
        public override bool Allocate(string objectPath = "")
        {
            if (!this._isInitialized)
            {
                return(false);
            }

            Assert.IsNotNull(this._objectLoadPolicy, "No Object Load Policy specified! In order to run the pool you need one!");
            Assert.IsTrue(this._objectLoadPolicy.IsCreated(), "Object Load Policy has not been created please call Initialize on Object Pool!");
            Assert.IsNotNull(this._parent, "The parent object is null! You need to specify a parent object at construction time!");

            UnityEngine.Object original = this._objectLoadPolicy.Load(objectPath);
            if (original == null)
            {
                DLog.Error("Couldn't find original allocation object for pool ( " + objectPath + ").", DLogCategory.Loading);
                return(false);
            }

            this._original = (GameObject)GameObject.Instantiate(original);
            this._original.transform.parent = this._parent.transform;
            this._original.SetActive(false);
            this._original.name = "GameObject_Reference";


            try
            {
                for (int i = 0; i < this._sizeOfPool; i++)
                {
                    GameObject obj = UnityEngine.Object.Instantiate(_original);
                    if (obj == null)
                    {
                        return(false);
                    }

                    obj.name             = "GameObject";
                    obj.transform.parent = this._parent.transform;
                    obj.SetActive(false);
                    this._pool.Enqueue(obj);
                }
            }
            catch (Exception ex)
            {
                DLog.Error(ex, DLogCategory.Loading);
                return(false);
            }

            return(true);
        }
예제 #10
0
        /// <summary>
        /// Resolve an assembly by name with given parameters.
        /// </summary>
        public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
        {
            AssemblyDefinition result;

            if (references.TryGetValue(name.Name, out result))
            {
                return(result);
            }

            var path = ResolvePath(name.Name);

            if (path == null)
            {
                DLog.Error(DContext.CompilerAssemblyResolver, "Failed to resolve assembly {0} in {1}", name, string.Join(";  ", referenceFolders));
                throw new AssemblyResolutionException(name);
            }

            try
            {
                Console.WriteLine(string.Format("Loading {0}", name.Name));
                var reference = AssemblyDefinition.ReadAssembly(path, parameters);
                references[name.Name] = reference;
                VerifyFrameworkAssembly(reference, path);
                if (assemblyLoaded != null)
                {
                    assemblyLoaded(reference);
                }
                if (classLoader != null)
                {
                    classLoader.LoadAssembly(reference);
                }
                return(reference);
            }
            catch (Exception ex)
            {
                // Unload the reference
                references.Remove(name.Name);
#if DEBUG
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
#endif
                // Log the error
                DLog.Error(DContext.CompilerAssemblyResolver, "Failed to load assembly {0}", ex, name);

                // Pass the error on
                throw new AssemblyResolutionException(name);
            }
        }
예제 #11
0
        /// <summary>
        /// Process the result of an AllThreads request.
        /// </summary>
        private void ProcessAllThreads(Task <List <ThreadId> > task)
        {
            if (!task.CompletedOk())
            {
                DLog.Error(DContext.DebuggerLibModel, "LoadAllThreads failed", task.Exception);
                task.ForwardException();
                return;
            }

            List <DalvikThread> created = null;
            List <DalvikThread> removed = null;

            lock (threadsLock)
            {
                // Create missing threads
                foreach (var id in task.Result.Where(x => !threads.ContainsKey(x)))
                {
                    // Create and record
                    var thread = CreateThread(id);
                    threads[id] = thread;
                    list.Add(thread);

                    created = created ?? new List <DalvikThread>();
                    created.Add(thread);
                }

                // Remove obsolete threads
                var toRemove = threads.Keys.Where(x => !task.Result.Contains(x)).ToList();
                foreach (var id in toRemove)
                {
                    var thread = threads[id];
                    threads.Remove(id);
                    list.Remove(thread);
                    removed = removed ?? new List <DalvikThread>();
                    removed.Add(thread);
                }
            }

            if (created != null)
            {
                created.ForEach(OnThreadCreated);
            }
            if (removed != null)
            {
                removed.ForEach(OnThreadEnd);
            }
        }
            public void Convert(ReachableContext reachableContext)
            {
                // Collect all names
                var reachableInterfaces          = reachableContext.ReachableTypes.Where(i => i.IsInterface).ToList();
                var interfaceToImplementingTypes = reachableContext.ReachableTypes
                                                   .Except(reachableInterfaces)
                                                   .SelectMany(t => GetInterfaces(t).Distinct(), Tuple.Create)
                                                   .Where(e => e.Item2.IsReachable)
                                                   .ToLookup(e => e.Item2, e => e.Item1);

                // TODO: I don't think the we cover all possible cases here yet.
                //       What about methods overriding imported methods?

                foreach (var intf in reachableInterfaces)
                {
                    foreach (var iMethod in intf.Methods)
                    {
                        // ignore DexImport Interface types. TODO: also cover the reverse: a method implementing
                        //                                         both a import-interface as well as a .NET interface.
                        if (iMethod.GetDexOrJavaImportAttribute() != null || iMethod.GetDexNameAttribute() != null)
                        {
                            continue;
                        }

                        var nativeImpls = interfaceToImplementingTypes[intf].Select(t => Tuple.Create(t, iMethod.GetImplementation(t)))
                                          .Where(e => e.Item2 != null &&
                                                 (e.Item2.GetDexOrJavaImportAttribute() != null ||
                                                  e.Item2.GetDexNameAttribute() != null));
                        foreach (var typeAndImpl in nativeImpls)
                        {
                            var type = typeAndImpl.Item1;
                            var impl = typeAndImpl.Item2;

                            var finalName = GetFinalImplementationName(impl);

                            if (finalName == iMethod.Name)
                            {
                                continue;
                            }

                            // TODO: automatically create a redirecting stub.

                            DLog.Error(DContext.CompilerILConverter, "Type '{0}' implements interface method '{1}' using imported method '{2}'. This is not supported at the moment. As a workaround, create a 'new' or explicit implementation of the interface, that redirects to the imported.", type.FullName, iMethod.FullName, impl.FullName);
                        }
                    }
                }
            }
예제 #13
0
        /// <summary>
        /// Send the given event to all event sinks
        /// </summary>
        private void SendEvent(IDebugCoreServer2 server, IDebugPort2 port, IDebugProcess2 process, IDebugProgram2 program, BaseEvent @event)
        {
            var iid = @event.IID;

            DLog.Debug(DContext.VSDebuggerEvent, "DebugPort Event {0} {1}", @event.GetType().Name, iid);
            foreach (var eventSink in eventSinks)
            {
                var events = eventSink as IDebugPortEvents2;
                if (events != null)
                {
                    var rc = events.Event(server, port, process, program, @event, ref iid);
                    if (!ErrorHandler.Succeeded(rc))
                    {
                        DLog.Error(DContext.VSDebuggerEvent, "DebugPort Event failed {0}", rc);
                    }
                }
            }
        }
예제 #14
0
        //Request Methods
        public async Task <TResult> Request <TResult>(string url, HttpMethod method, object data = null) where TResult : class
        {
            var logString = $"{method} - {url}\n";

            CurrentRequestState = RequestState.Ongoing;
            HttpResponseMessage response = null;

            try
            {
                HttpRequestMessage request = new HttpRequestMessage(method, url);
                if (data != null)
                {
                    var postContent = JsonConvert.SerializeObject(data);
                    logString      += $"Request Content - ${postContent}\n";
                    request.Content = new StringContent(postContent);
                    request.Content.Headers.ContentType = new MediaTypeHeaderValue(RequestContentType);
                }
                response = await _httpClient.SendAsync(request);
            }
            catch (Exception ex)
            {
                logString += $"Rest Client Exception - {ex.Message}\nStackTrace - {ex.StackTrace}";
            }

            if (response?.IsSuccessStatusCode ?? false)
            {
                var responseString = await response.Content.ReadAsStringAsync();

                DLog.Success($"{logString}Response Data - {responseString}");

                if (!String.IsNullOrEmpty(responseString))
                {
                    var result = JsonConvert.DeserializeObject <TResult>(responseString);
                    return(result);
                }

                CurrentRequestState = RequestState.Success;
                return(default(TResult));
            }

            DLog.Error($"{logString}Status Code - {response?.StatusCode}");
            CurrentRequestState = RequestState.Failed;
            return(default(TResult));
        }
예제 #15
0
        /// <summary>
        /// Resolve an assembly by name with given parameters.
        /// </summary>
        public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
        {
            AssemblyDefinition result;

            if (references.TryGetValue(name.Name, out result))
            {
                return(result);
            }

            var referencePaths = referenceFolders.Select(x => Path.Combine(x, name.Name + ".dll"));
            var path           = referencePaths.FirstOrDefault(x => string.Equals(Path.GetFileNameWithoutExtension(x), name.Name, StringComparison.OrdinalIgnoreCase) && File.Exists(x));

            if (path == null)
            {
                DLog.Error(DContext.CompilerAssemblyResolver, "Failed to resolve assembly {0} in {1}", name, string.Join(";  ", referenceFolders));
                throw new AssemblyResolutionException(name);
            }

            try
            {
                if (ShowLoading)
                {
                    Console.WriteLine(string.Format("Loading {0}", name.Name));
                }
                var reference = AssemblyDefinition.ReadAssembly(path, parameters);
                references[name.Name] = reference;
                return(reference);
            }
            catch (Exception ex)
            {
                // Unload the reference
                references.Remove(name.Name);
#if DEBUG
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
#endif
                // Log the error
                DLog.Error(DContext.CompilerAssemblyResolver, "Failed to load assembly {0}", ex, name);

                // Pass the error on
                throw new AssemblyResolutionException(name);
            }
        }
예제 #16
0
        /// <summary>
        /// Resolve an assembly by name with given parameters.
        /// </summary>
        public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
        {
            AssemblyDefinition result;

            if (referencesByName.TryGetValue(name.Name, out result))
            {
                return(result);
            }

            var path = ResolvePath(name.Name);

            if (path == null)
            {
                DLog.Error(DContext.CompilerAssemblyResolver, "Failed to resolve assembly {0} in {1}", name, string.Join(";  ", referenceFolders));
                throw new AssemblyResolutionException(name);
            }

            return(Load(name, path, parameters));
        }
예제 #17
0
        /// <summary>
        /// Allocates a single element!
        /// (ATTENTION THIS WILL RETURN AN OBJECT THAT ISN'T MANAGED BY THE POOL)
        /// </summary>
        /// <returns></returns>
        public virtual T AllocateSingle()
        {
            if (!this._isInitialized)
            {
                return(null);
            }

            if (this._objectLoadPolicy == null)
            {
                DLog.Error("Did you forget to set your object policy?!", DLogCategory.Loading);
                return(null);
            }

            try
            {
                T obj = this._objectLoadPolicy.Load();
                return(obj);
            }
            catch (Exception ex)
            {
                DLog.Error(ex, DLogCategory.Loading);
                return(null);
            }
        }
예제 #18
0
        /// <summary>
        /// Resumes process execution.
        /// </summary>
        public int ResumeProcess(IDebugProcess2 pProcess)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.ResumeProcess");
            var process = pProcess as DebugProcess;

            if (process == null)
            {
                return(VSConstants.E_INVALIDARG);
            }

            try
            {
                var program = process.Program;
                ((IDebugPortNotify2)process.Port).AddProgramNode(program);

                // Suspend and prepare the VM
                var debugger = process.Debugger;
                var suspend  = process.Debugger.VirtualMachine.SuspendAsync();
                var prepare  = suspend.ContinueWith(t => {
                    t.ForwardException();
                    return(debugger.PrepareAsync());
                }).Unwrap();
                var loadThreads = prepare.ContinueWith(t => {
                    t.ForwardException();
                    return(program.ThreadManager.RefreshAsync());
                }).Unwrap();
                loadThreads.ContinueWith(t => {
                    t.ForwardException();

                    // Notify module
                    eventCallback.Send(program, new ModuleLoadEvent(program.MainModule, "Loading module", true));
                    eventCallback.Send(program, new SymbolSearchEvent(program.MainModule, "Symbols loaded", enum_MODULE_INFO_FLAGS.MIF_SYMBOLS_LOADED));

                    var mainThread = program.ThreadManager.MainThread();
                    if (mainThread != null)
                    {
                        // Threads loaded
                        // Load complete
                        eventCallback.Send(mainThread, new LoadCompleteEvent());
                        eventCallback.Send(mainThread, new EntryPointEvent());

                        // Resume now
                        debugger.VirtualMachine.ResumeAsync();

                        // We're fully attached now
                        if (stateUpdate != null)
                        {
                            stateUpdate(LauncherStates.Attached, string.Empty);
                        }
                        stateUpdate = null;
                    }
                    else
                    {
                        DLog.Error(DContext.VSDebuggerLauncher, "No main thread found");
                    }
                });

                return(VSConstants.S_OK);
            }
            catch (Exception ex)
            {
                DLog.Error(DContext.VSDebuggerLauncher, "ResumeProcess failed", ex);
                return(VSConstants.E_FAIL);
            }
        }
        private void HandleCompositeCommand(JdwpPacket packet)
        {
            var data          = packet.Data;
            var suspendPolicy = (Jdwp.SuspendPolicy)data.GetByte();
            var count         = data.GetInt();

            for (var i = 0; i < count; i++)
            {
                var       eventKind = (Jdwp.EventKind)data.GetByte();
                JdwpEvent evt;
                switch (eventKind)
                {
                case Jdwp.EventKind.VmInit:
                    evt = new VmStart(data);
                    break;

                case Jdwp.EventKind.SingleStep:
                    evt = new SingleStep(data);
                    break;

                case Jdwp.EventKind.BreakPoint:
                    evt = new Breakpoint(data);
                    break;

                case Jdwp.EventKind.MethodEntry:
                    evt = new MethodEntry(data);
                    break;

                case Jdwp.EventKind.MethodExit:
                    evt = new MethodExit(data);
                    break;

                case Jdwp.EventKind.Exception:
                    evt = new Exception(data);
                    break;

                case Jdwp.EventKind.ThreadStart:
                    evt = new ThreadStart(data);
                    break;

                case Jdwp.EventKind.ThreadEnd:
                    evt = new ThreadDeath(data);
                    break;

                case Jdwp.EventKind.ClassPrepare:
                    evt = new ClassPrepare(data);
                    break;

                case Jdwp.EventKind.ClassUnload:
                    evt = new ClassUnload(data);
                    break;

                case Jdwp.EventKind.FieldAccess:
                    evt = new FieldAccess(data);
                    break;

                case Jdwp.EventKind.FieldModification:
                    evt = new FieldModification(data);
                    break;

                case Jdwp.EventKind.VmDeath:
                    evt = new VmDeath(data);
                    break;

                default:
                    throw new ArgumentException("Unknown event kind in compositive command " + (int)eventKind);
                }
                DLog.Debug(DContext.DebuggerLibDebugger, "JDWP event {0} {1}", eventKind, evt);
                Task.Factory.StartNew(() => {
                    evt.Accept(compositeCommandProcessor, suspendPolicy);
                }).ContinueWith(task =>
                {
                    DLog.Error(DContext.DebuggerLibJdwpConnection, "HandleCompositeCommand: Internal failure on event processing. SuspendPolicy was {1}; IsCancelled={0}. Exception={1}", suspendPolicy, task.IsCanceled, task.Exception);
                    if (suspendPolicy != Jdwp.SuspendPolicy.None)
                    {
                        // we should better resume the VM, as the command handler may have failed to do so.
                        if (Connected)
                        {
                            VirtualMachine.ResumeAsync();
                        }
                    }
                }, TaskContinuationOptions.NotOnRanToCompletion);
            }
        }
예제 #20
0
        /// <summary>
        /// Read incoming packets
        /// </summary>
        private void ReadLoop()
        {
            var myThread         = Thread.CurrentThread;
            var readBuffer       = new byte[1024 * 1024];
            var readBufferOffset = 0;

            while (readThread == myThread)
            {
                // Should we stop?
                if ((!tcpClient.Connected) || (readThread != myThread))
                {
                    return;
                }

                // Read all available data
                var available = tcpClient.Available;
                if (available > 0)
                {
                    Read(readBuffer, readBufferOffset, available);
                    readBufferOffset += available;
                }
                else if (readBufferOffset == 0)
                {
                    // Wait a while
                    Thread.Sleep(10);
                }

                // Try to find packet and process them
                if (readBufferOffset == 0)
                {
                    continue;
                }

                if (state == States.AwaitingHandshake)
                {
                    // Look for handshake
                    if (readBufferOffset < Handshake.Length)
                    {
                        continue;
                    }
                    if (Equals(readBuffer, Handshake, Handshake.Length))
                    {
                        DLog.Debug(DContext.DebuggerLibJdwpConnection, "Valid handshake received from VM");
                        // Found correct handshake
                        ConsumeReadBuffer(Handshake.Length, readBuffer, ref readBufferOffset);
                        state = States.Ready;
                        NotifyWriteQueue();
                    }
                    else
                    {
                        // Invalid handshake
                        DLog.Error(DContext.DebuggerLibJdwpConnection, "Received invalid handshape");
                    }
                }
                else if (state == States.Ready)
                {
                    // Normal packet expected
                    var packet = FindPacket(this, readBuffer, readBufferOffset);
                    if (packet == null)
                    {
                        continue;
                    }

                    // Remove packet from buffer
                    var length = packet.Length;
                    ConsumeReadBuffer(length, readBuffer, ref readBufferOffset);

#if DEBUG
                    DLog.Debug(DContext.DebuggerLibJdwpConnection,
                               "Read packet " + (packet.IsChunk() ? packet.AsChunk() : packet));
#endif

                    // Find callback
                    var processed = false;
                    if (packet.IsReply)
                    {
                        var packetId = packet.Id;
                        Action <JdwpPacket> callback;
                        if (callbacks.TryRemove(packetId, out callback))
                        {
                            // Perform callback.
                            processed = true;
                            callback(packet);
                        }
                    }
                    if (!processed)
                    {
                        if (packet.IsChunk())
                        {
                            // Handle non-reply chunks
                            chunkHandler(packet.AsChunk());
                        }
                        else if (!packet.IsReply)
                        {
                            // Handle non-reply packet
                            packetHandler(packet);
                        }
                        processed = true;
                    }

                    if (!processed)
                    {
                        DLog.Debug(DContext.DebuggerLibJdwpConnection, "Unknown JDWP packet read {0}", packet);
                    }
                }
            }
        }
예제 #21
0
 /// <summary>
 /// Write the error message at log file
 /// </summary>
 /// <param name="messageLog">Message to write on log file</param>
 public static void Error(string messageLog)
 {
     //Proceed to save log
     DLog.Error(messageLog);
 }
예제 #22
0
        /// <summary>
        /// this is fully reentrant and multithreading capable, but will itself block.
        /// </summary>
        private AssemblyDefinition Load(AssemblyNameReference name, string assemblyFilename, ReaderParameters parameters)
        {
            AssemblyDefinition ret = null;
            TaskCompletionSource <AssemblyDefinition> loadingTaskSource = new TaskCompletionSource <AssemblyDefinition>();

            bool nameRegistered = false, filenameRegistered = false;

            try
            {
                // First, make sure we are the only one loading.
                while (true)
                {
                    Task <AssemblyDefinition> loadingTask;
                    if (name != null && !nameRegistered)
                    {
                        if (loadingTasks.TryGetValue(name.Name, out loadingTask))
                        {
                            ret = loadingTask.Result;
                            return(ret);
                        }

                        if (!loadingTasks.TryAdd(name.Name, loadingTaskSource.Task))
                        {
                            continue;
                        }
                        nameRegistered = true;
                    }

                    if (loadingTasks.TryAdd(assemblyFilename, loadingTaskSource.Task))
                    {
                        filenameRegistered = true;
                        break;
                    }
                    if (loadingTasks.TryGetValue(assemblyFilename, out loadingTask))
                    {
                        if (loadingTask == loadingTaskSource.Task)
                        {
                            break;
                        }

                        ret = loadingTask.Result;
                        return(ret);
                    }
                }

                // now check if it has already been loaded.
                if (name != null)
                {
                    if (referencesByName.TryGetValue(name.Name, out ret))
                    {
                        return(ret);
                    }
                }

                ret = fileNamesByAssembly.FirstOrDefault(v => v.Value.Equals(assemblyFilename, StringComparison.InvariantCultureIgnoreCase)).Key;
                if (ret != null)
                {
                    return(ret);
                }

                // now load the assembly.
                Console.WriteLine("Loading {0}...", Path.GetFileName(assemblyFilename));

                AssemblyDefinition assm = AssemblyDefinition.ReadAssembly(assemblyFilename, parameters);

                VerifyFrameworkAssembly(assm, assemblyFilename);

                // have to use a lock to update both data structures at the same time.
                lock (referencesByName)
                {
                    // now check again by the assembly name if it has been loaded before.
                    // This can happen if we were only provided a file name
                    if (!referencesByName.TryAdd(assm.Name.Name, assm))
                    {
                        ret = referencesByName[assm.Name.Name];
                        return(ret);
                    }

                    fileNamesByAssembly[assm] = assemblyFilename;
                }

                ret = assm;

                // now notify any listeners. note that if we were called on multiple threads
                // these might be called reentrantly as well.

                if (assemblyLoaded != null)
                {
                    assemblyLoaded(ret);
                }

                if (classLoader != null)
                {
                    classLoader.LoadAssembly(ret);
                }

                // done.
                return(ret);
            }
            catch (Exception ex)
            {
#if DEBUG
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
#endif
                // Log the error
                var assemblyName = name == null?assemblyFilename:name.ToString();
                DLog.Error(DContext.CompilerAssemblyResolver, "Failed to load assembly {0}: {1}", assemblyName, ex.Message);

                // Pass the error on
                var exn = new AssemblyResolutionException(name ?? new AssemblyNameDefinition(assemblyFilename, new Version()));
                loadingTaskSource.SetException(exn);
                throw exn;
            }
            finally
            {
                loadingTaskSource.TrySetResult(ret);

                // cleanup our registrations
                Task <AssemblyDefinition> ignore;
                if (nameRegistered)
                {
                    loadingTasks.TryRemove(name.Name, out ignore);
                }
                if (filenameRegistered)
                {
                    loadingTasks.TryRemove(assemblyFilename, out ignore);
                }
            }
        }
예제 #23
0
        /// <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);
        }