Beispiel #1
0
        internal jvmtiError AddGlobalReference(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, jobject obj)
        {
            long       tag;
            jvmtiError error = environment.GetTag(obj, out tag);

            if (error != jvmtiError.None)
            {
                return(error);
            }

            if (tag == 0)
            {
                return(jvmtiError.IllegalArgument);
            }

            _globalReferences.AddOrUpdate(tag,
                                          t =>
            {
                return(Tuple.Create(nativeEnvironment.NewGlobalReference(obj), 1));
            },
                                          (t, v) =>
            {
                if (v.Item2 == 0)
                {
                    return(Tuple.Create(nativeEnvironment.NewGlobalReference(obj), 1));
                }
                else
                {
                    return(Tuple.Create(v.Item1, v.Item2 + 1));
                }
            });

            return(jvmtiError.None);
        }
Beispiel #2
0
        public jvalue(JavaVM virtualMachine, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, Value value)
            : this()
        {
            if (value.Data == 0)
                return;

            switch (value.Tag)
            {
            case Tag.Byte:
                ByteValue = (byte)value.Data;
                break;

            case Tag.Char:
                CharValue = (char)value.Data;
                break;

            case Tag.Float:
                IntValue = (int)(uint)value.Data;
                break;

            case Tag.Int:
                IntValue = (int)value.Data;
                break;

            case Tag.Double:
                LongValue = (long)(ulong)value.Data;
                break;

            case Tag.Long:
                LongValue = value.Data;
                break;

            case Tag.Short:
                ShortValue = (short)value.Data;
                break;

            case Tag.Boolean:
                break;

            case Tag.Array:
            case Tag.Object:
            case Tag.String:
            case Tag.Thread:
            case Tag.ThreadGroup:
            case Tag.ClassLoader:
            case Tag.ClassObject:
                if (value.Data == 0)
                    return;

                ObjectValue = virtualMachine.GetLocalReferenceForObject(nativeEnvironment, new ObjectId(value.Data)).Value;
                break;

            case Tag.Void:
            case Tag.Invalid:
            default:
                throw new ArgumentException();
            }
        }
            public static EventFilter CreateFilter(EventKind internalEventKind, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, RequestId requestId, SuspendPolicy suspendPolicy, ImmutableList<EventRequestModifier> modifiers)
            {
                if (modifiers.Count == 0)
                    return new PassThroughEventFilter(internalEventKind, requestId, suspendPolicy, modifiers);

                EventFilter[] elements = modifiers.Select(modifier => CreateFilter(internalEventKind, environment, nativeEnvironment, requestId, suspendPolicy, modifiers, modifier)).ToArray();
                if (elements.Length == 1)
                    return elements[0];

                return new AggregateEventFilter(internalEventKind, requestId, suspendPolicy, modifiers, elements);
            }
Beispiel #4
0
        internal TaggedReferenceTypeId TrackLocalClassReference(jclass classHandle, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, bool freeLocalReference)
        {
            if (classHandle == jclass.Null)
            {
                return(default(TaggedReferenceTypeId));
            }

            bool isArrayClass;

            JvmtiErrorHandler.ThrowOnFailure(environment.IsArrayClass(classHandle, out isArrayClass));
            bool isInterface;

            JvmtiErrorHandler.ThrowOnFailure(environment.IsInterface(classHandle, out isInterface));

            TypeTag typeTag = isArrayClass ? TypeTag.Array : (isInterface ? TypeTag.Interface : TypeTag.Class);

            int hashCode;

            JvmtiErrorHandler.ThrowOnFailure(environment.GetObjectHashCode(classHandle, out hashCode));

            ReferenceTypeId       typeId       = new ReferenceTypeId(hashCode);
            TaggedReferenceTypeId taggedTypeId = new TaggedReferenceTypeId(typeTag, typeId);

            lock (_classes)
            {
                if (!_classes.ContainsKey(typeId))
                {
                    jweak weak  = nativeEnvironment.NewWeakGlobalReference(classHandle);
                    bool  added = false;
                    if (!_classes.ContainsKey(typeId))
                    {
                        _classes.Add(typeId, new jclass(weak.Handle));
                        added = true;
                    }

                    if (!added)
                    {
                        nativeEnvironment.DeleteWeakGlobalReference(weak);
                    }
                }
            }

            if (freeLocalReference)
            {
                nativeEnvironment.DeleteLocalReference(classHandle);
            }

            return(taggedTypeId);
        }
Beispiel #5
0
        public int GetEnvironment(out JvmtiEnvironment environment)
        {
            jvmtiEnvHandle env;
            int            error = RawInterface.GetEnv(this, out env, jvmtiVersion.Version1_1);

            if (error == 0)
            {
                environment = JvmtiEnvironment.GetOrCreateInstance(this, env);
            }
            else
            {
                environment = null;
            }

            return(error);
        }
            private static EventFilter CreateFilter(EventKind internalEventKind, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, RequestId requestId, SuspendPolicy suspendPolicy, ImmutableList<EventRequestModifier> modifiers, EventRequestModifier modifier)
            {
                switch (modifier.Kind)
                {
                case ModifierKind.Count:
                    return new CountEventFilter(internalEventKind, requestId, suspendPolicy, modifiers, modifier.Count);

                case ModifierKind.ThreadFilter:
                    return new ThreadEventFilter(internalEventKind, requestId, suspendPolicy, modifiers, modifier.Thread);

                case ModifierKind.ClassTypeFilter:
                    throw new NotImplementedException();

                case ModifierKind.ClassMatchFilter:
                    throw new NotImplementedException();

                case ModifierKind.ClassExcludeFilter:
                    throw new NotImplementedException();

                case ModifierKind.LocationFilter:
                    return new LocationEventFilter(internalEventKind, requestId, suspendPolicy, modifiers, modifier.Location);

                case ModifierKind.ExceptionFilter:
                    return new ExceptionEventFilter(internalEventKind, requestId, suspendPolicy, modifiers, modifier.ExceptionOrNull, modifier.Caught, modifier.Uncaught);

                case ModifierKind.FieldFilter:
                    throw new NotImplementedException();

                case ModifierKind.Step:
                    return new StepEventFilter(internalEventKind, requestId, suspendPolicy, modifiers, modifier.Thread, environment, nativeEnvironment, modifier.StepSize, modifier.StepDepth);

                case ModifierKind.InstanceFilter:
                    throw new NotImplementedException();

                case ModifierKind.SourceNameMatchFilter:
                    throw new NotImplementedException();

                case ModifierKind.Conditional:
                    throw new NotImplementedException();

                case ModifierKind.Invalid:
                default:
                    throw new ArgumentException();
                }
            }
Beispiel #7
0
        public int AttachCurrentThreadAsDaemon(JvmtiEnvironment environment, out JniEnvironment nativeEnvironment, bool agentThread)
        {
            JavaVMAttachArgs args = new JavaVMAttachArgs(jniVersion.Version1_6, IntPtr.Zero, jthreadGroup.Null);

            bool alreadyAgent = IsAgentThread.Value;

            if (agentThread && !alreadyAgent)
            {
                IsAgentThread.Value = true;
            }

            JNIEnvHandle jniEnv;
            int          error = RawInterface.AttachCurrentThreadAsDaemon(this, out jniEnv, ref args);

            if (error == 0)
            {
                bool created;
                nativeEnvironment = JniEnvironment.GetOrCreateInstance(jniEnv, out created);
                if (agentThread && !alreadyAgent)
                {
                    if (environment == null)
                    {
                        GetEnvironment(out environment);
                    }

                    jthread thread;
                    JvmtiErrorHandler.ThrowOnFailure(environment.RawInterface.GetCurrentThread(environment, out thread));
                    if (thread != jthread.Null)
                    {
                        ThreadId threadId = TrackLocalThreadReference(thread, environment, nativeEnvironment, true);
                        lock (_agentThreads)
                        {
                            _agentThreads.Add(threadId);
                        }
                    }
                }
            }
            else
            {
                nativeEnvironment = null;
            }

            return(error);
        }
Beispiel #8
0
        internal jvmtiError RemoveGlobalReference(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, jobject obj)
        {
            long       tag;
            jvmtiError error = environment.GetTag(obj, out tag);

            if (error != jvmtiError.None)
            {
                return(error);
            }

            if (tag == 0)
            {
                return(jvmtiError.IllegalArgument);
            }

            var result = _globalReferences.AddOrUpdate(tag,
                                                       t =>
            {
                return(Tuple.Create(jobject.Null, 0));
            },
                                                       (t, v) =>
            {
                if (v.Item2 == 0)
                {
                    return(Tuple.Create(jobject.Null, 0));
                }
                else if (v.Item2 == 1)
                {
                    nativeEnvironment.DeleteGlobalReference(v.Item1);
                    return(Tuple.Create(jobject.Null, 0));
                }
                else
                {
                    return(Tuple.Create(v.Item1, v.Item2 - 1));
                }
            });

            return(jvmtiError.None);
        }
Beispiel #9
0
        internal ThreadId TrackLocalThreadReference(jthread thread, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, bool freeLocalReference)
        {
            if (thread == jthread.Null)
            {
                return(default(ThreadId));
            }

            int hashCode;

            JvmtiErrorHandler.ThrowOnFailure(environment.RawInterface.GetObjectHashCode(environment, thread, out hashCode));

            ThreadId threadId = new ThreadId(hashCode);

            lock (_threads)
            {
                if (!_threads.ContainsKey(threadId))
                {
                    jweak weak  = nativeEnvironment.NewWeakGlobalReference(thread);
                    bool  added = false;
                    if (!_threads.ContainsKey(threadId))
                    {
                        _threads.Add(threadId, new jthread(weak.Handle));
                        added = true;
                    }

                    if (!added)
                    {
                        nativeEnvironment.DeleteWeakGlobalReference(weak);
                    }
                }
            }

            if (freeLocalReference)
            {
                nativeEnvironment.DeleteLocalReference(thread);
            }

            return(threadId);
        }
Beispiel #10
0
        internal jclass FindBaseClass(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, jclass classHandle, string signature)
        {
            string currentSignature;
            string genericSignature;

            JvmtiErrorHandler.ThrowOnFailure(environment.GetClassSignature(classHandle, out currentSignature, out genericSignature));
            if (currentSignature == signature)
            {
                return((jclass)nativeEnvironment.NewGlobalReference(classHandle));
            }

            jclass superClass = nativeEnvironment.GetSuperclass(classHandle);

            if (superClass == jclass.Null)
            {
                return(jclass.Null);
            }

            jclass result = FindBaseClass(environment, nativeEnvironment, superClass, signature);

            nativeEnvironment.DeleteLocalReference(superClass);
            return(result);
        }
Beispiel #11
0
        internal void HandleVMInit(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, jthread thread)
        {
            jclass threadClass = nativeEnvironment.GetObjectClass(thread);

            _threadClass = FindBaseClass(environment, nativeEnvironment, threadClass, "Ljava/lang/Thread;");

            {
                jclass classClass = nativeEnvironment.GetObjectClass(threadClass);
                _classClass = FindBaseClass(environment, nativeEnvironment, classClass, "Ljava/lang/Class;");
                nativeEnvironment.DeleteLocalReference(classClass);
            }

            {
                jvmtiThreadInfo threadInfo;
                JvmtiErrorHandler.ThrowOnFailure(environment.GetThreadInfo(thread, out threadInfo));
                jclass threadGroupClass = nativeEnvironment.GetObjectClass(threadInfo._threadGroup);
                _threadGroupClass = FindBaseClass(environment, nativeEnvironment, threadGroupClass, "Ljava/lang/ThreadGroup;");

                jclass classLoaderClass = nativeEnvironment.GetObjectClass(threadInfo._contextClassLoader);
                _classLoaderClass = FindBaseClass(environment, nativeEnvironment, classLoaderClass, "Ljava/lang/ClassLoader;");
                nativeEnvironment.DeleteLocalReference(classLoaderClass);

                nativeEnvironment.DeleteLocalReference(threadGroupClass);
                nativeEnvironment.DeleteLocalReference(threadInfo._contextClassLoader);
                nativeEnvironment.DeleteLocalReference(threadInfo._threadGroup);
                environment.Deallocate(threadInfo._name);
            }

            nativeEnvironment.DeleteLocalReference(threadClass);

            jobject stringObject = nativeEnvironment.NewString(string.Empty);
            jclass  stringClass  = nativeEnvironment.GetObjectClass(stringObject);

            _stringClass = FindBaseClass(environment, nativeEnvironment, stringClass, "Ljava/lang/String;");
            nativeEnvironment.DeleteLocalReference(stringObject);
            nativeEnvironment.DeleteLocalReference(stringClass);
        }
            public override bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location)
            {
                _current++;
                if (_current == _count)
                {
                    _current = 0;
                    return true;
                }

                return false;
            }
            public override bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location)
            {
                if (!location.HasValue)
                    return false;

                return _location.Index == location.Value.Index
                    && _location.Class == location.Value.Class
                    && _location.Method == location.Value.Method;
            }
            private bool ShouldSkipCurrentMethod(JavaVM virtualMachine, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, jthread thread, int stackDepth, Location location, out bool convertToFramePop)
            {
                Contract.Assert(_depth == StepDepth.Into || _depth == StepDepth.Over);

                convertToFramePop = false;

                if (!_hasMethodInfo || stackDepth < _stackDepth || (stackDepth == _stackDepth && (location.Method.Equals(_lastMethod))))
                    return false;

                /*
                 * change this to a Frame Pop event if we're not in a native frame
                 */
                bool native;
                jvmtiError error = environment.IsMethodNative(location.Method, out native);
                if (error != jvmtiError.None)
                    return false;

                convertToFramePop = !native;

                if (_depth == StepDepth.Over || native)
                    return true;

                JvmAccessModifiers modifiers;
                error = environment.GetMethodModifiers(location.Method, out modifiers);
                if (error != jvmtiError.None || ((modifiers & JvmAccessModifiers.Static) != 0))
                    return false;

                jobject thisObject;
                error = environment.GetLocalObject(thread, 0, 0, out thisObject);
                if (error != jvmtiError.None)
                    return false;

                try
                {
                    bool classLoader = nativeEnvironment.IsInstanceOf(thisObject, virtualMachine.ClassLoaderClass);
                    if (!classLoader)
                        return false;

                    string name;
                    string signature;
                    string genericSignature;
                    error = environment.GetMethodName(location.Method, out name, out signature, out genericSignature);
                    if (error != jvmtiError.None)
                        return false;

                    if (name == "loadClass" && signature == "(Ljava/lang/String;)Ljava/lang/Class;")
                        return true;

                    if (name == "checkPackageAccess" && signature == "(Ljava/lang/Class;Ljava/security/ProtectionDomain;)V")
                        return true;

                    return false;
                }
                finally
                {
                    nativeEnvironment.DeleteLocalReference(thisObject);
                }
            }
            private jvmtiError ApplySuspendPolicy(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, SuspendPolicy policy, ThreadId eventThread)
            {
                if (policy == SuspendPolicy.EventThread && eventThread == default(ThreadId))
                {
                    return jvmtiError.InvalidThread;
                }

                switch (policy)
                {
                case SuspendPolicy.None:
                    return jvmtiError.None;

                case SuspendPolicy.EventThread:
                    return environment.SuspendThread(nativeEnvironment, eventThread);

                case SuspendPolicy.All:
                    ThreadId[] requestList;
                    JvmtiErrorHandler.ThrowOnFailure(environment.GetAllThreads(nativeEnvironment, out requestList));
                    jvmtiError[] errors;
                    return environment.SuspendThreads(nativeEnvironment, requestList, out errors);

                default:
                    throw new ArgumentException("Invalid suspend policy.");
                }
            }
            public Error SetEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventKind eventKind, SuspendPolicy suspendPolicy, ImmutableList<EventRequestModifier> modifiers, bool internalRequest, out RequestId requestId)
            {
                Contract.Requires<ArgumentNullException>(modifiers != null, "modifiers");

                requestId = default(RequestId);

                EventKind internalEventKind = eventKind;

                EventRequestModifier locationModifier = default(EventRequestModifier);
                EventRequestModifier stepModifier = default(EventRequestModifier);

                switch (eventKind)
                {
                case EventKind.Breakpoint:
                    // we're going to need the location modifier to set the breakpoint
                    if (modifiers.Count == 0 || modifiers[0].Kind != ModifierKind.LocationFilter)
                        return Error.IllegalArgument;

                    locationModifier = modifiers[0];
                    break;

                case EventKind.SingleStep:
                    // the first modifier contains the step properties
                    if (modifiers.Count == 0 || modifiers[0].Kind != ModifierKind.Step)
                        return Error.IllegalArgument;

                    stepModifier = modifiers[0];
                    if (stepModifier.StepDepth == StepDepth.Out)
                    {
                        // we want to attach the filter as a frame pop request instead of a step request
                        eventKind = EventKind.FramePop;
                        internalEventKind = EventKind.SingleStep;
                    }

                    break;

                default:
                    break;
                }

                requestId = new RequestId(Interlocked.Increment(ref _nextRequestId));
                if (internalRequest)
                    requestId = new RequestId(-requestId.Id);

                EventFilter filter = EventFilter.CreateFilter(internalEventKind, environment, nativeEnvironment, requestId, suspendPolicy, modifiers);
                return SetEventInternal(environment, nativeEnvironment, eventKind, filter);
            }
            private void SendClassPrepareEvent(JvmtiEnvironment environment, EventFilter filter, ThreadId threadId, TaggedReferenceTypeId classId, string signature, ClassStatus classStatus, bool preventSuspend)
            {
                if (!VirtualMachine.IsAgentThread.Value)
                {
                    // ignore events before VMInit
                    if (AgentEventDispatcher == null)
                        return;

                    // dispatch this call to an agent thread
                    Action<JvmtiEnvironment, EventFilter, ThreadId, TaggedReferenceTypeId, string, ClassStatus, bool> method = SendClassPrepareEvent;
                    AgentEventDispatcher.Invoke(method, environment, filter, threadId, classId, signature, classStatus, preventSuspend);
                    return;
                }

                JniEnvironment nativeEnvironment;
                JniErrorHandler.ThrowOnFailure(VirtualMachine.AttachCurrentThreadAsDaemon(environment, out nativeEnvironment, true));

                SuspendPolicy suspendPolicy = preventSuspend ? SuspendPolicy.None : filter.SuspendPolicy;
                if (!preventSuspend)
                    ApplySuspendPolicy(environment, nativeEnvironment, filter.SuspendPolicy, threadId);

                Callback.ClassPrepare(suspendPolicy, filter.RequestId, threadId, classId.TypeTag, classId.TypeId, signature, classStatus);
            }
 public override bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location)
 {
     return true;
 }
        private jvmtiError GetEnvironment(out JvmtiEnvironment environment, out JniEnvironment nativeEnvironment)
        {
            environment = null;
            nativeEnvironment = null;

            environment = _environment;
            int error = VirtualMachine.AttachCurrentThreadAsDaemon(environment, out nativeEnvironment, true);
            if (error != 0)
                return GetToolsErrorForJniError(error);

            //error = VirtualMachine.GetEnvironment(out environment);
            //if (error != 0)
            //    return GetToolsErrorForJniError(error);

            return jvmtiError.None;
        }
            public StepEventFilter(EventKind internalEventKind, RequestId requestId, SuspendPolicy suspendPolicy, IEnumerable<EventRequestModifier> modifiers, ThreadId thread, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, StepSize size, StepDepth depth)
                : base(internalEventKind, requestId, suspendPolicy, modifiers, thread)
            {
                if (size == StepSize.Statement && JavaVM.DisableStatementStepping)
                    size = StepSize.Line;

                _size = size;
                _depth = depth;

                // gather reference information for the thread
                using (var threadHandle = environment.VirtualMachine.GetLocalReferenceForThread(nativeEnvironment, thread))
                {
                    if (threadHandle.IsAlive)
                    {
                        jvmtiError error = environment.GetFrameLocation(threadHandle.Value, 0, out _lastMethod, out _lastLocation);
                        if (error == jvmtiError.None)
                            error = environment.GetFrameCount(threadHandle.Value, out _stackDepth);

                        if (error == jvmtiError.None)
                            _hasMethodInfo = true;

                        UpdateLastLine(environment);

                        if (error == jvmtiError.None && size == StepSize.Statement && (depth == StepDepth.Over || depth == StepDepth.Into))
                        {
                            byte[] bytecode;
                            JvmtiErrorHandler.ThrowOnFailure(environment.GetBytecodes(_lastMethod, out bytecode));
                            _disassembledMethod = BytecodeDisassembler.Disassemble(bytecode);

                            TaggedReferenceTypeId declaringClass;
                            JvmtiErrorHandler.ThrowOnFailure(environment.GetMethodDeclaringClass(nativeEnvironment, _lastMethod, out declaringClass));
                            using (var classHandle = environment.VirtualMachine.GetLocalReferenceForClass(nativeEnvironment, declaringClass.TypeId))
                            {
                                int constantPoolCount;
                                byte[] data;
                                JvmtiErrorHandler.ThrowOnFailure(environment.GetConstantPool(classHandle.Value, out constantPoolCount, out data));

                                List<ConstantPoolEntry> entryList = new List<ConstantPoolEntry>();
                                int currentPosition = 0;
                                for (int i = 0; i < constantPoolCount - 1; i++)
                                {
                                    entryList.Add(ConstantPoolEntry.FromBytes(data, ref currentPosition));
                                    switch (entryList.Last().Type)
                                    {
                                    case ConstantType.Double:
                                    case ConstantType.Long:
                                        // these entries take 2 slots
                                        entryList.Add(ConstantPoolEntry.Reserved);
                                        i++;
                                        break;

                                    default:
                                        break;
                                    }
                                }

                                _constantPool = entryList.AsReadOnly();

                                string classSignature;
                                string classGenericSignature;
                                JvmtiErrorHandler.ThrowOnFailure(environment.GetClassSignature(classHandle.Value, out classSignature, out classGenericSignature));
                                string methodName;
                                string methodSignature;
                                string methodGenericSignature;
                                JvmtiErrorHandler.ThrowOnFailure(environment.GetMethodName(_lastMethod, out methodName, out methodSignature, out methodGenericSignature));

                                jobject classLoader;
                                JvmtiErrorHandler.ThrowOnFailure(environment.GetClassLoader(classHandle.Value, out classLoader));
                                long classLoaderTag;
                                JvmtiErrorHandler.ThrowOnFailure(environment.TagClassLoader(classLoader, out classLoaderTag));

                                ReadOnlyCollection<ExceptionTableEntry> exceptionTable;
                                JvmtiErrorHandler.ThrowOnFailure(environment.VirtualMachine.GetExceptionTable(classLoaderTag, classSignature, methodName, methodSignature, out exceptionTable));

                                _evaluationStackDepths = BytecodeDisassembler.GetEvaluationStackDepths(_disassembledMethod, _constantPool, exceptionTable);
                            }
                        }
                    }
                }
            }
            private void UpdateLastLine(JvmtiEnvironment environment)
            {
                _lastLine = null;
                if (!_hasMethodInfo)
                    return;

                LineNumberData[] lines;
                jvmtiError error = environment.GetLineNumberTable(_lastMethod, out lines);
                if (error != jvmtiError.None)
                    return;

                LineNumberData entry = lines.LastOrDefault(i => i.LineCodeIndex <= _lastLocation.Value);
                if (entry.LineNumber != 0)
                    _lastLine = entry.LineNumber;
            }
 public abstract bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location);
Beispiel #23
0
        public static unsafe int OnLoad(IntPtr vmPtr, IntPtr optionsPtr, IntPtr reserved)
        {
            _loaded = true;

            JavaVM vm = JavaVM.GetOrCreateInstance(new JavaVMHandle(vmPtr));

            string optionsString = null;

            if (optionsPtr != IntPtr.Zero)
            {
                optionsString = ModifiedUTF8Encoding.GetString((byte *)optionsPtr);
            }

            string[] options = new string[0];
            if (optionsString != null)
            {
                options = optionsString.Split(',', ';');
            }

#if false
            // quick test
            GetEnvironmentVersion(vm);

            Action <JavaVM> action = GetEnvironmentVersion;
            IAsyncResult    result = action.BeginInvoke(vm, null, null);
            result.AsyncWaitHandle.WaitOne();
#endif

            AppDomain.CurrentDomain.AssemblyResolve += HandleAssemblyResolve;

            if (options.Contains("ShowAgentExceptions", StringComparer.OrdinalIgnoreCase))
            {
                AppDomain.CurrentDomain.FirstChanceException += HandleFirstChanceException;
                AppDomain.CurrentDomain.UnhandledException   += HandleUnhandledException;
                //AppDomain.CurrentDomain.ProcessExit += HandleProcessExit;
            }

            if (options.Contains("DisableStatementStepping", StringComparer.OrdinalIgnoreCase))
            {
                JavaVM.DisableStatementStepping = true;
            }

            List <WaitHandle> waitHandles = new List <WaitHandle>();
            Binding           binding;

            /*
             * start the wcf services and wait for the client to connect
             */

#if false
            /* IJvmEventsService
             */
            _jvmEventsPublisherHost = new ServiceHost(typeof(JvmEventsPublisher));
            Binding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                ReceiveTimeout = TimeSpan.MaxValue,
                SendTimeout    = TimeSpan.MaxValue
            };

            _jvmEventsPublisherHost.AddServiceEndpoint(typeof(IJvmEventsService), binding, "net.pipe://localhost/Tvl.Java.DebugHost/JvmEventsService/");
            IAsyncResult jvmEventsPublisherStartResult = _jvmEventsPublisherHost.BeginOpen(null, null);
            waitHandles.Add(jvmEventsPublisherStartResult.AsyncWaitHandle);

            /* IJvmToolsInterfaceService
             */
            _jvmToolsInterfaceHost = new ServiceHost(typeof(JvmToolsInterfaceService));
            binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                ReceiveTimeout = TimeSpan.MaxValue,
                SendTimeout    = TimeSpan.MaxValue
            };

            _jvmToolsInterfaceHost.AddServiceEndpoint(typeof(IJvmToolsInterfaceService), binding, "net.pipe://localhost/Tvl.Java.DebugHost/JvmToolsInterfaceService/");
            IAsyncResult toolsInterfaceStartResult = _jvmToolsInterfaceHost.BeginOpen(null, null);
            waitHandles.Add(toolsInterfaceStartResult.AsyncWaitHandle);

            /* IJvmDebugSessionService
             */
            _jvmDebugSessionHost = new ServiceHost(typeof(JvmDebugSessionService));
            binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                ReceiveTimeout = TimeSpan.MaxValue,
                SendTimeout    = TimeSpan.MaxValue
            };

            _jvmDebugSessionHost.AddServiceEndpoint(typeof(IJvmDebugSessionService), binding, "net.pipe://localhost/Tvl.Java.DebugHost/JvmDebugSessionService/");
            IAsyncResult debugSessionStartResult = _jvmDebugSessionHost.BeginOpen(null, null);
            waitHandles.Add(debugSessionStartResult.AsyncWaitHandle);
#endif

            /* IDebugProtocolService
             */
            var debugProtocolService = new DebugProtocolService(vm);
            _debugProtocolHost = new ServiceHost(debugProtocolService);
            binding            = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                MaxReceivedMessageSize = 10 * 1024 * 1024,
                ReceiveTimeout         = TimeSpan.MaxValue,
                SendTimeout            = TimeSpan.MaxValue
            };

            _debugProtocolHost.AddServiceEndpoint(typeof(IDebugProtocolService), binding, "net.pipe://localhost/Tvl.Java.DebugHost/DebugProtocolService/");
            IAsyncResult debugProtocolStartResult = _debugProtocolHost.BeginOpen(null, null);
            waitHandles.Add(debugProtocolStartResult.AsyncWaitHandle);

            /* Wait for the services to finish opening
             */
            WaitHandle.WaitAll(waitHandles.ToArray());

            EventWaitHandle eventWaitHandle = null;
            try
            {
                eventWaitHandle = EventWaitHandle.OpenExisting(string.Format("JavaDebuggerInitHandle{0}", Process.GetCurrentProcess().Id));
            }
            catch (WaitHandleCannotBeOpenedException)
            {
                // must have been launched without the debugger
            }

            if (eventWaitHandle != null)
            {
                eventWaitHandle.Set();
                Action           waitAction  = _debuggerAttachComplete.Wait;
                IAsyncResult     waitResult  = waitAction.BeginInvoke(vm.HandleAsyncOperationComplete, null);
                DispatcherFrame  frame       = new DispatcherFrame(true);
                JvmtiEnvironment environment = debugProtocolService.Environment;
                vm.PushDispatcherFrame(frame, environment, waitResult);
            }

            return(0);
        }
            public override bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location)
            {
                foreach (EventFilter filter in _filters)
                {
                    if (!filter.ProcessEvent(environment, nativeEnvironment, processor, thread, @class, location))
                        return false;
                }

                return true;
            }
            public Error SetEventInternal(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventKind eventKind, EventFilter filter)
            {
                EventRequestModifier locationModifier = default(EventRequestModifier);
                EventRequestModifier stepModifier = default(EventRequestModifier);

                switch (eventKind)
                {
                case EventKind.Breakpoint:
                    // we're going to need the location modifier to set the breakpoint
                    if (filter.Modifiers.Count == 0 || filter.Modifiers[0].Kind != ModifierKind.LocationFilter)
                        return Error.IllegalArgument;

                    locationModifier = filter.Modifiers[0];
                    break;

                case EventKind.SingleStep:
                    // the first modifier contains the step properties
                    if (filter.Modifiers.Count == 0 || filter.Modifiers[0].Kind != ModifierKind.Step)
                        return Error.IllegalArgument;

                    stepModifier = filter.Modifiers[0];
                    break;

                case EventKind.FramePop:
                    if (filter.InternalEventKind == EventKind.SingleStep)
                        goto case EventKind.SingleStep;

                    break;

                default:
                    break;
                }

                lock (_eventRequests)
                {
                    Dictionary<RequestId, EventFilter> requests;
                    if (!_eventRequests.TryGetValue(eventKind, out requests))
                    {
                        requests = new Dictionary<RequestId, EventFilter>();
                        _eventRequests.Add(eventKind, requests);
                    }

                    requests.Add(filter.RequestId, filter);
                    if (requests.Count == 1)
                    {
                        JvmEventType? eventToEnable = GetJvmEventType(eventKind);

                        if (eventToEnable != null)
                        {
                            jvmtiError error = Environment.SetEventNotificationMode(JvmEventMode.Enable, eventToEnable.Value);
                            if (error != jvmtiError.None)
                                return GetStandardError(error);
                        }
                    }
                }

                switch (eventKind)
                {
                case EventKind.Breakpoint:
                    {
                        Contract.Assert(locationModifier.Kind == ModifierKind.LocationFilter);
                        jmethodID methodId = locationModifier.Location.Method;
                        jlocation location = new jlocation((long)locationModifier.Location.Index);
                        jvmtiError error = Environment.SetBreakpoint(methodId, location);
                        if (error != jvmtiError.None)
                            return GetStandardError(error);

                        break;
                    }

                case EventKind.FramePop:
                    if (filter.InternalEventKind == EventKind.SingleStep)
                    {
                        using (var thread = VirtualMachine.GetLocalReferenceForThread(nativeEnvironment, stepModifier.Thread))
                        {
                            if (!thread.IsAlive)
                                return Error.InvalidThread;

                            jvmtiError error = environment.RawInterface.NotifyFramePop(environment, thread.Value, 0);
                            if (error != jvmtiError.None)
                                return GetStandardError(error);
                        }
                    }

                    break;

                default:
                    break;
                }

                return Error.None;
            }
Beispiel #26
0
        internal TaggedObjectId TrackLocalObjectReference(jobject @object, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, bool freeLocalReference)
        {
            if (@object == jobject.Null)
            {
                return(new TaggedObjectId(Tag.Object, new ObjectId(0), default(TaggedReferenceTypeId)));
            }

            long tag;

            JvmtiErrorHandler.ThrowOnFailure(environment.GetTag(@object, out tag));

            TaggedReferenceTypeId type = default(TaggedReferenceTypeId);
            Tag objectKind;

            if (tag == 0)
            {
                long uniqueTag = Interlocked.Increment(ref _nextTag);

                /* first figure out what type of object we're dealing with. could be:
                 *  - String
                 *  - Thread
                 *  - ThreadGroup
                 *  - ClassLoader
                 *  - ClassObject
                 *  - Array
                 *  - Object
                 */

                // check for array
                jclass objectClass = nativeEnvironment.GetObjectClass(@object);
                try
                {
                    type = TrackLocalClassReference(objectClass, environment, nativeEnvironment, false);

                    bool isArray = type.TypeTag == TypeTag.Array;
                    if (isArray)
                    {
                        objectKind = Tag.Array;
                    }
                    else
                    {
                        if (_stringClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _stringClass))
                        {
                            objectKind = Tag.String;
                        }
                        else if (_threadClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _threadClass))
                        {
                            objectKind = Tag.Thread;
                        }
                        else if (_threadGroupClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _threadGroupClass))
                        {
                            objectKind = Tag.ThreadGroup;
                        }
                        else if (_classClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _classClass))
                        {
                            objectKind = Tag.ClassObject;
                        }
                        else if (_classLoaderClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _classLoaderClass))
                        {
                            objectKind = Tag.ClassLoader;
                        }
                        else
                        {
                            objectKind = Tag.Object;
                        }
                    }
                }
                finally
                {
                    nativeEnvironment.DeleteLocalReference(objectClass);
                }

                tag = (uniqueTag << 8) | (uint)objectKind;
                JvmtiErrorHandler.ThrowOnFailure(environment.SetTag(@object, tag));

                lock (_objects)
                {
                    _objects.Add(new ObjectId(tag), nativeEnvironment.NewWeakGlobalReference(@object));
                }
            }
            else
            {
                jclass objectClass = nativeEnvironment.GetObjectClass(@object);
                type = TrackLocalClassReference(objectClass, environment, nativeEnvironment, true);
            }

            if (freeLocalReference)
            {
                nativeEnvironment.DeleteLocalReference(@object);
            }

            objectKind = (Tag)(tag & 0xFF);
            return(new TaggedObjectId(objectKind, new ObjectId(tag), type));
        }
 private void InitializeAgentThread(JvmtiEnvironment environment, JniEnvironment nativeEnvironment)
 {
     _agentStartedEvent = new ManualResetEventSlim(false);
     _agentThread = CreateAgentThread(nativeEnvironment);
     _agentCallbackDelegate = AgentDispatcherThread;
     JvmtiErrorHandler.ThrowOnFailure(environment.RawInterface.RunAgentThread(environment, _agentThread, _agentCallbackDelegate, IntPtr.Zero, JvmThreadPriority.Maximum));
     _agentStartedEvent.Wait();
 }
            public override bool ProcessEvent(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, EventProcessor processor, ThreadId thread, TaggedReferenceTypeId @class, Location? location)
            {
                if (!base.ProcessEvent(environment, nativeEnvironment, processor, thread, @class, location))
                    return false;

                // Step Out is implemented with Frame Pop events set at the correct depth
                if (_depth == StepDepth.Out)
                {
                    if (location.HasValue && !location.Value.Method.Equals(_lastMethod))
                    {
                        _lastLocation = new jlocation((long)location.Value.Index);
                        _lastMethod = location.Value.Method;
                        UpdateLastLine(environment);
                    }

                    return true;
                }

                using (var threadHandle = environment.VirtualMachine.GetLocalReferenceForThread(nativeEnvironment, thread))
                {
                    int stackDepth;
                    JvmtiErrorHandler.ThrowOnFailure(environment.GetFrameCount(threadHandle.Value, out stackDepth));

                    if (_hasMethodInfo && stackDepth > _stackDepth)
                    {
                        bool convertToFramePop;
                        if (location.HasValue && (!_convertedToFramePop || !_framePopMethod.Equals(location.Value.Method)) && ShouldSkipCurrentMethod(processor.VirtualMachine, environment, nativeEnvironment, threadHandle.Value, stackDepth, location.Value, out convertToFramePop))
                        {
                            if (convertToFramePop)
                            {
                                // remove the single step event
                                JvmtiErrorHandler.ThrowOnFailure((jvmtiError)processor.ClearEventInternal(EventKind.FramePop, this.RequestId));
                                JvmtiErrorHandler.ThrowOnFailure((jvmtiError)processor.ClearEventInternal(EventKind.SingleStep, this.RequestId));
                                // set an actual step filter to respond when the thread arrives back in this frame
                                JvmtiErrorHandler.ThrowOnFailure((jvmtiError)processor.SetEventInternal(environment, nativeEnvironment, EventKind.FramePop, this));
                                _convertedToFramePop = true;
                                _framePopMethod = location.Value.Method;
                            }

                            return false;
                        }
                        else
                        {
                            _convertedToFramePop = false;
                            return true;
                        }
                    }
                    else if (stackDepth == _stackDepth)
                    {
                        if (_size == StepSize.Statement && _disassembledMethod != null)
                        {
                            int instructionIndex = _disassembledMethod.Instructions.FindIndex(i => (uint)i.Offset == location.Value.Index);
                            if (instructionIndex >= 0 && _evaluationStackDepths != null && (_evaluationStackDepths[instructionIndex] ?? 0) != 0)
                            {
                                return false;
                            }
                            else if (instructionIndex >= 0 && _disassembledMethod.Instructions[instructionIndex].OpCode.FlowControl == JavaFlowControl.Branch)
                            {
                                // follow branch instructions before stopping
                                return false;
                            }
                        }
                        else if (_lastLine != null)
                        {
                            // see if we're on the same line
                            LineNumberData[] lines;
                            jvmtiError error = environment.GetLineNumberTable(location.Value.Method, out lines);
                            if (error == jvmtiError.None)
                            {
                                LineNumberData entry = lines.LastOrDefault(i => i.LineCodeIndex <= (long)location.Value.Index);
                                if (entry.LineNumber == _lastLine)
                                    return false;
                            }
                        }
                    }

                    if (location.HasValue)
                    {
                        _lastLocation = new jlocation((long)location.Value.Index);
                        _lastMethod = location.Value.Method;
                        UpdateLastLine(environment);
                    }

                    _stackDepth = stackDepth;
                    return true;
                }
            }
            private void SendSingleStepEvent(JvmtiEnvironment environment, EventFilter filter, ThreadId threadId, Location location)
            {
                if (!VirtualMachine.IsAgentThread.Value)
                {
                    // ignore events before VMInit
                    if (AgentEventDispatcher == null)
                        return;

                    // dispatch this call to an agent thread
                    Action<JvmtiEnvironment, EventFilter, ThreadId, Location> invokeMethod = SendSingleStepEvent;
                    AgentEventDispatcher.Invoke(invokeMethod, environment, filter, threadId, location);
                    return;
                }

                JniEnvironment nativeEnvironment;
                JniErrorHandler.ThrowOnFailure(VirtualMachine.AttachCurrentThreadAsDaemon(environment, out nativeEnvironment, false));

                ApplySuspendPolicy(environment, nativeEnvironment, filter.SuspendPolicy, threadId);
                Callback.SingleStep(filter.SuspendPolicy, filter.RequestId, threadId, location);
            }
Beispiel #30
0
        public jvalue(JavaVM virtualMachine, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, Value value)
            : this()
        {
            if (value.Data == 0)
            {
                return;
            }

            switch (value.Tag)
            {
            case Tag.Byte:
                ByteValue = (byte)value.Data;
                break;

            case Tag.Char:
                CharValue = (char)value.Data;
                break;

            case Tag.Float:
                IntValue = (int)(uint)value.Data;
                break;

            case Tag.Int:
                IntValue = (int)value.Data;
                break;

            case Tag.Double:
                LongValue = (long)(ulong)value.Data;
                break;

            case Tag.Long:
                LongValue = value.Data;
                break;

            case Tag.Short:
                ShortValue = (short)value.Data;
                break;

            case Tag.Boolean:
                break;

            case Tag.Array:
            case Tag.Object:
            case Tag.String:
            case Tag.Thread:
            case Tag.ThreadGroup:
            case Tag.ClassLoader:
            case Tag.ClassObject:
                if (value.Data == 0)
                {
                    return;
                }

                ObjectValue = virtualMachine.GetLocalReferenceForObject(nativeEnvironment, new ObjectId(value.Data)).Value;
                break;

            case Tag.Void:
            case Tag.Invalid:
            default:
                throw new ArgumentException();
            }
        }