Beispiel #1
0
        public async Task PushAllResultsAsync(bool clean)
        {
            if (elasticClient == null)
            {
                throw new InvalidOperationException("ElasticSearch has not been initialized! Please verify that the settings specify a correct elastic search host.");
            }

            await BlockIfBundleRepoNotReady("ElasticSearchService.PushAllResultsAsync");

            if (clean)
            {
                DeleteIndex();
                CreateIndex();

                // since we are clean, we can do everything in one bulk
                var dumps = dumpRepo.GetAll().OrderByDescending(x => x.Created);
                foreach (var dumpsBatch in dumps.Batch(100))
                {
                    var tasks   = dumpsBatch.Select(x => Task.Run(async() => new { res = await dumpRepo.GetResult(x.Id), bundleInfo = bundleRepo.Get(x.BundleId), dumpInfo = x }));
                    var results = (await Task.WhenAll(tasks)).Where(x => x.res != null);

                    Console.WriteLine($"pushing {results.Count()} results into elasticsearch");
                    var sdResults = results.Select(x => ElasticSDResult.FromResultOrDefault(x.res, x.bundleInfo, x.dumpInfo, pathHelper)).Where(x => x != null);
                    await PushBulk(sdResults);
                }
                return;
            }

            IEnumerable <string> documentIds = GetAllDocumentIds();

            int nErrorsLogged = 0;
            var bundles       = bundleRepo.GetAll();

            if (bundles == null)
            {
                throw new InvalidOperationException("Bundle repository must be populated before pushing data into ES.");
            }

            // In order to check if a dump has already been added, we go through them all and add one at the time
            // There is potential to optimize this and still do a bulk add.
            foreach (BundleMetainfo bundle in bundles)
            {
                var dumps = dumpRepo.Get(bundle.BundleId);
                if (dumps == null)
                {
                    continue;
                }
                foreach (DumpMetainfo dump in dumps)
                {
                    if (documentIds.Contains(bundle.BundleId + "/" + dump.DumpId))
                    {
                        continue;
                    }
                    SDResult result = await dumpRepo.GetResult(dump.Id);

                    if (result != null)
                    {
                        bool success = await PushResultAsync(result, bundle, dump);

                        if (!success && nErrorsLogged < 20)
                        {
                            Console.WriteLine($"Failed to create document for {dump.BundleId}/{dump.DumpId}");
                            nErrorsLogged++;
                        }
                    }
                }
            }
        }
 public DebugSymbolAnalysis(IFilesystem filesystem, IProcessHandler processHandler, SDResult result)
 {
     this.filesystem     = filesystem ?? throw new ArgumentNullException("Filesystem must not be null!");
     this.processHandler = processHandler ?? throw new ArgumentNullException("ProcessHandler must not be null!");
     this.analysisResult = result ?? throw new ArgumentNullException("SD Result must not be null!");
 }
Beispiel #3
0
        private static void RunAnalysis(Options options)
        {
            if (Environment.Is64BitProcess)
            {
                Environment.SetEnvironmentVariable("_NT_DEBUGGER_EXTENSION_PATH", @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP;C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext;C:\Program Files (x86)\Windows Kits\10\Debuggers\x64;");
            }
            else
            {
                Environment.SetEnvironmentVariable("_NT_DEBUGGER_EXTENSION_PATH", @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\WINXP;C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\winext;C:\Program Files (x86)\Windows Kits\10\Debuggers\x86;");
            }
            using (var context = new DumpContext()) {
                Console.WriteLine("SuperDump - Windows dump analysis tool");
                Console.WriteLine("--------------------------");
                //check if symbol path is set
                if (string.IsNullOrEmpty(SYMBOL_PATH))
                {
                    Console.WriteLine("WARNING: Environment variable _NT_SYMBOL_PATH is not set!");
                }

                DUMP_LOC   = options.DumpFile;
                OUTPUT_LOC = options.OutputFile;

                string absoluteDumpFile = Path.GetFullPath(DUMP_LOC);
                Console.WriteLine(absoluteDumpFile);

                var logfile = new FileInfo(Path.Combine(Path.GetDirectoryName(OUTPUT_LOC), "superdump.log"));
                context.Printer = new FilePrinter(logfile.FullName);

                if (File.Exists(absoluteDumpFile))
                {
                    LoadDump(context, absoluteDumpFile);

                    // do this as early as possible, as some WinDbg commands help us get the right DAC files
                    RunSafe(context, nameof(WinDbgAnalyzer), () => {
                        var windbgAnalyzer = new WinDbgAnalyzer(context, Path.Combine(context.DumpDirectory, "windbg.log"));
                        windbgAnalyzer.Analyze();
                    });

                    // start analysis
                    var analysisResult = new SDResult();
                    analysisResult.IsManagedProcess = context.Target.ClrVersions.Count > 0;

                    if (analysisResult.IsManagedProcess)
                    {
                        SetupCLRRuntime(context);
                    }

                    RunSafe(context, nameof(ExceptionAnalyzer), () => {
                        var sysInfo = new SystemAnalyzer(context);
                        analysisResult.SystemContext = sysInfo.systemInfo;

                        //get non loaded symbols
                        List <string> notLoadedSymbols = new List <string>();
                        foreach (var item in sysInfo.systemInfo.Modules)
                        {
                            if (item.PdbInfo == null || string.IsNullOrEmpty(item.PdbInfo.FileName) || string.IsNullOrEmpty(item.PdbInfo.Guid))
                            {
                                notLoadedSymbols.Add(item.FileName);
                            }
                            analysisResult.NotLoadedSymbols = notLoadedSymbols;
                        }

                        // print to log
                        sysInfo.PrintArchitecture();
                        sysInfo.PrintCLRVersions();
                        sysInfo.PrintAppDomains();
                        sysInfo.PrintModuleList();
                    });

                    RunSafe(context, nameof(ExceptionAnalyzer), () => {
                        var exceptionAnalyzer = new ExceptionAnalyzer(context, analysisResult);
                    });

                    RunSafe(context, nameof(ThreadAnalyzer), () => {
                        context.WriteInfo("--- Thread analysis ---");
                        ThreadAnalyzer threadAnalyzer      = new ThreadAnalyzer(context);
                        analysisResult.ExceptionRecord     = threadAnalyzer.exceptions;
                        analysisResult.ThreadInformation   = threadAnalyzer.threads;
                        analysisResult.DeadlockInformation = threadAnalyzer.deadlocks;
                        analysisResult.LastExecutedThread  = threadAnalyzer.GetLastExecutedThreadOSId();
                        context.WriteInfo("Last executed thread (engine id): " + threadAnalyzer.GetLastExecutedThreadEngineId().ToString());

                        threadAnalyzer.PrintManagedExceptions();
                        threadAnalyzer.PrintCompleteStackTrace();
                    });

                    RunSafe(context, nameof(MemoryAnalyzer), () => {
                        var memoryAnalyzer = new MemoryAnalyzer(context);
                        analysisResult.MemoryInformation = memoryAnalyzer.memDict;
                        analysisResult.BlockingObjects   = memoryAnalyzer.blockingObjects;

                        memoryAnalyzer.PrintExceptionsObjects();
                    });

                    // this analyzer runs after all others to put tags onto taggableitems
                    RunSafe(context, nameof(TagAnalyzer), () => {
                        var tagAnalyzer = new TagAnalyzer(analysisResult);
                        tagAnalyzer.Analyze();
                    });

                    // write to json
                    analysisResult.WriteResultToJSONFile(OUTPUT_LOC);

                    context.WriteInfo("--- End of output ---");
                    Console.WriteLine("done.");
                }
                else
                {
                    throw new FileNotFoundException("File can not be found!");
                }
            }
        }
        public GdbSharedLibAnalyzer(IFilesystem filesystem, IProcessHandler processHandler, IFileInfo coredump, SDResult result)
        {
            this.filesystem     = filesystem ?? throw new ArgumentNullException("FilesystemHelper must not be null!");
            this.processHandler = processHandler ?? throw new ArgumentNullException("ProcessHandler must not be null!");
            this.coredump       = coredump ?? throw new ArgumentNullException("Coredump must not be null!");

            this.systemContext         = (SDCDSystemContext)result.SystemContext;
            this.systemContext.Modules = new List <SDModule>();
        }
Beispiel #5
0
        public async Task <IActionResult> Report(string bundleId, string dumpId)
        {
            ViewData["Message"] = "Get Report";
            var id = DumpIdentifier.Create(bundleId, dumpId);

            var bundleInfo = superDumpRepo.GetBundle(bundleId);

            if (bundleInfo == null)
            {
                logger.LogNotFound("Report: Bundle not found", HttpContext, "BundleId", bundleId);
                return(View(null));
            }

            var dumpInfo = superDumpRepo.GetDump(id);

            if (dumpInfo == null)
            {
                logger.LogNotFound("Report: Dump not found", HttpContext, "Id", id.ToString());
                return(View(null));
            }

            logger.LogDumpAccess("Report", HttpContext, bundleInfo, dumpId);

            string   sdReadError = string.Empty;
            SDResult res         = null;

            try {
                res = await superDumpRepo.GetResultAndThrow(id);
            } catch (Exception e) {
                sdReadError = e.ToString();
            }

            // don't add relationships when the repo is not ready yet. it might take some time with large amounts.
            IEnumerable <KeyValuePair <DumpMetainfo, double> > similarDumps =
                !relationshipRepo.IsPopulated ? Enumerable.Empty <KeyValuePair <DumpMetainfo, double> >() :
                (await relationshipRepo.GetRelationShips(DumpIdentifier.Create(bundleId, dumpId)))
                .Select(x => new KeyValuePair <DumpMetainfo, double>(dumpRepo.Get(x.Key), x.Value)).Where(dump => dump.Key != null);

            return(base.View(new ReportViewModel(id)
            {
                BundleFileName = bundleInfo.BundleFileName,
                DumpFileName = dumpInfo.DumpFileName,
                Result = res,
                CustomProperties = Utility.Sanitize(bundleInfo.CustomProperties),
                TimeStamp = dumpInfo.Created,
                Files = dumpRepo.GetFileNames(id),
                AnalysisError = dumpInfo.ErrorMessage,
                ThreadTags = res != null ? res.GetThreadTags() : new HashSet <SDTag>(),
                PointerSize = res == null ? 8 : (res.SystemContext?.ProcessArchitecture == "X86" ? 8 : 12),
                CustomTextResult = await ReadCustomTextResult(dumpInfo),
                SDResultReadError = sdReadError,
                DumpType = dumpInfo.DumpType,
                RepositoryUrl = settings.RepositoryUrl,
                InteractiveGdbHost = settings.InteractiveGdbHost,
                SimilarityDetectionEnabled = settings.SimilarityDetectionEnabled,
                Similarities = similarDumps,
                IsDumpAvailable = dumpRepo.IsPrimaryDumpAvailable(id),
                MainBundleJiraIssues = !settings.UseJiraIntegration || !jiraIssueRepository.IsPopulated ? Enumerable.Empty <JiraIssueModel>() : await jiraIssueRepository.GetAllIssuesByBundleIdWithoutWait(bundleId),
                SimilarDumpIssues = !settings.UseJiraIntegration || !jiraIssueRepository.IsPopulated ? new Dictionary <string, IEnumerable <JiraIssueModel> >() : await jiraIssueRepository.GetAllIssuesByBundleIdsWithoutWait(similarDumps.Select(dump => dump.Key.BundleId)),
                UseJiraIntegration = settings.UseJiraIntegration,
                DumpStatus = dumpInfo.Status,
                IsRelationshipsPopulated = relationshipRepo.IsPopulated || !settings.SimilarityDetectionEnabled,
                IsJiraIssuesPopulated = jiraIssueRepository.IsPopulated || !settings.UseJiraIntegration
            }));
        }
 public virtual void AnalyzeResult(SDResult result)
 {
 }
 public SourceFileProvider(SDResult result, IFilesystem filesystem, IHttpRequestHandler requestHandler)
 {
     this.result         = result;
     this.filesystem     = filesystem ?? throw new NullReferenceException("Filesystem must not be null!");
     this.requestHandler = requestHandler ?? throw new NullReferenceException("Request Handler must not be null!");
 }
Beispiel #8
0
 public UnwindAnalyzer(IFileInfo coredump, SDResult result)
 {
     this.analysisResult = result ?? throw new ArgumentNullException("SD Result must not be null!");
     this.coredump       = coredump ?? throw new ArgumentNullException("Coredump Path must not be null!");
 }
Beispiel #9
0
 private bool PreSelectOnResults(SDResult resultA, SDResult resultB)
 {
     return(true);            // no ideas on how to pre-select here yet.
 }
 private static void AddTagToFrameAndThread(SDResult result, SDTag tag)
 {
     result.ThreadInformation[1].Tags.Add(tag);
     result.ThreadInformation[1].StackTrace[0].Tags.Add(tag);
 }