2009-02-17 7 views
25

मुझे लॉक समस्या को ट्रैक करने में कठिनाई हो रही है, इसलिए मैं प्रत्येक विधि कॉल की प्रविष्टि और बाहर निकलना चाहता हूं। मैंने इसे प्रत्येक विधि में कोड जोड़ने के बिना सी ++ के साथ पहले किया है। क्या यह सी # के साथ संभव है?मैं सी # में प्रत्येक विधि कॉल में ट्रेस() कैसे जोड़ सकता हूं?

+0

के लिए एक ट्यूटोरियल है मोटे तौर पर वह कहाँ है, कैसे कुछ कोड पोस्टिंग ... –

+1

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

+0

बस रिकॉर्ड के लिए, मैं इस तरह से खत्म नहीं हुआ। मैंने WinDbg और स्टैकट्रैक डंप के दर्जनों का उपयोग करके समस्या को हल कर दिया। –

उत्तर

19

शायद आपकी सबसे अच्छी शर्त एक एओपी (पहलू उन्मुख प्रोग्रामिंग) ढांचे का उपयोग करना होगा ताकि विधि निष्पादन के पहले और बाद में स्वचालित रूप से ट्रेसिंग कोड को कॉल किया जा सके। एओपी और .NET के लिए एक लोकप्रिय विकल्प PostSharp है।

+0

धन्यवाद - पोस्टशर्प यहां एक उदाहरण प्रोजेक्ट के साथ आता है जो कुछ समान करता है। :) –

+1

हाल ही में पोस्टशर्प डायग्नोस्टिक्स टूलकिट पेश किया गया है http://www.sharpcrafters.com/blog/post/Configuring-PostSharp-Diagnostics-Toolkits.aspx –

2

रेड गेट से ANTS Profiler का उपयोग करें, आपकी सबसे अच्छी शर्त होगी। यह विफल हो रहा है, में interceptors देखें। ऐसा लगता है कि आप आईओसी के माध्यम से अपने प्रकार लोड कर रहे हैं।

प्रतिबिंब एक और तरीका है, आप स्मृति में कोड लिखने के लिए System.Reflection.Emit विधियों का उपयोग कर सकते हैं। वह कोड आपकी विधि के कोड को प्रतिस्थापित कर सकता है, और इसे निष्पादित कर सकता है लेकिन उचित लॉगिंग के साथ। उस पर शुभकामनाएं, हालांकि ... Aspect# जैसे एक पहलू ओरिएंटेड प्रोग्रामिंग ढांचे का उपयोग करना आसान होगा।

+0

एएनटीएस बहुत अच्छा है (जैसा कि प्रोफाइलर में बनाया गया वीएस है), लेकिन दोष यह है कि आप ऐप की स्मृति/समय 'पदचिह्न' बदल सकते हैं। और संभवतः लॉक का अनुभव नहीं ... –

+0

ट्रेसिंग भी समय बदल जाएगा। –

+1

हां, यह हेइजेनबर्ग की अनिश्चितता सिद्धांत है। प्रयोग को देखकर आप प्रयोग के परिणामों को अच्छी तरह से बदल सकते हैं। यह आपके लिए थ्रेड सिंक डिबगिंग है ... –

0

आप कैसे जानते हैं कि यह हो रहा है? यदि यह एक बहुप्रचारित अनुप्रयोग है, तो मैं शर्त के लिए परीक्षण की सलाह दूंगा और सिस्टम का पता लगाऊंगा। डायग्नोस्टिक्स.डिबगर। ब्रेक() रनटाइम पर जब यह पता चला है। फिर, बस थ्रेड विंडो खोलें और प्रत्येक प्रासंगिक थ्रेड पर कॉल स्टैक के माध्यम से कदम उठाएं।

3

विकास के दौरान आपके चल रहे कोड को देखने के लिए एक प्रोफाइलर बहुत अच्छा है, लेकिन यदि आप उत्पादन में कस्टम निशान करने की क्षमता की तलाश में हैं, तो डेनिस जी का उल्लेख किया गया है, PostSharp एक आदर्श उपकरण है: आप नहीं करते अपने सभी कोड को बदलना होगा और आप इसे आसानी से चालू/बंद कर सकते हैं।

कुछ मिनटों में सेट अप करना भी आसान है और पोस्टशर्प के निर्माता गेल फ्रेटूर भी वीडियो हैं जो आपको दिखाता है कि मौजूदा ऐप में ट्रेसिंग करना कितना आसान है।
आपको documentation section में उदाहरण और ट्यूटोरियल मिलेगा।

1

यह लॉक समस्या को पकड़ने, मेमोरी डंप करने और विभिन्न धागे पर कॉल स्टैक का विश्लेषण करने का इंतजार कर रहा है। आप DebugDiag या एडप्लस स्क्रिप्ट (इस मामले में हैंग मोड) का उपयोग कर सकते हैं जो Debugging Tools for Windows के साथ आता है।

Tess Ferrandez में .NET मेमोरी डंप का उपयोग करके विभिन्न समस्याओं को डीबग करने के लिए सीखने पर excellent lab series भी है। मैं इसकी पुरजोर सलाह देता हूँ।

3

की जाँच अपने प्राथमिक लक्ष्य समारोह प्रवेश/निकास बिंदुओं और बीच में कभी-कभी जानकारी लॉग इन करने की है, तो है, मैं एक डिस्पोजेबल प्रवेश वस्तु के साथ अच्छे परिणाम मिला है जहां कन्स्ट्रक्टर फ़ंक्शन एंट्री, और निपटान() बाहर निकलने का निशान का पता लगाता है। यह कथन का उपयोग करते हुए कॉलिंग कोड को प्रत्येक विधि के कोड को केवल के अंदर लपेटने की अनुमति देता है। बीच में मनमाना लॉग के लिए तरीके भी प्रदान किए जाते हैं।

using System; 
using System.Diagnostics; 
using System.Diagnostics.Tracing; 
using System.Reflection; 
using System.Runtime.CompilerServices; 

namespace MyExample 
{ 
    // This class traces function entry/exit 
    // Constructor is used to automatically log function entry. 
    // Dispose is used to automatically log function exit. 
    // use "using(FnTraceWrap x = new FnTraceWrap()){ function code }" pattern for function entry/exit tracing 
    public class FnTraceWrap : IDisposable 
    { 
     string methodName; 
     string className; 

     private bool _disposed = false; 

     public FnTraceWrap() 
     { 
      StackFrame frame; 
      MethodBase method; 

      frame = new StackFrame(1); 
      method = frame.GetMethod(); 
      this.methodName = method.Name; 
      this.className = method.DeclaringType.Name; 

      MyEventSourceClass.Log.TraceEnter(this.className, this.methodName); 
     } 

     public void TraceMessage(string format, params object[] args) 
     { 
      string message = String.Format(format, args); 
      MyEventSourceClass.Log.TraceMessage(message); 
     } 

     public void Dispose() 
     { 
      if (!this._disposed) 
      { 
       this._disposed = true; 
       MyEventSourceClass.Log.TraceExit(this.className, this.methodName); 
      } 
     } 
    } 

    [EventSource(Name = "MyEventSource")] 
    sealed class MyEventSourceClass : EventSource 
    { 
     // Global singleton instance 
     public static MyEventSourceClass Log = new MyEventSourceClass(); 

     private MyEventSourceClass() 
     { 
     } 

     [Event(1, Opcode = EventOpcode.Info, Level = EventLevel.Informational)] 
     public void TraceMessage(string message) 
     { 
      WriteEvent(1, message); 
     } 

     [Event(2, Message = "{0}({1}) - {2}: {3}", Opcode = EventOpcode.Info, Level = EventLevel.Informational)] 
     public void TraceCodeLine([CallerFilePath] string filePath = "", 
            [CallerLineNumber] int line = 0, 
            [CallerMemberName] string memberName = "", string message = "") 
     { 
      WriteEvent(2, filePath, line, memberName, message); 
     } 

     // Function-level entry and exit tracing 
     [Event(3, Message = "Entering {0}.{1}", Opcode = EventOpcode.Start, Level = EventLevel.Informational)] 
     public void TraceEnter(string className, string methodName) 
     { 
      WriteEvent(3, className, methodName); 
     } 

     [Event(4, Message = "Exiting {0}.{1}", Opcode = EventOpcode.Stop, Level = EventLevel.Informational)] 
     public void TraceExit(string className, string methodName) 
     { 
      WriteEvent(4, className, methodName); 
     } 
    } 
} 

कोड का उपयोग करता है यह कुछ इस तरह दिखेगा::

public void DoWork(string foo) 
{ 
    using (FnTraceWrap fnTrace = new FnTraceWrap()) 
    { 
     fnTrace.TraceMessage("Doing work on {0}.", foo); 
     /* 
     code ... 
     */ 
    } 
} 
-1

प्रयास करें JetBrains dottrace यह एक .NET है यहाँ एक समारोह प्रवेश/बाहर निकलें आवरण के साथ एक पूरी सी # ETW घटना का पता लगाने वर्ग है प्रदर्शन प्रोफाइलर। आपको अपना कोड संशोधित करने की आवश्यकता नहीं है। और यह आपको परीक्षण के लिए 10 दिन देता है।

यहाँ देखते हुए आप जानते हैं कि आप क्या कर रहे हैं और ताला लगा dottrace

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