2010-03-01 9 views
6

(मैं ढेर के शीर्ष पर निर्देश का पता रहा हूँ) मैं एक Win32 दुर्घटना के एक स्ट्रिंग वर्णन मिलता है मैं one described here मैं कैसे प्राप्त कर सकते हैं की तरह एक वर्ग/विधि का उपयोग स्टैक के शीर्ष पर कॉल का विवरण/पता?कैसे जबकि शीर्ष स्तर फिल्टर में

असल में मैं कुछ मूल्य मैं अपने बग ट्रैकिंग प्रणाली के लिए एक कॉल में उपयोग कर सकते हैं चाहता हूँ। मैं अपवाद के कारण निर्देश के पते के आधार पर "विशिष्ट रूप से" पहचान करना चाहता हूं।

(यह आमतौर पर mydll.dll के रूप के बारे में कुछ है 1234ABDC()!)

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

कुछ पृष्ठभूमि जानकारी:

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

उत्तर

1

EXCEPTION_POINTERS संरचना जो TopLevelFilter() पर भेजी गई है, में EXCEPTION_RECORD संरचना है जिसमें ExceptionAddress शामिल है। यह पता आप कौन सी पता लगा सकते हैं जिसमें डीएलएल अपमानजनक ओपोड CreateToolhelp32Snapshot के साथ मॉड्यूल की गणना करके है। आप dbghelp.dll में दिए गए प्रतीक को ढूंढने के लिए dbghelp.dll में फ़ंक्शन का उपयोग कर सकते हैं जो

1

GetExceptionInformation EXCEPTION_POINTERS संरचना को वापस कर देगा जिसमें अपवाद के बारे में जानकारी शामिल है। अपवाद रिकॉर्डर सदस्य में एक अपवाद एड्रेस सदस्य होता है, जो अपवाद का पता है।

आप उपयोगी होने के लिए अपने कोड में एक मॉड्यूल सापेक्ष स्थान के लिए इस पते को नहीं की आवश्यकता होगी। HMODULE (जो मॉड्यूल का मूल पता भी है) प्राप्त करने के लिए आप GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS के साथ GetModuleHandleEx का उपयोग कर सकते हैं। GetModuleInformation का उपयोग उस मॉड्यूल का वास्तविक नाम प्राप्त करने के लिए किया जा सकता है जिसमें अपवाद हुआ था।

यह वास्तव में आपके लिए सहायक नहीं हो सकता है अगर गलती वास्तव में सिस्टम डीएलएल के अंदर है। एक और परिष्कृत योजना एक स्टैक ट्रेस उत्पन्न करने के लिए होगी (stbwalk64 में dbghelp का उपयोग करके), और अपने कोड में मौजूद शीर्षतम फ्रेम को अनदेखा करना होगा।

+0

+1 हां, यह संभवतः स्टैक पर चलना बेहतर है जब तक कि हम पहले कोड पर न आएं, जो हमारा कोड है। – Tim

4

आपको अपवाद के लिए संदर्भ जानकारी के अधिकांश समय तक अपवाद हैंडलर तक पहुंचने के बाद कोड को अपने अपवाद फ़िल्टर में ऐसा करने की आवश्यकता है।

try 
{ 
    // whatever 
} 
except (MyExceptionFilter(GetExceptionInformation())) 
{ 
} 

आपका फ़िल्टर इस

LONG WINAPI MyExceptionFilter (
    EXCEPTION_POINTERS * pExcept, 
    BOOL     fPassOn) 
{ 
    EXCEPTION_RECORD * pER = pExcept->ExceptionRecord; 
    DWORD dwExceptionCode = pER->ExceptionCode; 

    TCHAR szOut[MAX_PATH*4]; // exception output goes here. 
    szOut[0] = 0; 

    MEMORY_BASIC_INFORMATION mbi; 
    DWORD cb = VirtualQuery (pER->ExceptionAddress, &mbi, sizeof(mbi)); 
    if (cb == sizeof(mbi)) 
     { 
     TCHAR szModule[MAX_PATH]; 
     if (GetModuleFileName ((HMODULE)mbi.AllocationBase, szModule, MAX_PATH)) 
     { 
     wsprintf(szOut, "Exception at '%s' + 0x%X", szModule, 
        (ULONG_PTR)pER->ExceptionAddress - (ULONG_PTR)mbi.AllocationBase); 
     } 
     } 

    return EXCEPTION_EXECUTE_HANDLER; 
} 

बेशक कुछ ऐसी दिखाई देगी, क्योंकि ExceptionAddress और AllocationBase कि में 64 बिट मात्रा हो जाएगा आप अपने उत्पादन 64 बिट आर्किटेक्चर के लिए थोड़ा समायोजित करने की आवश्यकता होगी मामला।

0

आप अपवाद के लिए एक स्ट्रिंग को मुद्रित करने के दर्द से बच सकते हैं (क्या होता है यदि आप मिनीडम्प को सहेज सकते हैं लेकिन क्रैश किए बिना स्ट्रिंग को प्रारूपित नहीं कर सकते हैं?) इसके बजाय minidump को सहेजकर और cdb.exe या windbg.exe का उपयोग करके अपवाद जानकारी निकालने के लिए।

+0

मुझे यकीन नहीं है कि आप यहां क्या सुझाव दे रहे हैं।मैं समझता हूं कि मैं एक स्ट्रिंग को प्रारूपित करने में सक्षम नहीं हो सकता, लेकिन मेरी प्रक्रिया के बाद मैं नहीं देखता कि मैं बिना किसी संदर्भ के इसे कैसे कर सकता हूं। मेरा लक्ष्य एक ईमेल या अन्य http संदेश भेजना है। – Tim

+0

@frungash, प्रक्रिया के भीतर पहले से ही क्रैश हो चुकी प्रक्रिया का निदान करने की कोशिश कर रहा है, यह बहुत ही कमजोर है। आप किसी भी क्रैश को पकड़ने या अपवाद फ़िल्टर में लॉन्च करने के लिए स्टार्टअप पर एक अलग वॉचडॉग प्रक्रिया लॉन्च कर सकते हैं। मैं अत्यधिक स्टैक ट्रेस या संदेश मैन्युअल रूप से उत्पन्न करने की कोशिश करने के बजाय एक मिनीडम्प प्राप्त करने की अत्यधिक अनुशंसा करता हूं। यह पोस्टमॉर्टम डीबगिंग को असीम रूप से आसान बनाता है। – MSN

+0

मैं मिनीडम्प को सहेज रहा हूं - मैं बस एक "अद्वितीय" नाम के साथ आना चाहता हूं जो दुर्घटना का वर्णन करता है (और स्टैक पर आखिरी कुछ आइटम प्रभावी ढंग से ऐसा करने का एक तरीका प्रतीत होता है) किसी भी मामले में हमारे पास मिनीडम्प है। मुझे एक नई प्रक्रिया में रूचि नहीं है - मैं अधिक सरल कोड के लिए विफल स्ट्रिंग क्रिएशन के कुछ प्रतिशत के साथ रह सकता हूं। – Tim