Ejemplo n.º 1
0
        public void WritePdb(SymbolData symData)
        {
            m_docWriters = new Dictionary<int, ISymbolDocumentWriter>();

            ImageDebugDirectory debugDirectory;
            byte[] debugInfo = null;
            // Rather than use the emitter here, we are just careful enough to emit pdb metadata that
            // matches what is already in the assembly image.
            object emitter = null;

            // We must be careful to close the writer before updating the debug headers.  The writer has an
            // open file handle on the assembly we want to update.
            m_writer = SymbolAccess.GetWriterForFile(m_symFormat, m_outputAssembly, ref emitter);

            // We don't actually need the emitter in managed code at all, so release the CLR reference on it
            Marshal.FinalReleaseComObject(emitter);

            try
            {
                WriteEntryPoint(symData.entryPointToken);
                WriteFiles(symData.sourceFiles);
                WriteMethods(symData.methods);
                debugInfo = m_writer.GetDebugInfo(out debugDirectory);
            }
            finally
            {
                m_writer.Close();
                ((IDisposable)m_writer).Dispose();
                m_writer = null;
                m_docWriters.Clear();
            }

            UpdatePEDebugHeaders(debugInfo);
        }
Ejemplo n.º 2
0
        public void WritePdb(SymbolData symData)
        {
            m_docWriters = new Dictionary <int, ISymbolDocumentWriter>();

            ImageDebugDirectory debugDirectory;

            byte[] debugInfo = null;
            // Rather than use the emitter here, we are just careful enough to emit pdb metadata that
            // matches what is already in the assembly image.
            object emitter = null;

            // We must be careful to close the writer before updating the debug headers.  The writer has an
            // open file handle on the assembly we want to update.
            m_writer = SymbolAccess.GetWriterForFile(m_symFormat, m_outputAssembly, ref emitter);

            // We don't actually need the emitter in managed code at all, so release the CLR reference on it
            Marshal.FinalReleaseComObject(emitter);

            try
            {
                WriteEntryPoint(symData.entryPointToken);
                WriteFiles(symData.sourceFiles);
                WriteMethods(symData.methods);
                debugInfo = m_writer.GetDebugInfo(out debugDirectory);
            }
            finally
            {
                m_writer.Close();
                ((IDisposable)m_writer).Dispose();
                m_writer = null;
                m_docWriters.Clear();
            }

            UpdatePEDebugHeaders(debugInfo);
        }
Ejemplo n.º 3
0
        /*
         * This function (UpdatePEDebugHeaders) represents a bit of a hack.
         *
         * When a debugger attempts to find debug information (pdb)
         * for an image file (dll or exe), it uses a data-blob in the
         * image file to decide if the debug info "matches" this version.
         *
         * Modifying the pdb without updating the image file would cause
         * a debugger to not load this new pdb due to mismatched information.
         *
         * In most situations when somebody emits debug info, they are also
         * emitting metadata and an assembly, so they can just include the
         * results of ISymUnmanagedWriter.GetDebugInfo in that new image file.
         *
         * The intent of this sample is to demonstrate managed symbol reading
         * and writing without too much extra stuff.  For this reason, I didn't
         * include a full implementation of PEFile manipulation because it's
         * not really the point of this sample.  The code that does the PE File
         * manipulation was thrown together to get a specific job done and not
         * to be a good demonstration of how a compiler should deal with this.
         * Managed data structures to mirror the native format would be a better
         * approach if you needed more functionality out of the PEFile class.
         */

        private void UpdatePEDebugHeaders()
        {
            if (File.Exists(m_outputAssembly))
            {
                ImageDebugDirectory DebugDirectory;
                byte[] DebugInfo = m_writer.GetDebugInfo(out DebugDirectory);
                var    file      = new PEFile(m_outputAssembly);
                file.UpdateHeader(DebugInfo);
            }
            else
            {
                Console.WriteLine("Warning: Assembly couldn't be found to update.");
                Console.WriteLine("New pdb won't \"match\" any assembly and will thus not be useful to a debugger.");
            }
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Gets the <see cref="IMAGE_DEBUG_DIRECTORY"/> and debug data that should be written to
 /// the PE file.
 /// </summary>
 /// <param name="idd">Updated with new values</param>
 /// <returns>Debug data</returns>
 public byte[] GetDebugInfo(out IMAGE_DEBUG_DIRECTORY idd)
 {
     return(writer.GetDebugInfo(out idd));
 }