2011-08-03 18 views
10

परिचय संशोधित कर रहा है - लंबा और उबाऊ हिस्सा

(सवाल अंत में है)तीसरे पक्ष के कोड एफपीयू नियंत्रण शब्द

मैं हो रही है सिर पर गंभीर एक तीसरी पार्टी COM घटक है कि रहता है से अधिक दर्द एफपीयू नियंत्रण शब्द बदल रहा है।

मेरे विकास पर्यावरण विंडोज और विजुअल C++ 2008 सामान्य एफपीयू नियंत्रण शब्द निर्दिष्ट करता है कि कोई अपवाद विभिन्न शर्तों के दौरान फेंक दिया जाना चाहिए। मैंने _CW_DEFAULT मैक्रो float.h में पाए गए मैक्रो के साथ-साथ स्टार्टअप पर डीबगर में नियंत्रण शब्द को देखकर दोनों को सत्यापित किया है।

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

मैं इस COM घटक के लिए स्रोत की जरूरत नहीं है, लेकिन मैं लेखक के साथ संपर्क में हूँ। मेरे द्वारा किए गए प्रतिक्रियाएं "हू?" रही हैं। मुझे नहीं लगता कि उसके पास थोड़ी सी सुराग है जिसके बारे में मैं बात कर रहा हूं, इसलिए मुझे डर है कि मुझे इसके बारे में कुछ करना है। मेरा मानना ​​है कि उसका रनटाइम (मुझे लगता है कि यह या तो डेल्फी या बोर्लैंड सी ++ है, क्योंकि डीएलएल प्रतीकात्मक नामों से भरा है, सभी पूंजी टी से शुरू होते हैं), या कुछ अन्य तीसरे पक्ष कोड का उपयोग कर रहे हैं, जिससे समस्या आ रही है। मुझे नहीं लगता कि उसका कोड स्पष्ट रूप से एफपीयू नियंत्रण शब्द को संशोधित करता है।

तो, मैं क्या कर सकता हूं? व्यवसाय के दृष्टिकोण से, इस तीसरे पक्ष के घटक का उपयोग करना जरूरी है। तकनीकी दृष्टि से, मैं इसे हटा सकता हूं, और संचार के प्रोटोकॉल को स्वयं कार्यान्वित कर सकता हूं। हालांकि, यह वास्तव में महंगा होगा, क्योंकि इस प्रोटोकॉल में क्रेडिट कार्ड लेनदेन को संभालना शामिल है। हम देयता को नहीं लेना चाहते हैं।

मैं सख्त एक हैक के आसपास, या Borland उत्पादों है कि मैं घटक के लेखक के पास भेजने के कर सकते हैं में एफपीयू सेटिंग्स के बारे में कुछ उपयोगी जानकारी की जरूरत है।

सवाल

क्या मैं कर सकते हैं? मुझे नहीं लगता कि घटक लेखक के पास इसे ठीक करने के लिए क्या लगता है (उसके बजाय अनजान प्रतिक्रियाओं से निर्णय लेना)।

मैं अपने खुद के अपवाद संचालक, जिसमें मैं सिर्फ हैंडलर में नियंत्रण शब्द रीसेट करें, और क्रियान्वित करने के लिए जारी करने के लिए Windows बता स्थापित करने के विचार के साथ की है। मैंने हैंडलर को SetUnhandledExceptionFilter() के साथ स्थापित करने का प्रयास किया, लेकिन किसी कारण से अपवाद पकड़े नहीं गए।

  1. मैं अपवादों को क्यों नहीं पकड़ रहा हूं?
  2. अगर मैं एफपीयू अपवादों को पकड़ने, एफपीयू नियंत्रण शब्द को रीसेट के साथ सफल, और सिर्फ निष्पादन जारी रखने के लिए कुछ भी नहीं के रूप में हुआ है करते हैं - सब दांव तो दूर कर रहे हैं?

अद्यतन

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

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

दो संशोधनों मैं अपने ऐप को बना दिया है:

  1. लपेटें मेरा संदेश पंप
  2. कोने मामलों में जहां संदेश पंप पार हो जाने को पकड़ने के लिए एक खिड़की हुक (WH_CALLWNDPROC) स्थापित करें

दोनों मामलों में, मैं जांचता हूं कि एफपीयू सीडब्ल्यू बदल गया है या नहीं। यदि यह है, तो मैं इसे _CW_DEFAULT पर रीसेट कर देता हूं।

+2

http://www.virtualdub.org/blog/pivot/entry.php?id=53; लंबी कहानी छोटी, उन्होंने किसी भी "खतरनाक" कोड पथ के बाद एफपीयू नियंत्रण दुनिया को बहाल करने के लिए कोड भी जोड़ा, लेकिन पोस्ट का उल्लेख है कि "बोर्लैंड रन-टाइम लाइब्रेरी के इस व्यवहार को अक्षम करना और इस समस्या से बचना संभव है" –

+0

@matteo , लिंक के लिए आपको धन्यवाद। एक दिलचस्प पढ़ा! मैं इसे लेखक को अग्रेषित करूंगा। –

+0

वैसे, मुझे लगता है कि उस पोस्ट में उल्लिखित व्यवहार को अक्षम करने का तरीका वास्तव में Set8087CW फ़ंक्शन का उपयोग कर रहा है, जैसा कि @ डेविड द्वारा उनके उत्तर में बताया गया है। –

उत्तर

6

मुझे लगता है कि आपका निदान यह है कि घटक एम्बरकेडेरो उत्पाद में लिखा गया है, यह सच होने की संभावना है। डेल्फी की रनटाइम लाइब्रेरी वास्तव में सी ++ बिल्डर के लिए फ़्लोटिंग पॉइंट अपवादों को सक्षम करती है।

Embarcaderos उपकरण के बारे में अच्छी चीजों में से एक यह है कि फ़्लोटिंग पॉइंट त्रुटियों को भाषा अपवादों में परिवर्तित किया जाता है जो संख्यात्मक कोडिंग को बहुत आसान बनाता है। यह आपके लिए थोड़ा सांत्वना होने वाला है!

यह संपूर्ण क्षेत्र एक विशाल पिटा है। एफपी नियंत्रण शब्द के संबंध में कोई नियम नहीं हैं। यह कुल मिलाकर सभी के लिए मुफ्त है।

मुझे विश्वास नहीं है कि अनचाहे अपवादों को पकड़ने के लिए काम नहीं किया जा रहा है क्योंकि एमएस सी ++ रनटाइम संभावित रूप से इन अपवादों को पकड़ लेगा, लेकिन मैं उस क्षेत्र में कोई विशेषज्ञ नहीं हूं और मैं गलत हो सकता हूं।

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

मेरे उत्पाद में डेल्फी में लागू एक डीएलएल शामिल है और मैं रिवर्स समस्या से पीड़ित हूं। ज्यादातर क्लाइंट जो कॉल करते हैं उनमें एक एफपीयू नियंत्रण शब्द होता है जो अपवाद अक्षम करता है। हम जिस रणनीति को अपनाते हैं, वह 8087 सीडब्ल्यू को एंट्री पर याद रखना है, इसे कोड निष्पादित करने से पहले मानक डेल्फी सीडब्ल्यू पर सेट करें, और उसके बाद इसे बाहर निकलने के बिंदु पर पुनर्स्थापित करें। हम कॉलबैक करने से पहले कॉलर के 8087 सीडब्ल्यू को बहाल करके भी कॉलबैक से निपटने का ख्याल रखते हैं। यह COM ऑब्जेक्ट की बजाय एक सादा DLL है, इसलिए यह शायद थोड़ा सा आसान है।

यदि आप COM कोड को अपने कोड को संशोधित करने का प्रयास करने का निर्णय लेते हैं तो उन्हें Set8087CW() फ़ंक्शन पर कॉल करने की आवश्यकता है।

हालांकि, चूंकि गेम के लिए कोई नियम नहीं हैं, मेरा मानना ​​है कि COM ऑब्जेक्ट विक्रेता को उनके कोड को बदलने से इनकार करने और आपको वापस चालू करने के लिए उचित ठहराया जाएगा।

क्षमा करें अगर यह 100% निर्णायक उत्तर नहीं है, लेकिन मुझे इन सभी विचारों को एक टिप्पणी में नहीं मिला!

+0

से सहमत हूं जानकारी के लिए धन्यवाद! मुझे उम्मीद है कि दूसरा लड़का मेरी मदद करने के लिए तैयार है, क्योंकि मैं उसके लिए राजस्व पैदा कर रहा हूं। मुझे लगता है कि अगर वह एक नया इंटरफ़ेस लागू करता है, तो 'IFPUControlWordPolicy' कहें, जिसके माध्यम से मैं अपना पसंदीदा सीडब्ल्यू पंजीकृत कर सकता हूं, फिर वह यह सुनिश्चित कर सकता है कि सीडब्ल्यू उस चीज़ पर सेट हो जो मैं चाहता हूं, और इसे अपने पसंदीदा सीडब्ल्यू पर पुनर्स्थापित करें आने वाली कॉल, आदि। यदि यह इतना आसान है। रनटाइम कोड हो सकता है जो "उसके दृश्यों" के पीछे चलाया जाता है, जो एफपीयू सीडब्ल्यू को संशोधित करता है। उनका दावा है कि वह एफपीयू सीडब्ल्यू के लिए कुछ भी नहीं कर रहे हैं, और किसी भी तरह एफपीयू सीडब्ल्यू संशोधित है ... –

+0

... ऐसा लगता है कि जब मैं एक घटना सिंक से लौटता हूं तो सीडब्ल्यू संशोधित होता है। मुझे संदेह है कि वह घटनाओं को असंकालिक रूप से उत्पन्न कर रहा है (यानी, वे अपने घटक में मेरी कॉल के परिणामस्वरूप उत्पन्न नहीं होते हैं), और सीडब्लू को तब संशोधित किया जाता है। मैं इसके खिलाफ खुद की रक्षा नहीं कर सकता, क्योंकि इस परिदृश्य में, मेरा कोड उस बिंदु पर कॉल स्टैक पर नहीं है। :/ –

+0

एम्बा रनटाइम सबसे निश्चित रूप से सीडब्ल्यू सेट करता है। वह स्पष्ट रूप से ऐसा नहीं करेगा। हालांकि उनका कोड एफपी अपवादों का भरोसा कर सकता है। –

6

हालांकि एफपी नियंत्रण शब्द प्रति-धागा है, हालांकि नए धागे बनाए जाने पर डेलमेन फ़ंक्शन को कॉल किया जाता है, मुझे नहीं लगता कि आप इस प्रक्रिया को एक नई प्रक्रिया में जाने से बच सकते हैं।

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

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

+0

सीडब्ल्यू को बार-बार रीसेट करने की आवश्यकता होती है क्योंकि जब भी डेल्फी कोड डेल्फी libs चलाता है इसे संशोधित करेगा –

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