Esempio n. 1
0
        protected override void OnRun(DebuggerStartInfo startInfo)
        {
            // Create the debugger

            string dversion = CorDebugger.GetDebuggerVersionFromFile(startInfo.Command);

            dbg = new CorDebugger(dversion);

            Dictionary <string, string> env = new Dictionary <string, string> ();

            foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
            {
                env[(string)de.Key] = (string)de.Value;
            }

            foreach (KeyValuePair <string, string> var in startInfo.EnvironmentVariables)
            {
                env[var.Key] = var.Value;
            }

            // The second parameter of CreateProcess is the command line, and it includes the application being launched
            string cmdLine = "\"" + startInfo.Command + "\" " + startInfo.Arguments;

            process   = dbg.CreateProcess(startInfo.Command, cmdLine, startInfo.WorkingDirectory, env);
            processId = process.Id;

            process.OnCreateProcess       += new CorProcessEventHandler(OnCreateProcess);
            process.OnCreateAppDomain     += new CorAppDomainEventHandler(OnCreateAppDomain);
            process.OnAssemblyLoad        += new CorAssemblyEventHandler(OnAssemblyLoad);
            process.OnAssemblyUnload      += new CorAssemblyEventHandler(OnAssemblyUnload);
            process.OnCreateThread        += new CorThreadEventHandler(OnCreateThread);
            process.OnThreadExit          += new CorThreadEventHandler(OnThreadExit);
            process.OnModuleLoad          += new CorModuleEventHandler(OnModuleLoad);
            process.OnModuleUnload        += new CorModuleEventHandler(OnModuleUnload);
            process.OnProcessExit         += new CorProcessEventHandler(OnProcessExit);
            process.OnUpdateModuleSymbols += new UpdateModuleSymbolsEventHandler(OnUpdateModuleSymbols);
            process.OnDebuggerError       += new DebuggerErrorEventHandler(OnDebuggerError);
            process.OnBreakpoint          += new BreakpointEventHandler(OnBreakpoint);
            process.OnStepComplete        += new StepCompleteEventHandler(OnStepComplete);
            process.OnBreak         += new CorThreadEventHandler(OnBreak);
            process.OnNameChange    += new CorThreadEventHandler(OnNameChange);
            process.OnEvalComplete  += new EvalEventHandler(OnEvalComplete);
            process.OnEvalException += new EvalEventHandler(OnEvalException);

            process.Continue(false);

            OnStarted();
        }
        /// <summary>
        /// Attach to a process with the given Process ID
        /// </summary>
        /// <param name="processId">The Process ID to attach to.</param>
        /// <returns>The resulting MDbgProcess.</returns>
        public MDbgProcess Attach(int processId)
        {
            string deeVersion;

            try
            {
                deeVersion = CorDebugger.GetDebuggerVersionFromPid(processId);
            }
            catch
            {
                // GetDebuggerVersionFromPid isn't implemented on Win9x and so will
                // throw NotImplementedException.  We'll also get an ArgumentException
                // if the specified process doesn't have the CLR loaded yet.
                // Rather than be selective (and potentially brittle), we'll handle all errors.
                // Ideally we'd assert (or log) that we're only getting the errors we expect,
                // but it's complex and ugly to do that in C#.

                // Fall back to guessing the version based on the filename.
                // Environment variables (eg. COMPLUS_Version) may have resulted
                // in a different choice.
                try
                {
                    var cp = new CorPublish.CorPublish();
                    CorPublishProcess cpp           = cp.GetProcess(processId);
                    string            programBinary = cpp.DisplayName;

                    deeVersion = CorDebugger.GetDebuggerVersionFromFile(programBinary);
                }
                catch
                {
                    // This will also fail if the process doesn't have the CLR loaded yet.
                    // It could also fail if the image EXE has been renamed since it started.
                    // For whatever reason, fall back to using the default CLR
                    deeVersion = null;
                }
            }

            MDbgProcess p = m_processMgr.CreateLocalProcess(deeVersion);

            p.Attach(processId);
            return(p);
        }
Esempio n. 3
0
        /// <summary>
        /// Given the full path to a binary, finds the CLR runtime version which
        /// it will bind to.
        /// </summary>
        /// <param name="filePath">The full path to a binary.</param>
        /// <returns>The version string that the binary will bind to; null if unknown.</returns>
        /// <remarks>If ICLRMetaHostPolicy can be asked, it is used. Otherwise
        /// fall back to mscoree!GetRequestedRuntimeVersion.</remarks>
        public static String GetDefaultRuntimeForFile(String filePath)
        {
            String version = null;

            CLRMetaHostPolicy policy;

            try
            {
                policy = new CLRMetaHostPolicy();
            }
            catch (NotImplementedException)
            {
                policy = null;
            }
            catch (System.EntryPointNotFoundException)
            {
                policy = null;
            }

            if (policy != null)
            {
                // v4 codepath
                StringBuilder  ver      = new StringBuilder();
                StringBuilder  imageVer = new StringBuilder();
                CLRRuntimeInfo rti      = null;

                String configPath = null;
                if (System.IO.File.Exists(filePath + ".config"))
                {
                    configPath = filePath + ".config";
                }

                try
                {
                    rti = policy.GetRequestedRuntime(CLRMetaHostPolicy.MetaHostPolicyFlags.metaHostPolicyHighCompat,
                                                     filePath,
                                                     configPath,
                                                     ref ver,
                                                     ref imageVer);
                }
                catch (System.Runtime.InteropServices.COMException)
                {
                    Debug.Assert(rti == null);
                }

                if (rti != null)
                {
                    version = rti.GetVersionString();
                }
                else
                {
                    version = null;
                }
            }
            else
            {
                // v2 codepath
                try
                {
                    version = CorDebugger.GetDebuggerVersionFromFile(filePath);
                }
                catch (System.Runtime.InteropServices.COMException)
                {
                    // we could not retrieve dee version.
                    // Leave version null;
                    Debug.Assert(version == null);
                }
            }

            return(version);
        }
Esempio n. 4
0
        protected override void OnRun(DebuggerStartInfo startInfo)
        {
            // Create the debugger

            string dversion;

            try {
                dversion = CorDebugger.GetDebuggerVersionFromFile(startInfo.Command);
            }
            catch {
                dversion = CorDebugger.GetDefaultDebuggerVersion();
            }
            dbg = new CorDebugger(dversion);

            Dictionary <string, string> env = new Dictionary <string, string> ();

            foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
            {
                env[(string)de.Key] = (string)de.Value;
            }

            foreach (KeyValuePair <string, string> var in startInfo.EnvironmentVariables)
            {
                env[var.Key] = var.Value;
            }

            // The second parameter of CreateProcess is the command line, and it includes the application being launched
            string cmdLine = "\"" + startInfo.Command + "\" " + startInfo.Arguments;

            int flags = 0;

            if (!startInfo.UseExternalConsole)
            {
                flags  = 0x08000000;                /* CREATE_NO_WINDOW*/
                flags |= CorDebugger.CREATE_REDIRECT_STD;
            }

            process   = dbg.CreateProcess(startInfo.Command, cmdLine, startInfo.WorkingDirectory, env, flags);
            processId = process.Id;

            process.OnCreateProcess       += new CorProcessEventHandler(OnCreateProcess);
            process.OnCreateAppDomain     += new CorAppDomainEventHandler(OnCreateAppDomain);
            process.OnAssemblyLoad        += new CorAssemblyEventHandler(OnAssemblyLoad);
            process.OnAssemblyUnload      += new CorAssemblyEventHandler(OnAssemblyUnload);
            process.OnCreateThread        += new CorThreadEventHandler(OnCreateThread);
            process.OnThreadExit          += new CorThreadEventHandler(OnThreadExit);
            process.OnModuleLoad          += new CorModuleEventHandler(OnModuleLoad);
            process.OnModuleUnload        += new CorModuleEventHandler(OnModuleUnload);
            process.OnProcessExit         += new CorProcessEventHandler(OnProcessExit);
            process.OnUpdateModuleSymbols += new UpdateModuleSymbolsEventHandler(OnUpdateModuleSymbols);
            process.OnDebuggerError       += new DebuggerErrorEventHandler(OnDebuggerError);
            process.OnBreakpoint          += new BreakpointEventHandler(OnBreakpoint);
            process.OnStepComplete        += new StepCompleteEventHandler(OnStepComplete);
            process.OnBreak         += new CorThreadEventHandler(OnBreak);
            process.OnNameChange    += new CorThreadEventHandler(OnNameChange);
            process.OnEvalComplete  += new EvalEventHandler(OnEvalComplete);
            process.OnEvalException += new EvalEventHandler(OnEvalException);
            process.OnLogMessage    += new LogMessageEventHandler(OnLogMessage);
            process.OnStdOutput     += new CorTargetOutputEventHandler(OnStdOutput);
            process.OnException2    += new CorException2EventHandler(OnException2);

            process.Continue(false);

            OnStarted();
        }
Esempio n. 5
0
        /// <summary>
        /// Helper function that parses inputs to run and crun commands.
        /// </summary>
        /// <param name="arguments">Argument to the run and crun command</param>
        /// <param name="debugMode">Returns desired debugging mode. Returns internal
        /// default if not specified
        /// </param>
        /// <param name="debuggeeVersion">Returns the debugger interface version.
        ///    Is null if the version cannot be determined.
        /// </param>
        /// <param name="programToRun">Returns path of the program to execute.</param>
        /// <param name="programArguments">Returns arguments to pass to the program being
        /// run, including the binary name as the 0th argument</param>
        public static void PreParseRunArguments(string arguments, out DebugModeFlag debugMode,
                                                out string debuggeeVersion,
                                                out string programToRun,
                                                out string programArguments)
        {
            Debug.Assert(arguments != null);
            if (arguments == null)
            {
                throw new ArgumentException("Parameter cannot be null.", "arguments");
            }

            debugMode = DebugModeFlag.Debug;
            // Is this the mode we want to always start in?

            int start, end;

            start = end = 0;

            // those flags are necessary so that people can run any program under debugger.
            // e.g to run program named '-debug.exe', they can write 'run -debug -debug'
            //
            // One obvious issue here is that if the binary name is same as the flag, then
            // user need to pass the flag to the run command so that the program name is not
            // interpreted as a flag.
            //

            bool debugModeFlagSet = false;
            bool versionFlagSet   = false;

            debuggeeVersion = null;

            while (FindToken(arguments, ref start, ref end))
            {
                Debug.Assert(start <= end);

                switch (arguments.Substring(start, end - start))
                {
                case "-default":
                    if (debugModeFlagSet)
                    {
                        goto default;
                    }
                    debugMode        = DebugModeFlag.Default;
                    debugModeFlagSet = true;
                    break;

                case "-debug":
                case "-d":
                    if (debugModeFlagSet)
                    {
                        goto default;
                    }
                    debugMode        = DebugModeFlag.Debug;
                    debugModeFlagSet = true;
                    break;

                case "-optimize":
                case "-o":
                    if (debugModeFlagSet)
                    {
                        goto default;
                    }
                    debugMode        = DebugModeFlag.Optimized;
                    debugModeFlagSet = true;
                    break;

                case "-enc":
                    if (debugModeFlagSet)
                    {
                        goto default;
                    }
                    debugMode        = DebugModeFlag.Enc;
                    debugModeFlagSet = true;
                    break;

                case "-ver":
                    if (versionFlagSet)
                    {
                        goto default;
                    }

                    if (!FindToken(arguments, ref start, ref end))
                    {
                        throw new MDbgShellException("missing argument to -ver option");
                    }
                    debuggeeVersion = arguments.Substring(start, end - start);
                    versionFlagSet  = true;
                    break;

                default:
                    // this means we have found some different token.
                    // To keep comaptibility with cordbg, we assume that this is a program binary name.

                    // Expand environment variables on the binary name so that we can use env vars in
                    // the program path. Note that environment variables are not expanded in program
                    // arguments so that we can pass in original strings. Programs can expand the environment
                    // themselves if they wish so.
                    string prog = Environment.ExpandEnvironmentVariables(arguments.Substring(start, end - start));

                    // program may be quoted, remove surrounding quotes
                    // Note: ideally we'd have a general escapedPath format and escape/unescape methods to convert
                    // but this is good enough for our purposes here.
                    if (prog.Length >= 2 && prog.StartsWith("\"") && prog.EndsWith("\""))
                    {
                        prog = prog.Substring(1, prog.Length - 2);
                    }

                    // may have omitted .exe extension, add it if necessary
                    const string optExt = ".exe";
                    if (!prog.EndsWith(optExt, StringComparison.OrdinalIgnoreCase))
                    {
                        prog += optExt;
                    }

                    // We're left with the program binary path
                    programToRun = prog;

                    // Use everything unmodified (including the possibly quoted binary path) as the run arguments
                    programArguments = arguments.Substring(start);

                    if (debuggeeVersion == null)
                    {
                        // user didn't specify, we need to guess it.
                        try
                        {
                            debuggeeVersion = CorDebugger.GetDebuggerVersionFromFile(programToRun);
                        }
                        catch (COMException)
                        {
                            // we could not retrieve dee version.
                            debuggeeVersion = null;
                        }
                    }

                    // Rest of line processed, we're done.
                    return;
                }
            }

            // we didn't find any token -- no other binary specified than options
            programToRun     = null;
            programArguments = null;

            return;
        }