private void AddMetaDataMessagesToContainer(CIContainer aContainer) { // All meta-data errors, warnings & messages are added as // children of the container. CACmdLineFSEntityList <CACmdLineFSEntity> metaDataFiles = iInputs.MetaDataFiles; foreach (CACmdLineFSEntity file in metaDataFiles) { file.CopyMessagesToContainer(aContainer); } }
private void TryToPrimeSources() { Trace("[CA Cmd] TryToPrimeSources() - START"); CrashItemEngine.ClearAll(); // Prime engine with source files CACmdLineFSEntityList <CACmdLineFileSource> sourceFileNames = iInputs.SourceFiles; int progress = -1; int count = sourceFileNames.Count; // Emit progress banner if (iReportProgress) { Print("Locating crash files..."); } for (int i = 0; i < count; i++) { CACmdLineFileSource file = sourceFileNames[i]; // try { // We prime each file individually. If an exception is thrown then we // record an appropriate error in the associated file object. Trace("[CA Cmd] TryToPrimeSources() - priming: " + file); bool primeSuccess = CrashItemEngine.Prime(file); // Report progress as we work through the sources if (iReportProgress) { float newProgress = (((float)i + 1) / (float)count) * 100.0f; if ((int)newProgress != progress || i == count - 1) { progress = (int)newProgress; Print(string.Format("{0:d3}%", progress)); } } Trace("[CA Cmd] TryToPrimeSources() - primed result: " + primeSuccess); } catch (Exception sourcePrimerException) { file.AddError("Error Identifying Source Type", "There was an error when attempting to identify the source file type. The file could not be processed."); file.AddDiagnostic("Crash Primer Exception Message", sourcePrimerException.Message); file.AddDiagnostic("Crash Primer Exception Stack", sourcePrimerException.StackTrace); } } AssociateInputFilesWithCrashItemSources(); Trace("[CA Cmd] TryToPrimeSources() - END"); }
private void AssociateInputFilesWithCrashItemSources() { CACmdLineFSEntityList <CACmdLineFileSource> sourceFileNames = iInputs.SourceFiles; // Emit progress banner if (iReportProgress) { Print("Categorizing files..."); } // Check each source in the engine and try to map it back onto an input source // file name. The goal is to identify input files which have no corresponding crash engine // source. These files are unsupported. CIEngineSourceCollection sources = iCrashItemEngine.Sources; int count = sources.Count; int progress = -1; for (int i = 0; i < count; i++) { CIEngineSource source = sources[i]; string sourceFileName = source.FileName; // Try to match an input file with a given source object CACmdLineFileSource inputFile = sourceFileNames[sourceFileName]; if (inputFile != null) { inputFile.Source = source; } // Report progress as we work through the sources if (iReportProgress) { float newProgress = (((float)i + 1) / (float)count) * 100.0f; if ((int)newProgress != progress || i == count - 1) { progress = (int)newProgress; Print(string.Format("{0:d3}%", progress)); } } } }
public bool ParseCommandLine() { bool retval = true; string commandLine = System.Environment.CommandLine; string ppattern = @"\s*(-.\s*[^-]*)"; MatchCollection matches = Regex.Matches(commandLine, ppattern, RegexOptions.None); if (matches.Count < 1) { PrintCommandHelp(); System.Console.WriteLine("Error: No valid parameters given"); throw new CACmdLineException("Error: No valid parameters given", CACmdLineException.KErrCommandLineError); } foreach (Match parameter in matches) { Regex pparser = new Regex(@"(?<id>-.)\s*(?<content>.*)"); Match m = pparser.Match(parameter.ToString()); if (m.Success) { GroupCollection groups = m.Groups; string paramId = m.Result("${id}").Trim(); string paramContent = m.Result("${content}").Trim(); if (paramId == "-a") { ArchivePath = paramContent; } if (paramId == "-s") { SkippedPath = paramContent; ErrorPath = paramContent + @"\errors"; } if (paramId == "-f") { DecodeWithoutSymbols = true; } if (paramId == "-t") { NotMovingFiles = true; } if (paramId == "-x") { UseXmlSink = true; } if (paramId == "-c") { CITargetPath = paramContent; System.Console.WriteLine("CITargetPath -c is " + CITargetPath); } // Plain text output if (paramId == "-p") { UseXmlSink = true; // XML sink is used for plain text output iSinkParams.PlainTextOutput = true; } // Crash files if (paramId == "-b") { CommandLineUsage = true; FileInfo fi = new FileInfo(paramContent); CACmdLineFSEntityList <CACmdLineFileSource> fileList = new CACmdLineFSEntityList <CACmdLineFileSource>(); if (fi.Exists) { fileList.Add(fi); } else { System.Console.WriteLine("Error: Crash file " + fi.FullName + " does not exist"); retval = false; } iSources = fileList; } // Symbol/map/dictionary files if (paramId == "-m") { string[] symbolFileTable = paramContent.Split(','); CACmdLineFSEntityList <CACmdLineFSEntity> fileList = new CACmdLineFSEntityList <CACmdLineFSEntity>(); foreach (string fileName in symbolFileTable) { FileInfo fi = new FileInfo(fileName); if (fi.Exists) { SymbolsGiven = true; fileList.Add(fi); } } iMetaData = fileList; if (fileList.Count == 0) { System.Console.WriteLine("Error: Invalid symbol/map/dictionary files: " + paramContent); retval = false; } } } else { System.Console.WriteLine("Error: No parameters found"); retval = false; } } //Parameter scanning finished - validate content if (CommandLineUsage) { if (iMetaData.Count == 0 && DecodeWithoutSymbols == false) { System.Console.WriteLine("Error: No symbol files given. Give symbol files with parameter -m"); retval = false; } if (!UseXmlSink) { // Plain text output as default in command line usage. UseXmlSink = true; iSinkParams.PlainTextOutput = true; } // When used in command line mode set current directory as default archive, // error and skipped path (just some valid dir as it is not really used). if (ArchivePath == String.Empty || SkippedPath == String.Empty) { if (ArchivePath != String.Empty || SkippedPath != String.Empty) { System.Console.WriteLine("Please give either both the archive path and the skipped path, or neither of them."); System.Console.WriteLine("Not moving any files."); } NotMovingFiles = true; ArchivePath = Directory.GetCurrentDirectory(); SkippedPath = ArchivePath; ErrorPath = SkippedPath + @"\errors"; } } if (ArchivePath == string.Empty) { System.Console.WriteLine("Error: No archive path given"); retval = false; } else if (!Directory.Exists(ArchivePath)) { System.Console.WriteLine("Error: Archive path " + ArchivePath + " cannot be found"); retval = false; } if (SkippedPath == string.Empty) { System.Console.WriteLine("Error: No skipped file path given"); retval = false; } else if (!Directory.Exists(SkippedPath)) { System.Console.WriteLine("Error: Skipped path " + SkippedPath + " cannot be found"); retval = false; } else //skipped path exists, create error path if not there { if (!Directory.Exists(ErrorPath) && !NotMovingFiles) { Directory.CreateDirectory(ErrorPath); } } if (CITargetPath != string.Empty) { CITargetPath = Path.GetFullPath(CITargetPath); System.Console.WriteLine("CITargetPath used! Resulting files will be created to " + CITargetPath); if (!Directory.Exists(CITargetPath)) { Directory.CreateDirectory(CITargetPath); } iSinkParams.OutputDirectory = new DirectoryInfo(CITargetPath); } //make sure paths are absolute iArchivePath = Path.GetFullPath(iArchivePath); iSkippedPath = Path.GetFullPath(iSkippedPath); iErrorPath = Path.GetFullPath(iErrorPath); //add weekly division DateTime today = DateTime.Now; CultureInfo culInfo = CultureInfo.CurrentCulture; int weekNum = culInfo.Calendar.GetWeekOfYear(today, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); int year = culInfo.Calendar.GetYear(today); iArchivePath = iArchivePath + @"\" + year + "_" + weekNum.ToString().PadLeft(2, '0'); iSkippedPath = iSkippedPath + @"\" + year + "_" + weekNum.ToString().PadLeft(2, '0'); iErrorPath = iErrorPath + @"\" + year + "_" + weekNum.ToString().PadLeft(2, '0'); if (NotMovingFiles) { System.Console.WriteLine("Not moving any files!"); } else if (retval) //Archive & skipped directories exsits, clean up paths and add week numbers { if (!Directory.Exists(iArchivePath)) { Directory.CreateDirectory(iArchivePath); } if (!Directory.Exists(iSkippedPath)) { Directory.CreateDirectory(iSkippedPath); } if (!Directory.Exists(iErrorPath)) { Directory.CreateDirectory(iErrorPath); } } else { PrintCommandHelp(); } if (!NotMovingFiles) { System.Console.WriteLine("Using archive path " + ArchivePath + ", skipped path " + SkippedPath + " and error path " + ErrorPath); } return(retval); }
private void TryToCreateOutput() { CACmdLineFSEntityList <CACmdLineFileSource> inputFiles = iInputs.SourceFiles; // CISink sink = FindSink(iInputs.UseXmlSink); if (sink == null) { throw new CACmdLineException("CI Output Plugin Not Available", CACmdLineException.KErrSinkNotAvailable); } CACmdLineFSEntityList <CACmdLineFileSource> sourceFileNames = iInputs.SourceFiles; int progress = -1; int count = sourceFileNames.Count; // Emit progress banner if (iReportProgress) { Print("Creating CI content..."); } for (int i = 0; i < count; i++) { CACmdLineFileSource file = sourceFileNames[i]; System.Console.WriteLine("Starting to process file " + file.Name); // If the file has a corresponding source then we know that crash item recognised it. // Otherwise, we skip it. if (file.Source != null) { // We copy and remove all the file-level messages. These will be added to the container // (where appropriate) or then to an output entry otherwise. CACmdLineMessage[] fileMessages = file.ToArray(); file.Clear(); // At this point, the input file is guaranteed to have an associated container. In // the current mobile crash file format, there will be a 1:1 mapping, i.e. each file // will contain a single crash report ("container") and therefore if symbols were // found for just a single container (within the file) then it's good enough to treat // the file as archivable. foreach (CIContainer container in file.Containers) { // Firstly, add any meta-data errors/messages/warnings to this container // as crash item message entries AddMetaDataMessagesToContainer(container); SetArchiveFileName(file.Name, container, sink); foreach (CIMessage message in container.Messages) { if (message.Type == CrashItemLib.Crash.Messages.CIMessage.TType.ETypeError) { container.Status = CIContainer.TStatus.EStatusErrorContainer; } } // Now we can try to serialize the container to CI. This method will // not throw an exception. // // If the operation succeeds, then the input file will have an associated // container object (and associated xml output file name) and we need not // do anymore. // // If it fails, then the input file will not be assigned the container // object and therefore, later on, we'll invoke the CI Sink directly to // create a stub 'FAILED' CI output file. // // NB: If Symbols were not available for the specified container, then // we don't create a CI file but instead callback to a helper that // will move the file to another temporary location for later repeat // processing bool hasSymbols = ContainsSymbols(container); if (container.Status == CIContainer.TStatus.EStatusErrorContainer) //normally don't output containers with errors { file.State = CACmdLineFileSource.TState.EStateUninitialized; if (iInputs.DecodeWithoutSymbols) //with force mode, output no matter what { TryToCreateOutput(sink, container, file, fileMessages); } } else if (hasSymbols || IsSymbollessMobileCrash(container)) { file.State = CACmdLineFileSource.TState.EStateProcessedAndReadyToBeArchived; TryToCreateOutput(sink, container, file, fileMessages); } else if (IsSymbollessMobileCrash(container)) //Crash api and registration files do not need symbols { file.State = CACmdLineFileSource.TState.EStateProcessedAndReadyToBeArchived; TryToCreateOutput(sink, container, file, fileMessages); } else { file.State = CACmdLineFileSource.TState.EStateSkippedDueToMissingSymbols; if (iInputs.DecodeWithoutSymbols) //with force mode, output no matter what { //remove this to prevent .corrupt_ci creation! TryToCreateOutput(sink, container, file, fileMessages); } } } } else { file.State = CACmdLineFileSource.TState.EStateSkippedDueToNotBeingRecognized; } // Move file to final location MoveProcessedFile(file); // Report progress as we work through the sources if (iReportProgress) { float newProgress = (((float)i + 1) / (float)count) * 100.0f; if ((int)newProgress != progress || i == count - 1) { progress = (int)newProgress; Print(string.Format("{0:d3}%", progress)); } } } }
private void TryToPrimeDbgEngine() { DbgEngine debugEngine = iDebugEngine; // Exception primerException = null; CACmdLineFSEntityList <CACmdLineFSEntity> metaDataFiles = iInputs.MetaDataFiles; // try { debugEngine.Clear(); foreach (CACmdLineFileSource file in iInputs.SourceFiles) { // Tell all used RomIds to debugEngine. if (file.RomId != null) { debugEngine.AddActiveRomId(file.RomId.Value); } // Tell all RomIds which needs symbols to debugEngine so that // we load only symbols for those. if (file.ContentType == TMobileCrashContentType.EContentTypePanic || file.ContentType == TMobileCrashContentType.EContentTypeException) { debugEngine.AddSymbolRomId(file.RomId.Value); } } foreach (CACmdLineFSEntity entry in metaDataFiles) { Trace("[CA Cmd] Seeding debug meta engine with entry: " + entry.Name); DbgEntity entity = debugEngine.Add(entry.Name); if (entity != null) { Trace("[CA Cmd] Entry type detected as: [" + entity.CategoryName + "]"); entity.Tag = entry; } else { Trace("[CA Cmd] Entry not handled: " + entry.Name); entry.AddError("Meta-Data File Not Supported", "The file \'" + entry.Name + "\' is of unknown origin."); } } // Listen to prime events try { Trace("[CA Cmd] Starting prime operation... "); debugEngine.EntityPrimingStarted += new DbgEngine.EventHandler(DbgEngine_EntityPrimingStarted); debugEngine.EntityPrimingProgress += new DbgEngine.EventHandler(DbgEngine_EntityPrimingProgress); debugEngine.EntityPrimingComplete += new DbgEngine.EventHandler(DbgEngine_EntityPrimingComplete); debugEngine.Prime(TSynchronicity.ESynchronous); Trace("[CA Cmd] Debug meta data priming completed successfully."); } finally { debugEngine.EntityPrimingStarted -= new DbgEngine.EventHandler(DbgEngine_EntityPrimingStarted); debugEngine.EntityPrimingProgress -= new DbgEngine.EventHandler(DbgEngine_EntityPrimingProgress); debugEngine.EntityPrimingComplete -= new DbgEngine.EventHandler(DbgEngine_EntityPrimingComplete); } } catch (Exception exception) { Trace("[CA Cmd] Debug meta data priming exception: " + exception.Message + ", " + exception.StackTrace); primerException = exception; } // Go through each debug entity and check it for errors. Add diagnostics // and error messages where appropriate. foreach (DbgEntity entity in debugEngine) { string name = entity.FullName; // CACmdLineFSEntity file = metaDataFiles[name]; file.Clear(); // if (entity.PrimerResult.PrimedOkay) { if (!entity.Exists) { file.AddError("Meta-Data File Missing", string.Format("The file \'{0}\' could not be found.", file.Name)); } else if (entity.IsUnsupported) { file.AddError("Meta-Data File Not Supported", string.Format("The file \'{0}\' is of unknown origin.", file.Name)); } } else { // Add error file.AddError("Meta-Data Read Error", entity.PrimerResult.PrimeErrorMessage); // And diagnostic information Exception exception = entity.PrimerResult.PrimeException != null ? entity.PrimerResult.PrimeException : primerException; if (exception != null) { file.AddDiagnostic("Meta-Data Exception Message", entity.PrimerResult.PrimeException.Message); file.AddDiagnostic("Meta-Data Exception Stack", entity.PrimerResult.PrimeException.StackTrace); } else { file.AddDiagnostic("Meta-Data Unknown Failure", "No exception occurred at the primer or entity level?"); } } } }