प्रोग्राम केवल रिलीज बिल्ड के रूप में क्रैश होता है - डिबग कैसे करें?


95

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

जब मैं Visual Studio के अंदर इस प्रोग्राम को चलाने का प्रयास करता हूं, तो यह क्रैश नहीं होता है। WinDbg.exe से लॉन्च करते समय समान जाता है। क्रैश केवल कमांड लाइन से लॉन्च करते समय होता है। यह Windows Vista, btw के तहत हो रहा है, और दुर्भाग्य से मेरे पास अभी परीक्षण करने के लिए XP मशीन तक पहुंच नहीं है।

यह वास्तव में अच्छा होगा यदि मैं विंडोज को स्टैक ट्रेस का प्रिंट आउट प्राप्त कर सकता हूं, या केवल प्रोग्राम को समाप्त करने के अलावा कुछ और ऐसा कर सकता हूं जैसे कि यह सफाई से बाहर निकल गया हो। क्या किसी के पास कोई सलाह है कि मैं कैसे यहां कुछ और सार्थक जानकारी प्राप्त कर सकता हूं और इस बग को ठीक कर सकता हूं?

संपादित करें: समस्या वास्तव में एक आउट-ऑफ-बाउंड्स सरणी के कारण हुई, जिसका मैं इस पोस्ट में अधिक वर्णन करता हूं । इस समस्या को खोजने में आपकी मदद के लिए हर कोई धन्यवाद!


क्या आप उस परीक्षण विधि का एक नमूना दे सकते हैं?
अंकलेनुक

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

3
अधिकांश उत्तर अनुमानों से थोड़ा अधिक हैं। डिबगर संलग्न किए बिना क्रैश रिलीज़ रिलीज़ का विश्लेषण करने के लिए कुछ सामान्य तकनीकें हैं: stackoverflow.com/a/18513077/214777?stw=2
सेबस्टियन

जवाबों:


127

100% मामलों में मैंने देखा है या सुना है, जहां सी या सी ++ प्रोग्राम डिबगर में ठीक चलता है, लेकिन जब बाहर चलाया जाता है तो विफल रहता है, इसका कारण एक फ़ंक्शन स्थानीय सरणी के अंत में लिख रहा है। (डिबगर स्टैक पर अधिक डालता है, इसलिए आपको कुछ महत्वपूर्ण को अधिलेखित करने की संभावना कम है।)


31
कोई इस आदमी को सिगार दे दे! मेरे मामले में, मैं एक StringBuilder में गुजर रहा था जिसमें P / Invoke फ़ंक्शन की बड़ी क्षमता नहीं थी। मुझे लगता है कि यह आपके चेहरे पर किसी जादू के मार्कर के साथ लिखने जैसा है जब आप सो रहे होते हैं: डीबगर के नीचे, वे आपके माथे पर स्क्रिबलिंग करते हैं, इसलिए आप ध्यान नहीं देते हैं, लेकिन डिबगर के बिना, वे आपको छुरा घोंपते हैं। आँख ... ऐसा कुछ। इस टिप के लिए धन्यवाद!
निकोलस पियासेकी

1
मेरे मामले में यह ओम्ज-सी का उपयोग करके एआरएम प्रोसेसर पर एक संरेखण मुद्दा बन गया।
अलमो

1
11 साल बाद और यह अभी भी सच है ... अपने वैक्टर को आरक्षित करना न भूलें।
डेविड ट्रान

1
ठीक है, तो फिर कोई डिबग मोड के व्यवहार को कैसे बदलता है ताकि कोई वास्तव में डिबग कर सके।
पॉल चिल्ड्स

1
"अब यह जानना कि कहाँ देखना है" लेकिन डिबग में काम करने वाली हर चीज़ आपको बताती है कि समस्या कहाँ है। हालांकि मुझे लगता है कि आपका उत्तर अधिकांश मामलों में सही है, और यह जानना कि क्या देखना एक अच्छी शुरुआत है, एक बड़े कोडबेस के माध्यम से ट्रोल करना जहां वास्तव में समस्या को महंगा किया जा सकता है।
पॉल चिल्ड

54

जब मुझे इस तरह की समस्याओं का सामना करना पड़ा है, तो यह आम तौर पर वैरिएबल इनिशियलाइज़ेशन के कारण हुआ है। डिबग मोड में, चर और संकेत स्वचालित रूप से शून्य पर आरंभिक हो जाते हैं, लेकिन रिलीज मोड में वे नहीं करते हैं। इसलिए, यदि आपके पास इस तरह का कोड है

int* p;
....
if (p == 0) { // do stuff }

डिबग मोड में यदि कोड निष्पादित नहीं होता है, लेकिन रिलीज़ मोड p में एक अपरिभाषित मान होता है, जो कि 0 होने की संभावना नहीं है, इसलिए कोड को अक्सर दुर्घटना का कारण बनाया जाता है।

मैं आपके कोड को अनइंस्टॉल किए गए वैरिएबल के लिए जाँचता हूँ। यह सरणियों की सामग्री पर भी लागू हो सकता है।


विशिष्ट मामले कंस्ट्रक्टर के सदस्य सूची को शुरू करने के लिए एक सदस्य चर (एक) में डालना भूल रहे हैं। एक ही प्रभाव है, लेकिन यह पता लगाना मुश्किल है कि क्या आप नहीं जानते हैं कि आपको उचित सदस्य आरंभीकरण के लिए भी देखना चाहिए।
स्टेफेनज

1
डिबग मोड में वेरिएबल्स को आमतौर पर कुछ 'कंपाइलर डिफाइंड कंटिन्यू' के लिए इनिशियलाइज़ किया जाता है, जिसका इस्तेमाल डिबगिंग में किया जा सकता है ताकि यह पता चले कि वेरिएबल किस अवस्था में है। उदाहरण के लिए: पॉइंटर्स NULL या 0xDeadBeef लोकप्रिय है।
मार्टिन यॉर्क

डिबग रनटाइम आमतौर पर मेमोरी को कुछ नॉनजेरो वैल्यू में इनिशियलाइज़ करते हैं, विशेष रूप से इसलिए कि NULL पॉइंटर टेस्ट कोड का कारण बनेंगे जैसे कि पॉइंटर हम नॉन-नाल हैं। अन्यथा आपके पास कोड है जो डिबग मोड में सही ढंग से चलता है जो रिलीज़ मोड को क्रैश करता है।
माइकल बूर

1
नहीं, चर बिल्कुल भी आरंभ नहीं किए गए हैं और यह अभी भी यूबी है जब तक कि वे असाइन नहीं किए जाते हैं, तब तक उन्हें "उपयोग" करना। हालांकि, अंतर्निहित मेमोरी सामग्री अक्सर 0x0000000 या 0xDEADBEEF या अन्य पहचानने योग्य पैटर्न के साथ पूर्वनिर्मित होती है।
ऑर्बिट

26

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

  1. रिलीज और डिबग बिल्ड कई कारणों से अलग व्यवहार करता है। यहाँ एक उत्कृष्ट अवलोकन है। इनमें से प्रत्येक अंतर रिलीज़ बिल्ड में बग का कारण बन सकता है जो डीबग बिल्ड में मौजूद नहीं है।

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

    डिबगिंग पर अधिक भ्रष्टाचार यहाँ ढेर।

  3. यदि पिछला समाधान काम नहीं करता है, तो आपको अनहैंड अपवाद को पकड़ने और क्रैश होने के बाद पोस्टमार्टम डिबगर संलग्न करने की आवश्यकता है। इसके लिए आप जैसे WinDbg का उपयोग कर सकते हैं, एविएबल पोस्टमार्टम डिबगर्स के बारे में विवरण और MSDN पर उनकी स्थापना

  4. आप अपने अपवाद हैंडलिंग कोड में सुधार कर सकते हैं और यदि यह एक उत्पादन अनुप्रयोग है, तो आपको यह करना चाहिए:

    ए। एक कस्टम समाप्ति हैंडलर का उपयोग कर स्थापित करेंstd::set_terminate

    यदि आप इस समस्या को स्थानीय रूप से डीबग करना चाहते हैं, तो आप समाप्ति हैंडलर के अंदर एक अंतहीन लूप चला सकते हैं और आपको सूचित करने के लिए कंसोल पर कुछ टेक्स्ट को आउटपुट std::terminateकर सकते हैं। फिर डिबगर संलग्न करें और कॉल स्टैक की जांच करें। या आप इस उत्तर में वर्णित स्टैक ट्रेस को प्रिंट करें।

    एक उत्पादन आवेदन में आप एक त्रुटि रिपोर्ट वापस घर भेजना चाहते हैं, आदर्श रूप से एक छोटी मेमोरी डंप के साथ मिल सकते हैं जो आपको यहां वर्णित समस्या का विश्लेषण करने की अनुमति देता है।

    ख। Microsoft के संरचित अपवाद हैंडलिंग तंत्र का उपयोग करें जो आपको हार्डवेयर और सॉफ़्टवेयर अपवादों को पकड़ने की अनुमति देता है। MSDN देखें । आप SEH का उपयोग करके अपने कोड के कुछ हिस्सों की रखवाली कर सकते हैं और समस्या के डीबग करने के लिए a) में उसी दृष्टिकोण का उपयोग कर सकते हैं। एसईएच उस अपवाद के बारे में अधिक जानकारी देता है जो उत्पादन ऐप से त्रुटि रिपोर्ट भेजते समय आप उपयोग कर सकते थे।


16

देखने के लिए चीजें:

ऐरे ओवररन - दृश्य स्टूडियो डिबगर पैडिंग को सम्मिलित करता है जो क्रैश को रोक सकता है।

दौड़ की स्थिति - क्या आपके पास कई थ्रेड्स शामिल हैं यदि कोई दौड़ की स्थिति बहुत से केवल तभी दिखाई देती है जब किसी एप्लिकेशन को सीधे निष्पादित किया जाता है।

लिंकिंग - क्या आपकी रिलीज़ बिल्ड सही पुस्तकालयों में खींच रही है।

कोशिश करने के लिए चीजें:

मिनिडम्प - वास्तव में उपयोग करने में आसान (बस इसे एमएसडीएन में देखें) आपको प्रत्येक थ्रेड के लिए पूर्ण क्रैश डंप देगा। आप सिर्फ आउटपुट को विजुअल स्टूडियो में लोड करते हैं और यह ऐसा है जैसे आप क्रैश के समय डिबगिंग कर रहे थे।


1
हाय - मैं इस जवाब पर एक गुमनाम नीचे वोट पड़ा है। मैं समझना चाहूंगा क्यों?
Morechilli

12

आप WinDbg को अपने पोस्टमॉर्टम डिबगर के रूप में सेट कर सकते हैं। यह डिबगर लॉन्च करेगा और क्रैश होने पर इसे प्रक्रिया में संलग्न करेगा। पोस्टमॉर्टम डिबगिंग के लिए WinDbg को स्थापित करने के लिए, / I विकल्प का उपयोग करें (ध्यान दें कि यह पूंजीकृत है ):

windbg /I

अधिक जानकारी यहाँ

कारण के रूप में, यह सबसे संभवतया एक इकाईय चर है जैसा कि अन्य उत्तर सुझाते हैं।


2
और यह मत भूलो कि आपके पास कंपाइलर पीडीएबी फ़ाइलों को रिलीज़ बिल्ड के लिए भी उत्पन्न कर सकता है, हालांकि यह डिफ़ॉल्ट नहीं है।
माइकल बर्ट

वास्तव में प्रश्न का एकमात्र वास्तविक उत्तर।
सेबेस्टियन

10

डिबगिंग के कई घंटों के बाद, मैंने आखिरकार समस्या का कारण पाया, जो वास्तव में एक बफर अतिप्रवाह के कारण था, एक एकल बाइट का कारण बनता है:

char *end = static_cast<char*>(attr->data) + attr->dataSize;

यह एक फ़र्स्टपोस्ट त्रुटि है (ऑफ-बाय-वन त्रुटि) और इसके द्वारा तय किया गया था:

char *end = static_cast<char*>(attr->data) + attr->dataSize - 1;

अजीब बात यह थी, मैंने अपने कोड के विभिन्न हिस्सों के आसपास _CrtCheckMemory () में कई कॉल किए, और वे हमेशा वापस लौटे। 1. मैं "वापस झूठे;" लिखकर समस्या का स्रोत खोजने में सक्षम था। परीक्षण के मामले में कॉल, और फिर अंततः परीक्षण और त्रुटि के माध्यम से निर्धारित करना जहां गलती थी।

आपकी टिप्पणियों के लिए सभी को धन्यवाद - मैंने आज windbg.exe के बारे में बहुत कुछ सीखा! :)


8
आज मैं एक समान समस्या पर बहस कर रहा हूं और _CrtCheckMemory () हमेशा वापस आ रहा था। लेकिन फिर मुझे एहसास हुआ कि क्यों: रिलीज़ मोड में, _CrtCheckMemory # परिभाषित के रूप में है ((int) 1)।
ब्रायन मोरेर्टी

7

भले ही आपने अपने निर्वासन को रिलीज़ के रूप में बनाया हो, फिर भी आप पीडीबी (प्रोग्राम डेटाबेस) फाइल्स जेनरेट कर सकते हैं जो आपको ट्रेस ट्रेस करने की अनुमति देगा, और सीमित मात्रा में वेरिएबल इंस्पेक्शन करेगा। आपकी बिल्ड सेटिंग्स में PDB फाइल बनाने का विकल्प होता है। इसे चालू करें और त्यागें। फिर आईडीई से चलने का प्रयास करें कि क्या आपको दुर्घटना मिलती है। यदि ऐसा है, तो महान - आप चीजों को देखने के लिए बिल्कुल तैयार हैं। यदि नहीं, तो कमांड लाइन से भागते समय आप दो काम कर सकते हैं:

  1. EXE चलाएँ, और क्रैश होने से पहले प्रक्रिया को संलग्न करें (विजुअल स्टूडियो पर टूल मेनू)।
  2. क्रैश के बाद, डिबगर लॉन्च करने के विकल्प का चयन करें।

जब पीडीबी फ़ाइलों को इंगित करने के लिए कहा जाता है, तो उन्हें खोजने के लिए ब्राउज़ करें। अगर PDB को आपके EXE या DLL के समान आउटपुट फ़ोल्डर में रखा जाता है, तो वे संभवत: स्वचालित रूप से उठाए जाएंगे।

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

NB: मैं यहाँ एक विंडोज़ / विज़ुअल स्टूडियो वातावरण मान रहा हूँ।


3

इस तरह की दुर्घटनाएं लगभग हमेशा होती हैं क्योंकि एक आईडीई आमतौर पर अनरिटाइज्ड वैरिएबल की सामग्री को शून्य, अशक्त या कुछ अन्य ऐसे 'समझदार' मूल्य पर सेट करेगा, जबकि मूल रूप से चलने पर आपको जो भी यादृच्छिक बकवास मिलेगा वह सिस्टम उठाएगा।

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


3

क्रैश डंप के लिए जिसका आप विश्लेषण कर सकते हैं:

  1. अपने कोड के लिए पीडीएफ़ फ़ाइलें बनाएँ।
  2. आप अपने exe और dll को एक ही पते पर लोड करने के लिए रिबेट करते हैं।
  3. डॉ। वाटसन जैसे पोस्टमार्टम डिबगर को सक्षम करें
  4. क्रैश खोजक जैसे उपकरण का उपयोग करके क्रैश विफल पते की जाँच करें ।

आपको विंडोज़ के लिए डीबगिंग टूल में टूल भी देखना चाहिए । आप आवेदन की निगरानी कर सकते हैं और पहले मौके के अपवादों को देख सकते हैं जो आपके दूसरे मौका अपवाद से पहले थे।

आशा करता हूँ की ये काम करेगा...


3

इस तरह की त्रुटि को डीबग करने का एक शानदार तरीका आपके डीबग बिल्ड के लिए अनुकूलन को सक्षम करना है।


2

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

तो आप की तर्ज पर कुछ कर सकते हैं:

लंबी __stdcall MyFilter (EXCEPTION_POINTERS *)
{
    HANDLE hEvt = :: CreateEventW (0,1,0,0);
    अगर (hEvt)
    {
        अगर (WAIT_FAILED == :: WaitForSingleObject (hEvt, INFINITE)
        {
            // लॉग विफलता
        }
    }

}
// कहीं आपके wmain / WinMain:
SetUnhandledExceptionFilter (MyFilter);

मैंने तब डिबगर संलग्न किया था जब बग स्वयं प्रकट हो गया था (गुई कार्यक्रम ने जवाब देना बंद कर दिया था)।

फिर आप या तो डंप ले सकते हैं और बाद में इसके साथ काम कर सकते हैं:

.dump / ma path_to_dump_file

या इसे तुरंत डीबग करें। सबसे आसान तरीका यह है कि रनटाइम अपवाद हैंडलिंग मशीनरी द्वारा प्रोसेसर संदर्भ को कहाँ सहेजा गया है:

एसडी एस्प 1003f रेंज

कमान खोजे जाने की लंबाई प्रदान करने वाले कॉन्टेक्ट रिकॉर्ड (ओं) के लिए स्टैक एड्रेस स्पेस खोजेगा। मैं आमतौर पर 'l! 10000' जैसी किसी चीज़ का इस्तेमाल करता हूं । ध्यान दें, रिकॉर्ड के रूप में आपके द्वारा आमतौर पर अनहैन्डेड अपवाद फ़िल्टर फ़्रेम के पास होने के बाद, बड़ी संख्या में उपयोग न करें। 1003f झंडे का संयोजन है (मेरा मानना ​​है कि यह प्रोसेसर के राज्य पर कब्जा करने के लिए प्रयुक्त CONTEXT_FULL से मेल खाता है)। आपकी खोज इस तरह दिखाई देगी:

0: 000> sd esp l1000 1003f
0012c160 0001003f 00000000 00000000 00000000 .....?

एक बार जब आप परिणाम वापस पा लेते हैं, तो cxr कमांड में पता का उपयोग करें:

.cxr 0012c160

यह आपको इस नए कॉन्टेक्ट में ले जाएगा, बिल्कुल दुर्घटना के समय (आप अपने ऐप के दुर्घटनाग्रस्त होने के समय बिल्कुल स्टैक ट्रेस प्राप्त करेंगे)। इसके अतिरिक्त, उपयोग करें:

.exr -1

यह पता लगाने के लिए कि कौन सा अपवाद हुआ था।

आशा करता हूँ की ये काम करेगा।


2

कभी-कभी ऐसा होता है क्योंकि आपने "मुखर" मैक्रो के अंदर महत्वपूर्ण संचालन को लपेट दिया है। जैसा कि आप जानते हैं, "अभिकर्ता" केवल डिबग मोड पर अभिव्यक्तियों का मूल्यांकन करता है।


1

नैदानिक ​​जानकारी प्राप्त करने में आपकी समस्याओं के संबंध में, क्या आपने WinDbg.exe के विकल्प के रूप में adplus.vbs का उपयोग करने की कोशिश की है? किसी चल रही प्रक्रिया में संलग्न करने के लिए, का उपयोग करें

adplus.vbs -crash -p <process_id>

या दुर्घटना जल्दी से होता है कि आवेदन शुरू करने के लिए:

adplus.vbs -crash -sc your_app.exe

पूरी जानकारी adplus.vbs पर देखी जा सकती है: http://support.microsoft.com/kb/286350


1

Ntdll.dll डिबगर संलग्न के साथ

IDE या WinDbg से प्रोग्राम को लॉन्च करने के बीच एक छोटा सा अंतर यह है कि इसे कमांड लाइन / डेस्कटॉप से ​​लॉन्च करने का विरोध किया जाता है, जब डिबगर संलग्न (यानी IDE या WinDbg) के साथ लॉन्च किया जाता है, तो ntdll.dll एक अलग ढेर कार्यान्वयन का उपयोग करता है जो कुछ कम सत्यापन करता है। स्मृति आवंटन / मुक्त करने पर।

आप ntdll.dll में अनपेक्षित उपयोगकर्ता ब्रेकपॉइंट में कुछ प्रासंगिक जानकारी पढ़ सकते हैं । एक उपकरण जो समस्या की पहचान करने में आपकी मदद करने में सक्षम हो सकता है वह है PageHeap.exe

क्रैश विश्लेषण

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


1

विस्टा SP1 वास्तव में सिस्टम में निर्मित एक बहुत अच्छा क्रैश डंप जनरेटर है। दुर्भाग्य से, यह डिफ़ॉल्ट रूप से चालू नहीं है!

इस लेख को देखें: http://msdn.microsoft.com/en-us/library/bb787181(VS.85).aspx

इस दृष्टिकोण का लाभ यह है कि प्रभावित सिस्टम पर कोई अतिरिक्त सॉफ़्टवेयर स्थापित करने की आवश्यकता नहीं है। इसे पकड़ें और इसे चीर दें, बच्चा!


1

मेरे अनुभव के रूप में, यह सबसे अधिक स्मृति भ्रष्टाचार के मुद्दे हैं।

उदाहरण के लिए :

char a[8];
memset(&a[0], 0, 16);

: /*use array a doing some thing */

जब कोई कोड चलाता है तो डिबग मोड में सामान्य होना बहुत संभव है।

लेकिन रिलीज में, यह दुर्घटना हो सकती है।

मेरे लिए, ऐसी अफवाहों से, जहां स्मृति बंधी हुई है, बहुत ही भयावह है।

कुछ उपकरणों का उपयोग करें जैसे कि दृश्य रिसाव डिटेक्टर (विंडोज़) या वेलग्रिंड (लिनक्स) अधिक बुद्धिमान विकल्प हैं।


1

मैंने बहुत से सही उत्तर देखे हैं। हालांकि, ऐसा कोई नहीं है जिसने मेरी मदद की हो। मेरे मामले में, बिना सोचे समझे मेमोरी के साथ SSE निर्देशों का गलत उपयोग हुआ । अपने गणित पुस्तकालय पर नज़र डालें (यदि आप एक का उपयोग करते हैं), और SIMD समर्थन को अक्षम करने, क्रैश को फिर से शुरू करने और पुन: उत्पन्न करने का प्रयास करें।

उदाहरण:

एक प्रोजेक्ट में मैथफू शामिल है , और एसटीएल वेक्टर के साथ कक्षाओं का उपयोग करता है: एसटीडी :: वेक्टर <मैथफू :: vec2> । इस तरह के उपयोग से संभवतः मैथ्यू :: vec2 आइटम के निर्माण के समय दुर्घटना हो सकती है क्योंकि एसटीएल डिफ़ॉल्ट आवंटनकर्ता 16-बाइट संरेखण की गारंटी नहीं देता है। इस मामले में विचार को साबित करने के लिए, #define MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT 1प्रत्येक गणितफू के शामिल होने से पहले परिभाषित कर सकता है , रिलीज कॉन्फ़िगरेशन में फिर से जुटा सकता है और फिर से जांच कर सकता है।

डिबग और RelWithDebInfo विन्यास अपने प्रोजेक्ट के लिए अच्छी तरह से काम किया, लेकिन नहीं रिलीज एक। इस व्यवहार के पीछे का कारण शायद यह है कि डिबगर आवंटन / निपटान अनुरोधों को संसाधित करता है और मेमोरी तक पहुंच की जांच करने और सत्यापित करने के लिए कुछ मेमोरी बुककीपिंग करता है।

मैंने विजुअल स्टूडियो 2015 और 2017 के वातावरण में स्थिति का अनुभव किया।


0

जीसीसी के साथ एक बार ऐसा ही कुछ मुझे खुशी देता है। यह एक बहुत आक्रामक अनुकूलन निकला जो केवल अंतिम रिलीज़ बनाते समय सक्षम किया गया था और विकास प्रक्रिया के दौरान नहीं।

खैर, सच कहूं तो यह मेरी गलती थी, जीसीसी की नहीं, जैसा कि मैंने नहीं देखा कि मेरा कोड इस तथ्य पर भरोसा कर रहा था कि विशेष अनुकूलन नहीं किया गया होगा।

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


0

मुझे यह लेख आपके परिदृश्य के लिए उपयोगी लगा है। ISTR संकलक विकल्प थोड़ा पुराना था। अपने रिलीज़ स्टूडियो के निर्माण के लिए pdb फ़ाइलों को कैसे बनाएँ, यह देखने के लिए अपने Visual Studio प्रोजेक्ट विकल्पों के आसपास देखें।


0

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


0

डिबगिंग रिलीज बिल्ड, अनुकूलन के कारण दर्द हो सकता है, जिससे आपके कोड की पंक्तियों को निष्पादित करने के क्रम में बदलाव होता है। यह वास्तव में भ्रमित हो सकता है!

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


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

0

आवंटित मेमोरी क्या है, यह देखने के लिए _CrtCheckMemory () का उपयोग करने का प्रयास करें । यदि सबकुछ ठीक हो जाता है, तो _CrtCheckMemory TRUE देता है , अन्यथा FALSE


0

आप अपने सॉफ़्टवेयर को ग्लोबल फ़्लैग्स सक्षम (Windows के लिए डिबगिंग टूल में देखें) के साथ चला सकते हैं। यह अक्सर समस्या को नाखून देने में मदद करेगा।


0

अपना कार्यक्रम एक मिनी डंप उत्पन्न करें जब अपवाद होता है, तो इसे डिबगर में खोलें (उदाहरण के लिए, WinDbg में)। देखने के लिए मुख्य कार्य: MiniDumpWriteDump, SetUnhandledExceptionFilter


0

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

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


-3

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


-6

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


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

स्टेफेनज: मैं गेम डेवलपर्स को बग ढूंढना चाहता हूं। आदर्श रूप से, इससे पहले कि वे जहाज करते हैं, लेकिन अगर यह बाद में है, तो मैं चाहता हूं कि वे पुन: पेश करने और इसे ट्रैक करने के लिए पर्याप्त जानकारी प्राप्त करने में सक्षम हों। यदि यह गुप्त कोड है, तो ट्रेडमार्क लागू नहीं होता है। PDBs? प्रोटीन डाटा-बैंक? अजगर डीबगर?
wnoise

IMHO, यह एक बुरा विचार है। निष्पादन योग्य बड़े हैं, वे अनुकूलित नहीं हैं, और बहुत धीमी गति से चलते हैं। ये मामले वास्तव में बहुत दुर्लभ हैं; भले ही वे विशेष रूप से जब वे ऐसा करते हैं। आपको अत्यंत हीन उत्पाद प्रदान नहीं करना चाहिए, अत्यंत दुर्लभ सबसे खराब स्थिति वाले डिबगिंग के बारे में चिंता करना। (मेरा कई पतन में से एक नहीं था।) मैंने नासा के लिए कुछ प्रोग्रामिंग की; और हमने कहा कि नंगे न्यूनतम पर, कोड की प्रत्येक पंक्ति का एक बार परीक्षण किया जाना चाहिए। यूनिट परीक्षण में भी मदद मिल सकती है।
कोडलेकर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.