コード例 #1
0
        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);
                }
            }
        }
コード例 #2
0
        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");
        }
コード例 #3
0
        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));
                    }
                }
            }
        }
コード例 #4
0
        /*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;
            }
        }
コード例 #5
0
        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);
                }
            }
        }
コード例 #6
0
        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));
                    }
                }
            }
        }