2016-04-15 18 views
7

से मेल खाती है, मैं सबूत को जांचना चाहता हूं कि दिए गए असेंबली के पास वैध पीडीबी फ़ाइल है और पीडीबी में संग्रहीत चेकसम स्रोत स्रोतों से मेल खाते हैं।जांचें कि पीडीबी फ़ाइल स्रोत

बिल्ड सर्वर कॉन्फ़िगरेशन को तोड़ने पर बिल्डिंग द्विआधारी को रोकने के लिए हमारे सीआई सर्वर पर यूनिट परीक्षण के रूप में जाना जाता था (उदाहरण के लिए कोड बनाने के लिए अलग गिट शाखा का उपयोग किया गया था)।

यदि संभव हो, तो इसे इनपुट पैरामीटर के रूप में MethodInfo स्वीकार करना चाहिए। मैं डबल-चेक करना चाहता हूं और सत्यापित करता हूं कि किसी विधि के लिए स्रोत लाइन अनुमानित हैं।

पहला भाग, विशिष्ट विधि के लिए स्रोत पढ़ने बहुत आसान है। यहां a sample है।

कठिन हिस्सा पीडीबी में सभी दस्तावेजों के चेकसम की जांच कर रहा है। मानक System.Diagnostics.SymbolStore.SymDocument.GetCheckSum()NotImplementedException फेंकता है इसलिए मुझे निश्चित रूप से कुछ और उपयोग करने की आवश्यकता है।

कोई सुझाव?

यूपीडी। स्पष्ट करने के लिए कोशिश कर रहा है :)

  1. मैं यह जांच करना कि स्रोत फ़ाइलें 'चेकसम PDB फ़ाइल में संग्रहीत चेकसम का मिलान कर रहे हैं में दिलचस्पी रखता हूँ, पहले भाग (कि pdb जाँच द्विआधारी से मेल खाता है) पहले से ही किया जाता है।

  2. मैं इस कार्य के लिए कुछ एपीआई ढूंढ रहा हूं क्योंकि मैं कंसोल आउटपुट को पार्स नहीं करना चाहता हूं। साथ ही, मैं अपने सीआई सर्वर पर कोई भी अतिरिक्त एसडीके इंस्टॉल नहीं करना चाहूंगा क्योंकि सबूत के लिए अतिरिक्त समय लगेगा कुछ भी टूटा नहीं गया था।

+1

माइक्रोसॉफ्ट के पास सीसीआई खुली सोर्स है जिसमें ओपन सोर्स प्रतीक पार्सर है, और आपको इसका उपयोग प्रतीक फ़ाइलों के आंतरिक जांचने के लिए करना चाहिए। –

+0

ठीक है, क्या वह अप्रचलित नहीं है? माइक्रोसॉफ्ट भी हैं। डायससिमर (वास्तव में, दो संस्करण हैं, मूल और पोर्टेबल) और सिस्टम। रिफ्लेक्शन।मेटाडाटा पैकेज और मोनो सेसिल भी है। कौन सा चयन करना है? * भ्रमित * – Sinix

+0

मोनो। सेसिल का पीडीबी कोड सीधे माइक्रोसॉफ्ट सीसीआई से आता है। अन्य जिन्हें मैंने जांच नहीं की लेकिन आपको पता होना चाहिए कि पीडीबी प्रारूप लंबे समय से बदल दिया गया है और आपको कुछ नवीनतम बिट्स की आवश्यकता नहीं है। –

उत्तर

5

यदि आपको ऐसा करने के लिए प्रोग्रामेटिक तरीका चाहिए, तो आप Microsoft.DiaSymReaderPackage (संस्करण 1.0.7.0) का उपयोग कर सकते हैं, और आपको कुछ अन्य अप्रबंधित इंटरफेस भी घोषित करने की आवश्यकता है। चेकम को दो एल्गोरिदम में से एक का उपयोग करके फ़ाइलों बाइट से आसानी से गणना की जाती है: SHA1 या MD5।

class Program 
    { 
     static void Main(string[] args) 
     { 
      ValidateChecksums(Path.GetFullPath("ConsoleApplication1.exe")); 
     } 

     // this needs a reference to Microsoft.DiaSymReader 
     // or redefine its interfaces manually from here https://github.com/dotnet/roslyn/tree/master/src/Dependencies/Microsoft.DiaSymReader 
     public static void ValidateChecksums(string filePath) 
     { 
      if (filePath == null) 
       throw new ArgumentNullException(nameof(filePath)); 

      var dispenser = (IMetaDataDispenser)new CorMetaDataDispenser(); 
      var import = dispenser.OpenScope(filePath, 0, typeof(IMetaDataImport).GUID); 

      var binder = (ISymUnmanagedBinder)new CorSymBinder_SxS(); 
      ISymUnmanagedReader reader; 
      binder.GetReaderForFile(import, filePath, null, out reader); 

      int count; 
      reader.GetDocuments(0, out count, null); 
      if (count > 0) 
      { 
       var docs = new ISymUnmanagedDocument[count]; 
       reader.GetDocuments(count, out count, docs); 
       foreach (var d in docs) 
       { 
        var doc = new SymDocument(d); 
        Console.WriteLine(doc.Url); 

        if (doc.Checksum.SequenceEqual(doc.ComputeChecksum())) 
        { 
         Console.WriteLine(" checksum is valid."); 
        } 
        else 
        { 
         Console.WriteLine(" checksum is not valid."); 
        } 
       } 
      } 
     } 
    } 

और एक नमूना सहायक वर्ग, देशी इंटरफेस और coclasses:

यहां नमूने सांत्वना अनुप्रयोग है कि अपने स्वयं के स्रोत के बारे में जानकारी प्रदर्शित करता है।

public class SymDocument 
    { 
     // guids are from corsym.h 
     public static readonly Guid CorSym_SourceHash_MD5 = new Guid(0x406ea660, 0x64cf, 0x4c82, 0xb6, 0xf0, 0x42, 0xd4, 0x81, 0x72, 0xa7, 0x99); 
     public static readonly Guid CorSym_SourceHash_SHA1 = new Guid(0xff1816ec, 0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60); 

     public SymDocument(ISymUnmanagedDocument doc) 
     { 
      if (doc == null) 
       throw new ArgumentNullException(nameof(doc)); 

      int len; 
      doc.GetUrl(0, out len, null); 
      if (len > 0) 
      { 
       var urlChars = new char[len]; 
       doc.GetUrl(len, out len, urlChars); 
       Url = new string(urlChars, 0, len - 1); 
      } 

      doc.GetChecksum(0, out len, null); 
      if (len > 0) 
      { 
       Checksum = new byte[len]; 
       doc.GetChecksum(len, out len, Checksum); 
      } 

      Guid id = Guid.Empty; 
      doc.GetChecksumAlgorithmId(ref id); 
      ChecksumAlgorithmId = id; 
     } 

     public string Url { get; private set; } 
     public byte[] Checksum { get; private set; } 
     public Guid ChecksumAlgorithmId { get; private set; } 

     public byte[] ComputeChecksum() 
     { 
      HashAlgorithm algo; 
      if (ChecksumAlgorithmId == CorSym_SourceHash_MD5) 
      { 
       algo = MD5.Create(); 
      } 
      else if (ChecksumAlgorithmId == CorSym_SourceHash_SHA1) 
      { 
       algo = SHA1.Create(); 
      } 
      else 
       throw new NotSupportedException(); 

      try 
      { 
       return algo.ComputeHash(File.ReadAllBytes(Url)); 
      } 
      finally 
      { 
       algo.Dispose(); 
      } 
     } 
    } 

    [ComImport, Guid("0A29FF9E-7F9C-4437-8B11-F424491E3931")] 
    internal class CorSymBinder_SxS // from corsym.h 
    { 
    } 

    [ComImport, Guid("E5CB7A31-7512-11d2-89CE-0080C792E5D8")] 
    internal class CorMetaDataDispenser // from cor.h 
    { 
    } 

    [Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    internal interface IMetaDataImport // from cor.h 
    { 
     // we don't need to use what's inside 
    } 

    [Guid("809c652e-7396-11d2-9771-00a0c9b4d50c"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    internal interface IMetaDataDispenser // from cor.h 
    { 
     void _VtblGap0_1(); // skip 1 method 
     IMetaDataImport OpenScope([MarshalAs(UnmanagedType.LPWStr)] string szScope, int dwOpenFlags, [MarshalAs(UnmanagedType.LPStruct)] Guid riid); 
    } 
2

आप उम्र और GUID PDB से Microsoft CCI या Mono.Cecil का उपयोग कर पढ़ा है, और एक पीई फ़ाइल में RSDS resource से ही जानकारी पढ़ सकते हैं।

यदि उम्र और GUID मैच, मान लें कि पीडीबी और पीई फ़ाइल वास्तव में मेल खाती है।

मैच को symchk उपकरण के साथ सत्यापित किया जा सकता है।

3

यदि ग्रिड मैच है, तो आपको यह सुनिश्चित करना चाहिए कि स्रोत मेल खाता है। मैं आयु और ग्रिड की तुलना करने के लिए chkmatch कमांड लाइन टूल का उपयोग करता हूं। (देखें: http://www.debuginfo.com/tools/chkmatch.html)

संबंधित मुद्दे