2008-10-01 8 views
35

मैं .net (C#) में एक अनचाहे अपवाद हैंडलर जोड़ने की कोशिश कर रहा हूं जो संभवतः 'उपयोगकर्ता' के लिए उपयोगी हो। अंतिम उपयोगकर्ता अधिकतर प्रोग्रामर होते हैं, इसलिए उन्हें केवल एक संकेत की आवश्यकता होती है कि वे किस वस्तु को गलत तरीके से जोड़ रहे हैं।एक .net अपवाद में तर्क मानों के साथ एक स्टैकट्रैक कैसे प्राप्त करें

मैं एक एप्लिकेशन को क्रैश होने पर विंडोज एक्सपी त्रुटि रिपोर्ट के समान विंडोज़ विकसित कर रहा हूं लेकिन यह अपवाद के बारे में जितना संभव हो उतना इमेडिएट जानकारी देता है।

जबकि स्टैक ट्रेस मुझे समस्या के स्रोत को इंगित करने के लिए सक्षम बनाता है (चूंकि मेरे पास स्रोत कोड है), उपयोगकर्ताओं के पास यह नहीं है और इसलिए वे बिना किसी जानकारी के खो गए हैं। कहने की जरूरत नहीं है कि मुझे उपकरण का समर्थन करने में बहुत समय व्यतीत करना है।

कुछ सिस्टम अपवाद हैं जैसे कि KeyNotFoundException शब्दकोश संग्रह द्वारा फेंक दिया गया है जो वास्तव में मुझे बग करता है क्योंकि वे संदेश में शामिल नहीं होने वाली कुंजी में शामिल नहीं होते हैं। मैं अपने कोड को पकड़ने के कई प्रयासों के साथ भर सकता हूं लेकिन इसके बजाय आक्रामक और बनाए रखने के लिए बहुत अधिक कोड है, स्थानीय स्तर पर होने वाले तारों के एक टन का उल्लेख न करें।

आखिरकार सवाल: कॉल स्टैक ट्रेस में प्रत्येक फ़ंक्शन के तर्कों के मूल्यों को चलाने के लिए कोई तरीका है (रनटाइम पर)? वह अकेले समर्थन कॉल का 9 0% हल कर सकता है।

+1

यह पहले ही अच्छी तरह से उत्तर दिया गया है, लेकिन भविष्य के संदर्भ के लिए मैं रेमंड चेन के उत्कृष्ट ब्लॉग आलेख में एक पॉइंटर जोड़ना चाहूंगा [जब ऑब्जेक्ट कचरा संग्रहण के लिए उपलब्ध हो जाता है?] (Http: //blogs.msdn। com/b/oldnewthing/archive/2010/08/10/10048149.aspx) अन्य चीजों के अलावा, यह इंगित करता है कि स्टैक ट्रेस से विश्वसनीय मूल्यों को एकत्रित करना असंभव है, क्योंकि तर्कों को एकत्र किया जा सकता है जबकि संदर्भित विधियां अभी भी निष्पादित हो रही हैं । –

+0

मैंने यह https://stackoverflow.com/questions/2696691/can-i-get-the-method-local-variables-through-a-stack-trace-in-c देखा है लेकिन मुझे नहीं पता कि कैसे 'अपवाद' ऑब्जेक्ट से 'स्टैकट्रेस' प्राप्त करने के लिए। उस पर एक 'स्ट्रिंग' है। –

उत्तर

0

मुझे ऐसा कुछ भी पता नहीं है, लेकिन मैं इसे स्वयं चाहता हूं। अपवाद फेंकते समय मैं आमतौर पर इसे स्वयं करता हूं, लेकिन यदि यह फेंकने के लिए नहीं है, तो आप हमारे बाकी हिस्सों से बाहर हो सकते हैं।

1

मुझे विश्वास नहीं है कि एक अंतर्निहित तंत्र है। स्टैक ट्रेस के प्रत्येक फ्रेम को पुनर्प्राप्त करते हुए, आपको ट्रेस में विधि निर्धारित करने की अनुमति देते हुए, केवल आपको उस विधि पर प्रतिबिंबित प्रकार की जानकारी देता है। कोई पैरामीटर जानकारी नहीं। मुझे लगता है कि यही कारण है कि कुछ अपवाद, विशेष रूप से, ArgumentException, et। अल। अपवाद में शामिल तर्क के मूल्य को निर्दिष्ट करने के लिए एक तंत्र प्रदान करें क्योंकि इसे प्राप्त करने का कोई आसान तरीका नहीं है।

7

मुझे नहीं लगता कि सिस्टम। डायग्नोस्टिक्स.स्टैकफ्रेम तर्क की जानकारी प्रदान करता है (विधि हस्ताक्षर के अलावा)।

आप एओपी के माध्यम से ट्रेस लॉगिंग के साथ परेशान कॉल का उपयोग कर सकते हैं, या यहां तक ​​कि अपने कोड को कूड़े बिना सशर्त रूप से लॉग अप करने के लिए अपवाद इंटरसेप्शन सुविधाओं का उपयोग कर सकते हैं। http://www.postsharp.org/ के आसपास एक नज़र डालें।

0

मुझे कॉल स्टैक ट्रेस में प्रत्येक फ़ंक्शन के तर्कों के मान प्राप्त करने का कोई तरीका नहीं पता है, लेकिन एक समाधान विशिष्ट अपवाद (KeyNotFoundException आपके उदाहरण में) को पकड़ने और उसे फिर से फेंकने के लिए होगा नई अपवाद यही कारण है कि आप किसी भी अतिरिक्त जानकारी संबद्ध करने के

इच्छा उदाहरण के लिए अनुमति देता है:

Dim sKey as String = "some-key" 
Dim sValue as String = String.Empty 

Try 
    sValue = Dictionary(sKey) 
Catch KeyEx As KeyNotFoundException 
    Throw New KeyNotFoundException("Class.Function() - Couldn't find [" & sKey & "]", KeyEx) 
End Try 

मैं त्रुटि तार स्थानीयकरण के बारे में अपने बयान की सराहना करते हैं, लेकिन अपने दर्शकों को कर रहे हैं 'ज्यादातर प्रोग्रामर' तो सम्मेलन पहले से ही अंग्रेजी की एक समझ तय कुछ डिग्री (सही या गलत तरीके से - लेकिन यह एक और बहस है!)

+1

हां, मुझे पता है कि मैं कर सकता हूं, लेकिन यह बेहद जबरदस्त है कि मैं इससे बचने की कोशिश कर रहा हूं। आखिरी शव मैंने बनाया है कि मेरे पास हैशटेबल के लिए लगभग 200+ कॉल हैं और वे हर रोज बढ़ेंगे। मैं एक सहायक समारोह के बारे में सोच रहा हूं लेकिन यह अभी भी बदसूरत दिखता है और केवल KeyNotFoundException को हल करता है। – Caerbanog

+1

हो सकता है कि एक सहायक फ़ंक्शन जाने का तरीका है, क्षमा करें, मैं मदद नहीं कर सका (मेरे पसंदीदा में जोड़ा गया है, इसलिए मैं यह देखने के लिए जांच कर सकता हूं कि आप क्या निर्णय लेते हैं): o) – Andrew

1

चूंकि अंतिम उपयोगकर्ता डेवलपर हैं, तो आप उन्हें एक संस्करण प्रदान कर सकते हैं जो पारित होने वाले सभी प्रमुख मूल्यों/तर्कों को लॉगिंग करने में सक्षम बनाता है। और एक सुविधा प्रदान करें ताकि वे लॉगिंग चालू/बंद कर सकें।

0

एक बार जब आप अपवाद रखते हैं तो दो चीजें आप रुचि रखते हैं System.Diagnostics.StackTrace और System.Diagnostics।StackFrame

एक MSDN उदाहरण नहीं है here

+0

ठीक है, लेकिन जब मेरे पास 'अपवाद' है तो मैं नहीं 'StackTrace' ऑब्जेक्ट प्राप्त करने का कोई तरीका नहीं दिखता है। अपवाद में 'स्टैकट्रेस' कॉल स्टैक का पहले से ही धारावाहिक स्ट्रिंग प्रतिनिधित्व है। –

+0

@CsabaToth https://msdn.microsoft.com/en-us/library/4ce0ktkk(v=vs.110).aspx – slf

+0

क्या आपका मतलब है कि मुझे कन्स्ट्रक्टर पैरामीटर के रूप में अपवाद का उपयोग करके 'स्टैकट्रेस' ऑब्जेक्ट बनाना चाहिए? मुझे लगता है कि मैं कोशिश करूँगा –

3

दुर्भाग्य से आप डीबगिंग उपकरण वास्तव में आवेदन के साथ संलग्न के साथ छोड़कर callstack से मानकों के वास्तविक मान नहीं मिल सकता है। हालांकि सिस्टम में StackTrace और StackFrame ऑब्जेक्ट्स का उपयोग करके। डायग्नोस्टिक्स आप कॉल स्टैक पर जा सकते हैं और इन सभी विधियों और पैरामीटर नामों और प्रकारों को पढ़ सकते हैं। आप वास्तविक मूल्यों की आवश्यकता तो आप minidumps लेते हैं और उन्हें विश्लेषण मैं डर लग रहा है की जरूरत के लिए जा रहे हैं

System.Diagnostics.StackTrace callStack = new System.Diagnostics.StackTrace(); 
System.Diagnostics.StackFrame frame = null; 
System.Reflection.MethodBase calledMethod = null; 
System.Reflection.ParameterInfo [] passedParams = null; 
for (int x = 0; x < callStack.FrameCount; x++) 
{ 
    frame = callStack.GetFrame(x); 
    calledMethod = frame.GetMethod(); 
    passedParams = calledMethod.GetParameters(); 
    foreach (System.Reflection.ParameterInfo param in passedParams) 
     System.Console.WriteLine(param.ToString()); 
} 

: आप इस तरह करना होगा। डंप में जानकारी प्राप्त करने के बारे में जानकारी में पाया जा सकता:

http://www.debuginfo.com/tools/clrdump.html

+4

इस समस्या के साथ आप अपवाद के समय ढेर नहीं, कैच के अंदर से ढेर प्राप्त कर रहे हैं। एक दिलचस्प मुद्दा (सुरक्षा) का उल्लेख करने के लिए – GeekyMonkey

1

यह पोर्टेबल निष्पादन योग्य (पीई) फ़ाइल स्वरूप का लाभ लेने के चर प्रकार और ऑफसेट पाने के लिए द्वारा तुम क्या चाहते करने के लिए सैद्धांतिक रूप से संभव है, लेकिन मैं कुछ साल पहले ऐसा करने की कोशिश कर रहे एक [दस्तावेज़ीकरण] दीवार में भाग गया। सौभाग्य!

1

यदि आप जो भी कर रहे हैं वह कर सकते हैं, तो आप .NET सुरक्षा के एक अभिन्न अंग को हरा देंगे।

मामले में सबसे अच्छा विकल्प, यह एक डीबगर या प्रोफाइलर से जुड़ा हुआ है (उनमें से कोई भी उन मानों तक पहुंच सकता है)। पूर्व संलग्न किया जा सकता है, प्रोग्राम शुरू होने से पहले सक्रिय होने की आवश्यकता है।

+1

+1; लेकिन क्या आप सुरक्षा को तोड़ने के तरीके पर थोड़ा और विस्तार कर सकते हैं, या बल्कि, आप उस पहलू को "अभिन्न" क्यों मानते हैं? – stakx

5

इसी तरह, मुझे रनटाइम पर स्वचालित रूप से पैरामीटर प्राप्त करने के लिए कुछ भी नहीं मिला है। इसके बजाय, मैं एक दृश्य स्टूडियो का उपयोग किया है ऐड-इन कोड कि स्पष्ट रूप से पैरामीटर पैकेज, इस तरह उत्पन्न करने के लिए:

public class ExceptionHandler 
{ 
    public static bool HandleException(Exception ex, IList<Param> parameters) 
    { 
     /* 
     * Log the exception 
     * 
     * Return true to rethrow the original exception, 
     * else false 
     */ 
    } 
} 

public class Param 
{ 
    public string Name { get; set; } 
    public object Value { get; set; } 
} 

public class MyClass 
{ 
    public void RenderSomeText(int lineNumber, string text, RenderingContext context) 
    { 
     try 
     { 
      /* 
      * Do some work 
      */ 
      throw new ApplicationException("Something bad happened"); 
     } 
     catch (Exception ex) 
     { 
      if (ExceptionHandler.HandleException(
        ex, 
        new List<Param> 
        { 
         new Param { Name = "lineNumber", Value=lineNumber }, 
         new Param { Name = "text", Value=text }, 
         new Param { Name = "context", Value=context} 
        })) 
      { 
       throw; 
      } 
     } 
    } 
} 

संपादित करें: या वैकल्पिक रूप से, एक पैरामीटर सरणी HandleException पैरामीटर बनाकर:

public static bool HandleException(Exception ex, params Param[] parameters) 
{ 
    ... 
} 

... 
if (ExceptionHandler.HandleException(
        ex, 
        new Param { Name = "lineNumber", Value=lineNumber }, 
        new Param { Name = "text", Value=text }, 
        new Param { Name = "context", Value=context} 
        )) 
{ 
    throw; 
} 
... 

यह असाधारण हैंडलर को पैरामीटर को स्पष्ट रूप से पास करने के लिए अतिरिक्त कोड उत्पन्न करने वाला दर्द है, लेकिन ऐड-इन के उपयोग के साथ आप इसे कम से कम स्वचालित कर सकते हैं।

एक कस्टम विशेषता कोई पैरामीटर है कि आप ऐड-इन अपवाद संचालक को पारित करने के लिए नहीं करना चाहते हैं टिप्पणी करने के लिए इस्तेमाल किया जा सकता:

public UserToken RegisterUser(string userId, [NoLog] string password) 
{ 
} 

2ND संपादित करें:

मन आप, मैं पूरी तरह से AVICode के बारे में भूल गया हूं:

http://www.avicode.com/

वे कॉल इंटरसेप्शन तकनीक का उपयोग जानकारी के बिल्कुल इस तरह प्रदान करने के लिए, तो यह संभव होना चाहिए।

2

वहाँ एक रेडगेट से एक सॉफ्टवेयर उपकरण है, जो बहुत ही प्रमोशनल लगता है।

http://www.red-gate.com/products/dotnet-development/smartassembly/

वर्तमान में हम ईमेल द्वारा अपने ग्राहकों को त्रुटि रिपोर्ट जमा कर रहे हैं और मैं कभी कभी लापता कुछ महत्वपूर्ण डेटा के साथ (ज्यादातर कुछ बहुत ही बुनियादी चर, आईडी की तरह मौजूदा रिकॉर्ड से तो मैं बग पुन: पेश कर सकते हैं) के लिए संघर्ष। मैंने अभी तक इस उपकरण का परीक्षण नहीं किया है, लेकिन मेरी समझ से यह करता है कि यह स्टैक से तर्क मान और स्थानीय चर एकत्र करता है।

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