2012-10-30 7 views
13

एक बिना क्रिया C++ अपवाद मैं प्रिंट करना चाहते हैं की स्थिति में:क्या मैं विंडोज एसईएच अपवाद से सी ++ अपवाद डीकोड कर सकता हूं? (? और यदि हां, तो कैसे)

  1. C++ अपवाद
  2. एक स्टैक ट्रेस का संदेश (what())।

आदेश स्टैक ट्रेस पाने के लिए, मैं संयोजन में SetUnhandledExceptionFilter उपयोग कर रहा हूँ StackWalker पुस्तकालय के साथ:

struct FooStackWalker : StackWalker 
{ 
    virtual void OnCallstackEntry(CallstackEntryType, CallstackEntry &entry) override 
    { 
     std::cerr << entry.lineFileName << " (" << entry.lineNumber << "): " << entry.undFullName << std::endl; 
    } 
}; 

LONG WINAPI UnhandledExceptionHandler(LPEXCEPTION_POINTERS pointers) 
{ 
    FooStackWalker walker; 
    walker.ShowCallstack(::GetCurrentThread(), pointers->ContextRecord); 
    ::TerminateProcess(::GetCurrentProcess(), 1); 
} 


int main() 
{ 
    ::SetUnhandledExceptionFilter(UnhandledExceptionHandler); 
} 

मैं स्टैक ट्रेस मिल गया है ठीक मुद्रित करने के लिए, लेकिन अब हो रही what है मुश्किल।

क्या कोई तरीका है कि मैं एसईएच अपवाद को सी ++ अपवाद के रूप में डीकोड कर सकता हूं ताकि इस सदस्य फ़ंक्शन को समाप्त करने से पहले कॉल किया जा सके?

+0

आपको 3 अपवाद जानकारी शब्द मिलेंगे। दूसरा अपवाद वस्तु के लिए एक सूचक है। आपको इसकी व्याख्या करने की कोई उम्मीद नहीं है, सी ++ में प्रतिबिंब जैसी कोई चीज़ नहीं है। * पकड़ * कीवर्ड द्वारा उत्सर्जित अपवाद फ़िल्टर महत्वपूर्ण हैं। –

+0

@ हंस: अगर कोई मानता है कि जो चीज फेंक दी गई है वह हमेशा 'std :: अपवाद' (जो कई कोडबेस के लिए सच है) से निकली है, तो इसका व्याख्या नहीं किया जा सकता है? एक बार आपके पास 'std :: अपवाद' हो जाने पर आप विशिष्ट अपवाद प्रकारों के लिए 'dynamic_cast' डाउन कर सकते हैं यदि आवश्यक हो ... –

+0

* क्या * अपवाद को कास्ट करें? यही कुंजी है। आपको * क्या * मिल सकता है। –

उत्तर

2

सी ++ मशीनरी का उपयोग क्यों न करें जो आपको पहले ही अपवाद विवरण देता है? यह एसईएच फिल्टर के साथ अनन्य नहीं है (हालांकि यह SetUnhandledExceptionFilter के साथ विशिष्ट है)। आपको केवल हैंडलर को सही तरीके से घोंसला करना होगा:

int main() 
{ 
    try { 
     return cppexcept_main(); 
    } 
    catch (const std::exception& e) 
    { 
     //use e.what() 
    } 
} 

int cppexcept_main() 
{ 
    __try { 
     return application_main(); 
    } 
    __except(GrabStackTrace(GetExceptionInformation()), EXCEPTION_CONTINUE_SEARCH) { 
     /* never reached due to EXCEPTION_CONTINUE_SEARCH */ 
    } 
} 
2

संपादित करें: मैंने आपके प्रश्न को गलत समझा। मैं निश्चित रूप से यह नहीं कह सकता कि उत्तर सी ++ अपवादों के लिए क्या है, लेकिन मुझे यकीन है कि उत्तर "नहीं" है। मुझे विश्वास नहीं है कि एसईएच (उदा। एक्सेस उल्लंघन) और बिना सी ++ अपवादों के असंतुलित अपवादों के बीच अंतर करने का कोई तरीका है, या विभिन्न प्रकार के सी ++ अपवादों के बीच अंतर करने का कोई तरीका है। घोड़े ने उस पर बर्न छोड़ दिया है।

मूल नीचे जवाब:


नहीं, एक SEH अपवाद एक what नहीं होने के कारण। यह std::exception नहीं है। This MSDN example कहता है कि जब आप एक सी ++ अपवाद के रूप में एक एसईएच अपवाद पकड़ने की कोशिश कर रहे हैं, तो इसे केवल इलिप्सिस (...) catch हैंडलर से पकड़ा जा सकता है। आप अपने स्वयं के फ़ंक्शन को परिभाषित करने के लिए _set_se_translator का उपयोग कर सकते हैं जो एसईएच अपवादों को सी ++ अपवादों में परिवर्तित करता है, लेकिन उस बिंदु पर आप एक ही स्थान पर एक ही जानकारी से अपना खुद का what उत्पन्न कर रहे हैं (और फिर भी, मुझे नहीं पता कि यह ' UnhandledExceptionFilter से इसे प्राप्त करना संभव है)।

आपके पास LPEXCEPTION_POINTERS structure में आपकी सभी जानकारी है। यदि एक प्रवेश उल्लंघन हुआ, तो pointers->ExceptionRecord->ExceptionCodeEXCEPTION_ACCESS_VIOLATION (0xC0000005) होगा। यदि ऐसा हुआ, तो आप NumberParameters और ExceptionInformation चर की जांच कर सकते हैं यह पता लगाने के लिए कि क्या यह एक पढ़ा गया था या लिखना उल्लंघन था और जिस पते को एक्सेस करने का प्रयास किया गया था।

+0

नहीं, मैं रिवर्स करना चाहता हूं - एक सी ++ अपवाद में एक एसईएच अपवाद बारी।बेशक, यदि एसईएच अपवाद वास्तव में एक सी ++ अपवाद नहीं है (एमएसवीसी ++ अपवाद कोड '0xE06D7363' का उपयोग करने के लिए प्रतीत होता है), जो भी रूपांतरण विफल हो जाता है या अन्यथा मुझे नरक में जाने के लिए कहता है (इस मामले में मैं नहीं करता वैसे भी एक स्टैक ट्रेस मुद्रित करने का प्रयास करना चाहते हैं - किसी को किसी भी उल्लंघन उल्लंघन या जो कुछ भी चलने के बाद दौड़ना जारी रखने की कोशिश नहीं करनी चाहिए)। –

+0

(यह ध्यान दिया जाना चाहिए कि मुझे इस तरह की चीज को सादा सी ++ 'पकड़' के अंदर करने में खुशी होगी, लेकिन उस बिंदु पर ढेर अवांछित रहा है इसलिए फेंकने की स्थिति के ढेर को प्रिंट करना असंभव है) –

+0

पुष्टि 0xE06D7363: http : //blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx –

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