Exemple #1
0
        /////////////////////////////////////////////////////////////////////////////////

        #region AppDomain EventHandler (ProcessExit / DomainUnload)
        private static void NativeStack_Exited(
            object sender,
            EventArgs e
            )
        {
            lock (syncRoot) /* TRANSACTIONAL */
            {
                if (ThreadContextBuffer != UIntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(ConversionOps.ToIntPtr(
                                              ThreadContextBuffer));

                    ThreadContextBuffer = UIntPtr.Zero;

                    AppDomain appDomain = AppDomainOps.GetCurrent();

                    if (appDomain != null)
                    {
                        if (!AppDomainOps.IsDefault(appDomain))
                        {
                            appDomain.DomainUnload -= NativeStack_Exited;
                        }
                        else
                        {
                            appDomain.ProcessExit -= NativeStack_Exited;
                        }
                    }
                }
            }
        }
Exemple #2
0
        ///////////////////////////////////////////////////////////////////////

        public static Assembly FindInAppDomain(
            AppDomain appDomain,
            AssemblyName assemblyName
            )
        {
            if (assemblyName != null)
            {
                if (appDomain == null)
                {
                    appDomain = AppDomainOps.GetCurrent();
                }

                if (appDomain != null)
                {
                    Assembly[] assemblies = appDomain.GetAssemblies();

                    foreach (Assembly assembly in assemblies)
                    {
                        if (assembly == null)
                        {
                            continue;
                        }

                        if (IsSameAssemblyName(
                                assembly.GetName(), assemblyName))
                        {
                            return(assembly);
                        }
                    }
                }
            }

            return(null);
        }
Exemple #3
0
        ///////////////////////////////////////////////////////////////////////

        public static Assembly FindInAppDomain(
            AppDomain appDomain,
            string name,
            Version version,
            byte[] publicKeyToken,
            ref Result error
            )
        {
            if (appDomain == null)
            {
                appDomain = AppDomainOps.GetCurrent();
            }

            if (appDomain != null)
            {
                Assembly[] assemblies = appDomain.GetAssemblies();

                foreach (Assembly assembly in assemblies)
                {
                    if (assembly == null)
                    {
                        continue;
                    }

                    AssemblyName assemblyName = assembly.GetName();

                    if (assemblyName == null)
                    {
                        continue;
                    }

                    if ((name != null) && !String.Equals(
                            assemblyName.Name, name,
                            StringOps.SystemStringComparisonType))
                    {
                        continue;
                    }

                    if ((version != null) && (PackageOps.VersionCompare(
                                                  assemblyName.Version, version) != 0))
                    {
                        continue;
                    }

                    if ((publicKeyToken != null) && !ArrayOps.Equals(
                            assemblyName.GetPublicKeyToken(), publicKeyToken))
                    {
                        continue;
                    }

                    return(assembly);
                }
            }

            error = "assembly not found in application domain";
            return(null);
        }
Exemple #4
0
        public static void DebugTrace(
            int?threadId,
            string message,
            string category,
            TracePriority priority
            )
        {
            if (!IsTracePossible())
            {
                return;
            }

            if (!IsTraceEnabled(priority)) /* HACK: *PERF* Bail. */
            {
                return;
            }

            string traceFormat = GetTraceFormat();

            if (traceFormat == null)
            {
                return;
            }

            bool traceDateTime;
            bool tracePriority;
            bool traceAppDomain;
            bool traceInterpreter;
            bool traceThreadId;
            bool traceMethod;

            GetTraceFormatFlags(
                out traceDateTime, out tracePriority, out traceAppDomain,
                out traceInterpreter, out traceThreadId, out traceMethod);

            string methodName = null;

            DebugTraceRaw(FormatOps.TraceOutput(traceFormat,
                                                traceDateTime ? (DateTime?)TimeOps.GetNow() : null,
                                                tracePriority ? (TracePriority?)priority : null,
                                                traceAppDomain ? AppDomainOps.GetCurrent() : null,
                                                traceInterpreter ? Interpreter.GetActive() : null,
                                                traceThreadId ? threadId : null, message, traceMethod,
                                                ref methodName), category, methodName, priority);
        }
Exemple #5
0
        public static void DebugWriteTo(
            Interpreter interpreter,
            string value,
            bool force
            )
        {
            if (!IsTracePossible())
            {
                return;
            }

            string traceFormat = GetTraceFormat();

            if (traceFormat == null)
            {
                return;
            }

            bool traceDateTime;
            bool tracePriority;
            bool traceAppDomain;
            bool traceInterpreter;
            bool traceThreadId;
            bool traceMethod;

            GetTraceFormatFlags(
                out traceDateTime, out tracePriority, out traceAppDomain,
                out traceInterpreter, out traceThreadId, out traceMethod);

            DebugOps.WriteTo(interpreter, FormatOps.TraceOutput(traceFormat,
                                                                traceDateTime ? (DateTime?)TimeOps.GetNow() : null, null,
                                                                traceAppDomain ? AppDomainOps.GetCurrent() : null,
                                                                traceInterpreter ? interpreter : null, traceThreadId ?
                                                                (int?)GlobalState.GetCurrentSystemThreadId() : null,
                                                                value, traceMethod), force);
        }
Exemple #6
0
        ///////////////////////////////////////////////////////////////////////

        #region Tracing Support Methods
        private static bool IsTracePossible()
        {
            /* NO-LOCK */
            return(isTracePossible && !AppDomainOps.IsCurrentFinalizing());
        }
Exemple #7
0
        /////////////////////////////////////////////////////////////////////////////////

        private static UIntPtr GetNativeRegister(
            IntPtr thread,
            uint flags,
            int offset,
            int size
            )
        {
            //
            // NOTE: Are we able to query the thread context (i.e. we know
            //       what platform we are on and the appropriate constants
            //       have been setup)?
            //
            if (!CanQueryThread)
            {
                if (Interlocked.Increment(ref CannotQueryThread) == 1)
                {
                    TraceOps.DebugTrace(
                        "GetNativeRegister: cannot query thread",
                        typeof(NativeStack).Name,
                        TracePriority.NativeError);
                }

                return(UIntPtr.Zero);
            }

            //
            // NOTE: We do not allow anybody to attempt to read outside what
            //       we think the bounds of the CONTEXT structure are.
            //
            if ((offset < 0) || (offset > (CONTEXT_SIZE - IntPtr.Size)))
            {
                return(UIntPtr.Zero);
            }

            try
            {
                lock (syncRoot) /* TRANSACTIONAL */
                {
                    //
                    // NOTE: Perform one-time allocation of the fixed-size
                    //       thread context buffer, on demand and schedule
                    //       to have it freed prior to process exit.
                    //
                    if (ThreadContextBuffer == UIntPtr.Zero)
                    {
                        //
                        // NOTE: Schedule the fixed-size thread context
                        //       buffer to be freed either upon the
                        //       AppDomain being unloaded (if we are not
                        //       in the default AppDomain) or when the
                        //       process exits.  This should gracefully
                        //       handle both embedding and stand-alone
                        //       scenarios.
                        //
                        AppDomain appDomain = AppDomainOps.GetCurrent();

                        if (appDomain != null)
                        {
                            if (!AppDomainOps.IsDefault(appDomain))
                            {
                                appDomain.DomainUnload += NativeStack_Exited;
                            }
                            else
                            {
                                appDomain.ProcessExit += NativeStack_Exited;
                            }
                        }

                        //
                        // NOTE: Now that we are sure that we have
                        //       succeeded in scheduling the cleanup for
                        //       this buffer, allocate it.
                        //
                        // NOTE: For safety, we now allocate at least a
                        //       whole page for this buffer.
                        //
                        // ThreadContextBuffer = ConversionOps.ToUIntPtr(
                        //     Marshal.AllocCoTaskMem((int)CONTEXT_SIZE));
                        //
                        ThreadContextBuffer = ConversionOps.ToUIntPtr(
                            Marshal.AllocCoTaskMem((int)Math.Max(
                                                       CONTEXT_SIZE, PlatformOps.GetPageSize())));
                    }

                    //
                    // NOTE: Make sure we were able to allocate the
                    //       thread context buffer.
                    //
                    if (ThreadContextBuffer == UIntPtr.Zero)
                    {
                        return(UIntPtr.Zero);
                    }

                    //
                    // NOTE: Internally convert our buffer UIntPtr to
                    //       IntPtr, as required by Marshal class.
                    //       This is absolutely required because
                    //       otherwise we end up calling the generic
                    //       version of the WriteInt32 and ReadInt32
                    //       methods (that take an object instead of
                    //       an IntPtr) and getting the wrong results.
                    //
                    IntPtr threadContext = ConversionOps.ToIntPtr(
                        ThreadContextBuffer);

                    //
                    // NOTE: Write flags that tell GetThreadContext
                    //       which fields of the thread context buffer
                    //       we would like it to populate.  For now,
                    //       we mainly want to support the control
                    //       registers (primarily for ESP and EBP).
                    //
                    Marshal.WriteInt32(
                        threadContext, (int)CONTEXT_FLAGS_OFFSET,
                        (int)flags);

                    //
                    // NOTE: Query the Win32 API to obtain the
                    //       requested thread context.  In theory,
                    //       this could fail or throw an exception
                    //       at this point.  In that case, we would
                    //       return zero from this function and the
                    //       stack checking code would assume that
                    //       native stack checking is unavailable
                    //       and should not be relied upon.
                    //
                    if (UnsafeNativeMethods.GetThreadContext(
                            thread, threadContext))
                    {
                        if (size == IntPtr.Size)
                        {
                            return(ConversionOps.ToUIntPtr(
                                       Marshal.ReadIntPtr(threadContext,
                                                          offset)));
                        }
                        else
                        {
                            switch (size)
                            {
                            case sizeof(long):
                            {
                                return(ConversionOps.ToUIntPtr(
                                           Marshal.ReadInt64(threadContext,
                                                             offset)));
                            }

                            case sizeof(int):
                            {
                                return(ConversionOps.ToUIntPtr(
                                           Marshal.ReadInt32(threadContext,
                                                             offset)));
                            }

                            case sizeof(short):
                            {
                                return(ConversionOps.ToUIntPtr(
                                           Marshal.ReadInt16(threadContext,
                                                             offset)));
                            }

                            case sizeof(byte):
                            {
                                return(ConversionOps.ToUIntPtr(
                                           Marshal.ReadByte(threadContext,
                                                            offset)));
                            }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (Interlocked.Increment(ref ContextException) == 1)
                {
                    TraceOps.DebugTrace(
                        e, typeof(NativeStack).Name,
                        TracePriority.NativeError);
                }
            }

            return(UIntPtr.Zero);
        }