Esempio n. 1
0
 public ScriptResultsManager(IErrorIndex errorIndex, ScriptManager scriptManager, IDebugger debugger, StackHashDebuggerSettings debuggerSettings)
 {
     m_ErrorIndex       = errorIndex;
     m_ScriptManager    = scriptManager;
     m_Debugger         = debugger;
     m_DebuggerSettings = debuggerSettings;
 }
Esempio n. 2
0
        /// <summary>
        /// Determines if the 32 bit or 64 bit debugger settings should be used.
        /// The 32 bit settings are used unless...
        ///
        /// 1) We are running on a 64 bit machine AND
        /// 2) 64 bit debugger specified and exists AND
        /// 3) (Dump is 64 bit) OR (Dump is 32 bit but no 32 bit debugger specified or exists)
        /// </summary>
        /// <param name="dumpIs32Bit">Flavour of the dump file.</param>
        /// <param name="debuggerSettings">Current debugger settings.</param>
        /// <returns>true - use 32 bit debugger settings, false - use 64 bit debugger settings.</returns>
        public bool Use32BitDebugger(bool dumpIs32Bit, StackHashDebuggerSettings debuggerSettings)
        {
            if (debuggerSettings == null)
            {
                throw new ArgumentNullException("debuggerSettings");
            }

            bool hostIs32Bit = !SystemInformation.Is64BitSystem();

            // Only have the option of using the 64 bit debugger on a host that is 64 bit.
            if (!hostIs32Bit)
            {
                if ((debuggerSettings.DebuggerPathAndFileName == null) ||           // No 32 bit debugger specified.
                    (!File.Exists(debuggerSettings.DebuggerPathAndFileName)) ||     // 32 bit debugger specified but path invalid.
                    !dumpIs32Bit)                                                   // The dump is 64 bit.
                {
                    // Still only use the 64 bit debugger if it exists.
                    if ((debuggerSettings.DebuggerPathAndFileName64Bit != null) &&
                        (File.Exists(debuggerSettings.DebuggerPathAndFileName64Bit)))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Esempio n. 3
0
        public void MyTestInitialize()
        {
            m_TempPath = Path.GetTempPath() + "StackHashAutoScriptTests\\";

            TidyTest();

            if (!Directory.Exists(m_TempPath))
            {
                Directory.CreateDirectory(m_TempPath);
            }

            m_DebuggerSettings = new StackHashDebuggerSettings();

            m_DebuggerSettings.DebuggerPathAndFileName      = StackHashDebuggerSettings.Default32BitDebuggerPathAndFileName;
            m_DebuggerSettings.DebuggerPathAndFileName64Bit = StackHashDebuggerSettings.Default64BitDebuggerPathAndFileName;
            m_DebuggerSettings.SymbolPath      = StackHashSearchPath.DefaultSymbolPath;
            m_DebuggerSettings.SymbolPath64Bit = StackHashSearchPath.DefaultSymbolPath;
            m_DebuggerSettings.BinaryPath      = StackHashSearchPath.DefaultSymbolPath;
            m_DebuggerSettings.BinaryPath64Bit = StackHashSearchPath.DefaultSymbolPath;
        }
Esempio n. 4
0
        public void RunSimpleScript()
        {
            // Create a test script.
            String testScriptName = "ScriptName";
            String testCommand    = @"r";
            String testComment    = @"Just a demo";

            StackHashScript script = new StackHashScript();

            script.Add(new StackHashScriptLine(testCommand, testComment));
            StackHashScriptSettings scriptSettings = new StackHashScriptSettings(testScriptName, script);

            String scriptFileName  = m_TempPath + @"\GeneratedScript.wds";
            String resultsFileName = m_TempPath + @"\Results.log";
            String symPath         = null;
            String exePath         = null;
            String srcPath         = null;

            scriptSettings.GenerateScriptFile(scriptFileName, resultsFileName, ref symPath, ref exePath, ref srcPath);

            Assert.AreEqual(null, symPath);
            Assert.AreEqual(null, exePath);
            Assert.AreEqual(null, srcPath);

            // Run the script with the debugger.
            Windbg debugger     = new Windbg();
            String dumpFileName = TestSettings.TestDataFolder + @"Dumps\Cucku.exe.mdmp";

            StackHashDebuggerSettings debuggerSettings = new StackHashDebuggerSettings();

            debuggerSettings.DebuggerPathAndFileName = StackHashDebuggerSettings.Default32BitDebuggerPathAndFileName;
            debuggerSettings.SymbolPath = StackHashSearchPath.DefaultSymbolPath;
            debugger.RunScript(debuggerSettings, true, scriptFileName, dumpFileName, resultsFileName, symPath, exePath, srcPath);

            Assert.AreEqual(true, File.Exists(resultsFileName));
            String[] allResults = File.ReadAllLines(resultsFileName, Encoding.Unicode);

            Assert.AreEqual(true, allResults.Length > 0);
        }
Esempio n. 5
0
        public void simpleScriptNCommands(int numCommands, bool addComment)
        {
            // Create a test script.
            String testScriptName = "ScriptName";
            String testCommand    = @"r";

            String testComment = null;

            if (addComment)
            {
                testComment = @"Just a demo";
            }

            StackHashScript script = new StackHashScript();

            for (int i = 0; i < numCommands; i++)
            {
                script.Add(new StackHashScriptLine(testCommand, testComment + i.ToString()));
            }
            StackHashScriptSettings scriptSettings = new StackHashScriptSettings(testScriptName, script);

            String scriptFileName  = m_TempPath + @"\GeneratedScript.wds";
            String resultsFileName = m_TempPath + @"\Results.log";

            String symPath = null;
            String exePath = null;
            String srcPath = null;

            scriptSettings.GenerateScriptFile(scriptFileName, resultsFileName, ref symPath, ref exePath, ref srcPath);

            Assert.AreEqual(null, symPath);
            Assert.AreEqual(null, exePath);
            Assert.AreEqual(null, srcPath);

            // Run the script with the debugger.
            Windbg debugger = new Windbg();

            String dumpFileName = TestSettings.TestDataFolder + @"Dumps\Cucku.exe.mdmp";

            DateTime startTime = DateTime.Now.ToUniversalTime();

            StackHashDebuggerSettings debuggerSettings = new StackHashDebuggerSettings();

            debuggerSettings.DebuggerPathAndFileName = StackHashDebuggerSettings.Default32BitDebuggerPathAndFileName;
            debuggerSettings.SymbolPath = StackHashSearchPath.DefaultSymbolPath;
            debuggerSettings.BinaryPath = StackHashSearchPath.DefaultBinaryPath;
            debugger.RunScript(debuggerSettings, true, scriptFileName, dumpFileName, resultsFileName, symPath, exePath, srcPath);

            DateTime endTime = DateTime.Now.ToUniversalTime();

            Assert.AreEqual(true, File.Exists(resultsFileName));

            // Now load in the test results.
            StackHashScriptResult result = new StackHashScriptResult(resultsFileName);


            Assert.AreEqual(scriptSettings.Name, result.Name);
            Assert.AreEqual(scriptSettings.LastModifiedDate.Date, result.LastModifiedDate.Date);
            Assert.AreEqual(scriptSettings.LastModifiedDate.Hour, result.LastModifiedDate.Hour);
            Assert.AreEqual(scriptSettings.LastModifiedDate.Minute, result.LastModifiedDate.Minute);
            Assert.AreEqual(scriptSettings.LastModifiedDate.Second, result.LastModifiedDate.Second);


            // Recorded time is only accurate to the second.
            long ticksInASecond = 10000000;

            startTime = new DateTime((startTime.Ticks / ticksInASecond) * ticksInASecond, DateTimeKind.Utc);
            endTime   = new DateTime((endTime.Ticks / ticksInASecond) * ticksInASecond, DateTimeKind.Utc);

            bool isGreaterEqual  = result.RunDate >= startTime;
            bool isLessThanEqual = result.RunDate <= endTime;

            long ticks1 = result.RunDate.Ticks;
            long ticks2 = startTime.Ticks;
            long ticks3 = endTime.Ticks;

            Assert.AreEqual(true, (result.RunDate >= startTime) && (result.RunDate <= endTime));

            Assert.AreEqual(numCommands, scriptSettings.Script.Count);

            for (int i = 0; i < numCommands; i++)
            {
                Assert.AreEqual(scriptSettings.Script[i].Command, result.ScriptResults[i].ScriptLine.Command);
                Assert.AreEqual(scriptSettings.Script[i].Comment, result.ScriptResults[i].ScriptLine.Comment);

                Assert.AreEqual(5, result.ScriptResults[i].ScriptLineOutput.Count);
                Assert.AreEqual(true, result.ScriptResults[i].ScriptLineOutput[0].StartsWith("eax="));
                Assert.AreEqual(true, result.ScriptResults[i].ScriptLineOutput[1].StartsWith("eip="));
                Assert.AreEqual(true, result.ScriptResults[i].ScriptLineOutput[2].StartsWith("cs="));
            }
        }
Esempio n. 6
0
        public bool RunScript(StackHashDebuggerSettings debuggerSettings,
                              bool dumpIs32Bit,
                              String scriptFileName,
                              String dumpPathAndFileName,
                              String outputPath,
                              String overrideSymbolPath,
                              String overrideExePath,
                              String overrideSourcePath)
        {
            if (debuggerSettings == null)
            {
                throw new ArgumentNullException("debuggerSettings");
            }
            if (scriptFileName == null)
            {
                throw new ArgumentNullException("scriptFileName");
            }

            // Default to using the 32 bit debugger unless the dump and host are 64 bit.
            String debuggerPath = String.Empty;
            String symbolPath   = String.Empty;
            String binaryPath   = String.Empty;
            String sourcePath   = String.Empty;

            // Only have the option of using the 64 bit debugger on a host that is 64 bit.
            if (Use32BitDebugger(dumpIs32Bit, debuggerSettings))
            {
                debuggerPath = debuggerSettings.DebuggerPathAndFileName;

                if (debuggerSettings.SymbolPath != null)
                {
                    symbolPath = debuggerSettings.SymbolPath.FullPath;
                }

                if (debuggerSettings.BinaryPath != null)
                {
                    binaryPath = debuggerSettings.BinaryPath.FullPath;
                }
            }
            else
            {
                debuggerPath = debuggerSettings.DebuggerPathAndFileName64Bit;

                if (debuggerSettings.SymbolPath64Bit != null)
                {
                    symbolPath = debuggerSettings.SymbolPath64Bit.FullPath;
                }

                if (debuggerSettings.BinaryPath64Bit != null)
                {
                    binaryPath = debuggerSettings.BinaryPath64Bit.FullPath;
                }
            }

            if (String.IsNullOrEmpty(debuggerPath))
            {
                throw new ArgumentException("debugger path cannot be null", "debuggerSettings");
            }

            if (overrideSymbolPath != null)
            {
                symbolPath = overrideSymbolPath;
            }

            if (overrideExePath != null)
            {
                binaryPath = overrideExePath;
            }

            if (overrideSourcePath != null)
            {
                sourcePath = overrideSourcePath;
            }

            if (symbolPath == null)
            {
                throw new ArgumentException("symbol path cannot be null", "debuggerSettings");
            }


            // Clear any previous abort request.
            AbortRequested = false;
            m_LastStderr   = new StringBuilder();
            m_LastExitCode = 0;

            //String commandLine = String.Format(CultureInfo.InvariantCulture,
            //    "-y \"{0}\" -i \"{1}\" -z \"{2}\" -c \"$$><{3};q\"",
            //    symbolPath, binaryPath, dumpPathAndFileName, scriptFileName);


            // The $$>< is required because we need to put ;q (quit) after the script is run.
            // and the filename may have spaces.
            // The >< is required so people can use debugger control commands.
            String commandLine = String.Format(CultureInfo.InvariantCulture,
                                               "-y \"{0}\" -i \"{1}\" -z \"{2}\" -srcpath \"{3}\" -c \"$$><{4};q\"",
                                               symbolPath, binaryPath, dumpPathAndFileName, sourcePath, scriptFileName);


            //           commandLine = "-y-z-df--djihj$$";

            String debuggerName = Path.GetFileName(debuggerPath);

            if (String.Compare(debuggerName, "windbg.exe", StringComparison.OrdinalIgnoreCase) == 0)
            {
                // WinDbg - command line options.
                // -Q   - Suppresses the "Save Workspace?" dialog box. Workspaces are not automatically saved. See Using Workspaces for details.
                // -QS  - Suppresses the "Reload Source?" dialog box. Source files are not automatically reloaded.
                // -QSY - Suppresses the "Reload Source?" dialog box and automatically reloads source files.
                // -QY  - Suppresses the "Save Workspace?" dialog box and automatically saves workspaces. See Using Workspaces for details.
                commandLine += " -Q -QS -QY -QSY";
            }

            Process debuggerProcess = null;

            try
            {
                debuggerProcess = new Process();
                debuggerProcess.StartInfo.FileName               = debuggerPath;
                debuggerProcess.StartInfo.Arguments              = commandLine;
                debuggerProcess.StartInfo.UseShellExecute        = false;
                debuggerProcess.StartInfo.RedirectStandardError  = true;
                debuggerProcess.StartInfo.RedirectStandardOutput = true;
                debuggerProcess.StartInfo.CreateNoWindow         = true;

                // StdError doesn't appear to be used - so in the case of a command line error - need the stdout too.
                debuggerProcess.ErrorDataReceived  += new System.Diagnostics.DataReceivedEventHandler(this.ErrorReceived);
                debuggerProcess.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(this.ErrorReceived);

                try
                {
                    Environment.SetEnvironmentVariable("DBGHELP", "1");
                    Environment.SetEnvironmentVariable("WININET", "1");
                    debuggerProcess.Start();
                }
                catch (System.ComponentModel.Win32Exception ex)
                {
                    throw new StackHashException("Failed to run debugger: " + commandLine, ex, StackHashServiceErrorCode.FailedToRunDebugger);
                }

                // Start the event handler - which will read data written to stderr into m_LastStderr.
                debuggerProcess.BeginErrorReadLine();
                debuggerProcess.BeginOutputReadLine();

                while (!AbortRequested)
                {
                    debuggerProcess.WaitForExit(2000);
                    if (debuggerProcess.HasExited)
                    {
                        break;
                    }
                }

                if (AbortRequested)
                {
                    // Abort the process.
                    if (!debuggerProcess.HasExited)
                    {
                        try
                        {
                            debuggerProcess.Kill();
                            debuggerProcess.WaitForExit();
                        }
                        catch (System.ComponentModel.Win32Exception) { }
                        catch (System.InvalidOperationException) { }
                        catch (System.SystemException) { }
                    }
                }
                m_LastExitCode = debuggerProcess.ExitCode;

                // Give the stderror text callback a chance to be called one more time or we
                // might miss the final error.
                Thread.Sleep(200);
            }
            finally
            {
                // Dispose any resources used by the process creation.
                if (debuggerProcess != null)
                {
                    try
                    {
                        debuggerProcess.ErrorDataReceived -= new System.Diagnostics.DataReceivedEventHandler(this.ErrorReceived);
                    }
                    finally
                    {
                        debuggerProcess.Dispose();
                    }
                }
            }

            return(!AbortRequested);
        }