private void MoveFile(CACmdLineFileSource aFile, string aTargetPath) { string newName = aTargetPath; //Name availability has already been checked before starting decoding for archive location //If file is going to skipped, its name may need changing if (File.Exists(newName)) { int counter = 1; string original_name = newName; while (File.Exists(newName)) { string basepath = Path.GetDirectoryName(original_name); string basename = Path.GetFileNameWithoutExtension(original_name); string extension = Path.GetExtension(original_name); newName = Path.Combine(basepath, basename + "_" + counter.ToString() + extension); counter++; } } // Move the file. if (!iInputs.NotMovingFiles) { System.Console.WriteLine("Moving file " + aFile.Name + " to " + newName); File.Move(aFile.Name, newName); if (!File.Exists(newName)) { System.Console.WriteLine("Error: unable to move file " + aFile.Name + " to " + newName); } } }
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)); } } } }
/*private bool ContainsSymbols( CIContainer aContainer ) * { * // Symbols can be registered as the global level, or then per-process. * bool ret = ( aContainer.SymbolDictionary.Count > 0 ); * if ( ret == false ) * { * // Check at process level * CISummarisableEntityList summaries = aContainer.Summaries; * foreach ( CISummarisableEntity entity in summaries.ChildrenByType<CISummarisableEntity>() ) * { * CIProcess process = entity.Process; * if ( process != null ) * { * ret = ( process.SymbolDictionary.Count > 0 ); * if ( ret == true ) * { * break; * } * } * } * } * // * return ret; * }*/ private void MoveProcessedFile(CACmdLineFileSource aFile) { string skippedTarget = Path.Combine(iInputs.SkippedPath, Path.GetFileName(iBinFileArchivePathName)); string errorTarget = Path.Combine(iInputs.ErrorPath, Path.GetFileName(iBinFileArchivePathName)); switch (aFile.State) { case CACmdLineFileSource.TState.EStateProcessedAndReadyToBeArchived: MoveFile(aFile, iBinFileArchivePathName); break; case CACmdLineFileSource.TState.EStateSkippedDueToMissingSymbols: MoveFile(aFile, skippedTarget); break; case CACmdLineFileSource.TState.EStateSkippedDueToNotBeingRecognized: MoveFile(aFile, errorTarget); break; default: MoveFile(aFile, errorTarget); break; } }
private void TryToCreateOutput(CISink aXmlSink, CIContainer aContainer, CACmdLineFileSource aFile, CACmdLineMessage[] aMessagesToAdd) { Trace("[CA Cmd] TryToCreateOutput() - START - container source: {0}", aContainer.Source.MasterFileName); // By the time we are outputting a container, there should no longer be any messages // associated with the file. System.Diagnostics.Debug.Assert(aFile.Count == 0); // Check whether the file contained any errors or // messages of it own. if (aMessagesToAdd.Length > 0) { // Copy warnings, messages and errors into crash item container. // Diagnostic messages are not copied. CACmdLineFSEntity.CopyMessagesToContainer(aMessagesToAdd, aContainer); } // This is where we will record the output attempt CACmdLineFileSource.OutputEntry outputEntry = null; // try { // Finish preparing the sink parameters CISinkSerializationParameters sinkParams = iInputs.SinkParameters; sinkParams.Container = aContainer; // Perform serialization Trace("[CA Cmd] TryToCreateOutput() - serializing..."); object output = aXmlSink.Serialize(sinkParams); Trace("[CA Cmd] TryToCreateOutput() - serialization returned: " + output); if (aFile != null) { // Create new output string outputFileName = output is string?(string)output : string.Empty; // Save output file name outputEntry = aFile.AddOutput(aContainer, outputFileName, TOutputStatus.ESuccess); } // Merge in any diagnostic messages that were left into the output entry. // This ensure we output diagnostics in the final manifest data. outputEntry.AddRange(aMessagesToAdd, CACmdLineMessage.TType.ETypeDiagnostic); } catch (Exception outputException) { Trace("[CA Cmd] TryToCreateOutput() - outputException.Message: " + outputException.Message); Trace("[CA Cmd] TryToCreateOutput() - outputException.StackTrace: " + outputException.StackTrace); if (aFile != null) { // Something went wrong with CI serialisation for the specified container. outputEntry = aFile.AddOutput(aContainer, string.Empty, TOutputStatus.EFailed); // outputEntry.AddError("Could not Create CI", "CI output could not be created"); outputEntry.AddDiagnostic("CI Sink Exception Message", outputException.Message); outputEntry.AddDiagnostic("CI Sink Exception Stack", outputException.StackTrace); // Since we didn't manage to sink the container to CI successfully, we must // make sure we don't lose any associated messages from the original file. // Merge these into the output entry also. outputEntry.AddRange(aMessagesToAdd); } } }
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)); } } } }