コード例 #1
0
        static void Main(string[] args)
        {
            var interpreter = new ExceptionReportInterpreter();

            ProcessCommandArgs(interpreter, args);

            if (ConsoleEx.IsInputRedirected)
            {
                interpreter.Translate(Console.In, Console.Out);
            }
            else
            {
                foreach (var symPath in interpreter.SymbolPaths)
                {
                    Console.WriteLine("Symbols: {0}", symPath);
                }

                Console.WriteLine("Paste a stack trace to analyze (ESC to exit) ...");
                while (true)
                {
                    var reader = new ConsoleTextReader();
                    interpreter.Translate(reader, Console.Out);

                    if (reader.IsEscapeDetected)
                    {
                        break;
                    }
                }
            }
        }
コード例 #2
0
        static void ProcessCommandArgs(ExceptionReportInterpreter interpreter, string[] args)
        {
            for (var i = 0; i < args.Length; ++i)
            {
                switch (args[i].ToLowerInvariant())
                {
                case "-vs":
                    var vsVersion = Environment.GetEnvironmentVariable("VisualStudioVersion");
                    if (!string.IsNullOrEmpty(vsVersion))
                    {
                        var vsDebuggerKey = string.Format(@"HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\{0}\Debugger", vsVersion);
                        var vsSymbolPaths = Registry.GetValue(vsDebuggerKey, "SymbolPath", null) as string;
                        if (!string.IsNullOrEmpty(vsSymbolPaths))
                        {
                            interpreter.SymbolPaths.AddRange(vsSymbolPaths.Split(';'));
                        }
                    }
                    break;

                case "-s":
                    if (++i >= args.Length)
                    {
                        goto default;
                    }
                    interpreter.SymbolPaths.AddRange(args[i].Split(';'));
                    break;

                default:
                    Console.Error.WriteLine("Usage: {0} [-vs] [-s \"symbol path1;symbol path2\"]", "ProductionStackTrace.Analyze.Console");
                    Environment.Exit(-1);
                    break;
                }
            }
        }
コード例 #3
0
        private void InternalTestException(IsolatedMode mode, string methodSig, string expectedException, LineNumberInfo[] expectedInfos)
        {
            // Parse the methodSig

            var assemblyName     = "ProductionStackTrace.Test.Library";
            var defaultNamespace = assemblyName;

            var m = _regexMethodSig.Match(methodSig);

            if (m == Match.Empty)
            {
                throw new ArgumentException("Invalid methodSig: " + methodSig);
            }
            var className    = m.Groups["Class"].ToString().TrimEnd('.');
            var methodName   = m.Groups["Method"].ToString();
            var methodParams = m.Groups["Params"].ToString();

            // Execute in isolated environment with or without access to
            // PDB symbols information (meaning native stack trace either has
            // or doesn't have line number info)
            //
            // Customization in the .csproj file for this Test project in the
            // "AfterBuild" target will setup two subfolders - lib and libpdb.
            // 'lib' will contain just the DLL, and 'libpdb' will have DLL + PDB.
            //
            // Also original PDB location will be deleted, so that PDB can only
            // be found if it's on the Symbols Paths or in the folder as DLL.

            var env = new IsolatedEnvironment();

            env.LibPaths.Add(mode == IsolatedMode.NoSymbols ? "lib" : "libpdb");

            var r = env.Run(string.Format("{1}.{2}, {0}", assemblyName, defaultNamespace, className), methodName);

            Assert.IsNotNull(r.Exception);
            Assert.IsNotNullOrEmpty(r.ExceptionStackTrace);
            Assert.IsNotNullOrEmpty(r.ExceptionReport);
            StringAssert.StartsWith(expectedException + "\r\n", r.ExceptionStackTrace);
            StringAssert.StartsWith(expectedException + "\r\n", r.ExceptionReport);
            StringAssert.Contains("   at " + defaultNamespace + "." + methodSig, r.ExceptionStackTrace);
            Assert.AreNotEqual(r.ExceptionStackTrace, r.ExceptionReport);

            if (mode == IsolatedMode.NoSymbols)
            {
                StringAssert.DoesNotContain(":line ", r.ExceptionStackTrace);
            }
            else
            {
                StringAssert.Contains(":line ", r.ExceptionStackTrace);
            }

            var    interpret = new ExceptionReportInterpreter();
            var    sb        = new StringBuilder();
            string parsedReport;

            if (mode != IsolatedMode.NoSymbols)
            {
                interpret.SymbolPaths.Add("libpdb");
            }

            // Run interpreter with no access to symbols
            // It should produce the same stack trace as the internal exception

            interpret.Translate(new StringReader(r.ExceptionReport), new StringWriter(sb));
            parsedReport = sb.ToString();

            // Parsed report should be exactly the same as we would obtain
            // from the original stack trace.
            //
            // - If the original stack trace was run without symbols, then
            //   interpreter didn't have access to symbols either, and so
            //   the output should match

            Assert.AreEqual(r.ExceptionStackTrace, parsedReport.TrimEnd());

            if (mode == IsolatedMode.NoSymbols)
            {
                // If we ran original report with no access to symbols, then
                // run it again - now with PDB symbols. The stack trace should now
                // include line number info

                sb.Clear();
                interpret.SymbolPaths.Add("libpdb");
                interpret.Translate(new StringReader(r.ExceptionReport), new StringWriter(sb));
                parsedReport = sb.ToString();

                StringAssert.DoesNotStartWith(parsedReport, r.ExceptionReport);   // check it is different
                Assert.AreNotEqual(r.ExceptionStackTrace, parsedReport);          // check it is not same as default stack trace
            }

            // Check that the expected line number info is present

            foreach (var info in expectedInfos)
            {
                StringAssert.Contains("\\" + info.File + ":line " + info.LineNo, parsedReport);    // check it has the line info
            }
        }