/// <summary> /// Write out the scopes and the locals to the PDB file. /// </summary> /// <param name="symWriter">The symbol writer for this file.</param> /// <param name="scope">The scope to write out.</param> private static void WriteScopeAndLocals(QSy.SymbolWriter symWriter, Scope scope) { // Open the scope symWriter.OpenScope(scope.OffsetStart); // Add each local variable foreach (LocalBinding lb in scope.Locals) { symWriter.DefineLocalVariable2( lb.Name, 0, #if SIMPLEWRITER lb.Token.GetToken(), #else lb.Token, #endif 1, lb.Index, 0, 0, lb.OffsetStart, lb.OffsetEnd ); } // Add each constants /* For now don't add constants. Doesn't work. AKB 09-01-2007 * foreach (ConstantBinding cb in scope.Constants) { * symWriter.DefineConstant( * cb.Name, * cb.Value, * cb.GetSig() * ); * } */ // Add any child scopes foreach (Scope childScope in scope.ChildScopes) { WriteScopeAndLocals(symWriter, childScope); } // Close the scope symWriter.CloseScope(scope.OffsetEnd); }
/// <summary> /// Write the PDB file to disk. /// </summary> public void WritePDBFile() { /* * Write default template PDB file first * * NOTE: This is a dodgy hack so please feel free to change! AKB 06-01-2007 * * For some reason if there isn't a PDB file to start with the * debugger used to step through the resulting PDB file will * jump all over the place. Resulting in incorrect step-throughs. * I have not been able to work out why yet but I think it has * something to do with the call to GetWriterForFile(). * Also, it doesn't happen on all PDB files. * It is interesting to note that if it is writting a debug file * to go with a PE file compiled by csc (MS Compiler) it works fine. */ // Get the blank PDB file from the resource assembly System.Reflection.Assembly currentAssembly = System.Reflection.Assembly.GetExecutingAssembly(); Stream blankPDB = currentAssembly.GetManifestResourceStream("QUT.PERWAPI.Blank.pdb"); // Write the blank PDB file to the disk using (FileStream fs = new FileStream(PDBFilename, FileMode.OpenOrCreate, FileAccess.Write)) { BinaryWriter bw = new BinaryWriter(fs); // Loop through the PDB file and write it to the disk byte[] buffer = new byte[32768]; while (true) { int read = blankPDB.Read(buffer, 0, buffer.Length); if (read <= 0) break; bw.Write(buffer, 0, read); } // Close all of the streams we have opened bw.Close(); fs.Close(); } // Create the new Symbol Writer QSy.SymbolWriter symWriter = new QSy.SymbolWriter(PEFilename, PDBFilename); // Add each of the source documents foreach (Document doc in _docWriters) { #if SIMPLEWRITER doc._docWriter = symWriter.DefineDocument( doc._file, doc._docLanguage, doc._langVendor, doc._docType ); // Set the entry point if it exists if (entryPoint.GetToken() != 0) symWriter.SetUserEntryPoint(entryPoint.GetToken()); #else doc.docWriter = symWriter.DefineDocument( doc._file, ref doc._docLanguage, ref doc._langVendor, ref doc._docType ); // Set the entry point if it exists if (entryPoint.GetToken() != 0) symWriter.SetUserEntryPoint(entryPoint); #endif // SIMPLEWRITER } // Loop through and add each method foreach (Method meth in methods) { #if SIMPLEWRITER symWriter.OpenMethod(meth.Token.GetToken()); #else symWriter.OpenMethod(meth.Token); #endif // Write the scope and the locals if (meth.Scope != null) WriteScopeAndLocals(symWriter, meth.Scope); // Add each of the sequence points foreach (Document sourceDoc in meth.SequencePointList.Keys) { SequencePointList spList = (SequencePointList)meth.SequencePointList[sourceDoc]; #if SIMPLEWRITER symWriter.DefineSequencePoints(sourceDoc._docWriter, (uint[])spList.offsets.ToArray(), (uint[])spList.lines.ToArray(), (uint[])spList.cols.ToArray(), (uint[])spList.endLines.ToArray(), (uint[])spList.endCols.ToArray()); #else symWriter.DefineSequencePoints(sourceDoc.docWriter, spList.offsets.ToArray(), spList.lines.ToArray(), spList.cols.ToArray(), spList.endLines.ToArray(), spList.endCols.ToArray()); #endif // SIMPLEWRITER } symWriter.CloseMethod(); } // Get the debug info debugInfo = symWriter.GetDebugInfo(); // Close the PDB file symWriter.Close(); }
/// <summary> /// Write the PDB file to disk. /// </summary> public void WritePDBFile() { /* * Write default template PDB file first * * NOTE: This is a dodgy hack so please feel free to change! AKB 06-01-2007 * * For some reason if there isn't a PDB file to start with the * debugger used to step through the resulting PDB file will * jump all over the place. Resulting in incorrect step-throughs. * I have not been able to work out why yet but I think it has * something to do with the call to GetWriterForFile(). * Also, it doesn't happen on all PDB files. * It is interesting to note that if it is writting a debug file * to go with a PE file compiled by csc (MS Compiler) it works fine. */ // Get the blank PDB file from the resource assembly System.Reflection.Assembly currentAssembly = System.Reflection.Assembly.GetExecutingAssembly(); Stream blankPDB = currentAssembly.GetManifestResourceStream("QUT.PERWAPI.Blank.pdb"); // Write the blank PDB file to the disk using (FileStream fs = new FileStream(PDBFilename, FileMode.OpenOrCreate, FileAccess.Write)) { BinaryWriter bw = new BinaryWriter(fs); // Loop through the PDB file and write it to the disk byte[] buffer = new byte[32768]; while (true) { int read = blankPDB.Read(buffer, 0, buffer.Length); if (read <= 0) { break; } bw.Write(buffer, 0, read); } // Close all of the streams we have opened bw.Close(); fs.Close(); } // Create the new Symbol Writer QSy.SymbolWriter symWriter = new QSy.SymbolWriter(PEFilename, PDBFilename); // Add each of the source documents foreach (Document doc in _docWriters) { #if SIMPLEWRITER doc._docWriter = symWriter.DefineDocument( doc._file, doc._docLanguage, doc._langVendor, doc._docType ); // Set the entry point if it exists if (entryPoint.GetToken() != 0) { symWriter.SetUserEntryPoint(entryPoint.GetToken()); } #else doc.docWriter = symWriter.DefineDocument( doc._file, ref doc._docLanguage, ref doc._langVendor, ref doc._docType ); // Set the entry point if it exists if (entryPoint.GetToken() != 0) { symWriter.SetUserEntryPoint(entryPoint); } #endif // SIMPLEWRITER } // Loop through and add each method foreach (Method meth in methods) { #if SIMPLEWRITER symWriter.OpenMethod(meth.Token.GetToken()); #else symWriter.OpenMethod(meth.Token); #endif // Write the scope and the locals if (meth.Scope != null) { WriteScopeAndLocals(symWriter, meth.Scope); } // Add each of the sequence points foreach (Document sourceDoc in meth.SequencePointList.Keys) { SequencePointList spList = (SequencePointList)meth.SequencePointList[sourceDoc]; #if SIMPLEWRITER symWriter.DefineSequencePoints(sourceDoc._docWriter, (uint[])spList.offsets.ToArray(), (uint[])spList.lines.ToArray(), (uint[])spList.cols.ToArray(), (uint[])spList.endLines.ToArray(), (uint[])spList.endCols.ToArray()); #else symWriter.DefineSequencePoints(sourceDoc.docWriter, spList.offsets.ToArray(), spList.lines.ToArray(), spList.cols.ToArray(), spList.endLines.ToArray(), spList.endCols.ToArray()); #endif // SIMPLEWRITER } symWriter.CloseMethod(); } // Get the debug info debugInfo = symWriter.GetDebugInfo(); // Close the PDB file symWriter.Close(); }