2010-07-20 6 views
5

मेरे पास एक बहुत ही जटिल प्रोग्राम है जो असफल रहा है, और मैंने इसे बैच फ़ाइल और सी प्रोग्राम के साथ इस परीक्षण सेट में सरल बना दिया है।मैं विंडोज 7 में रिटर्न कोड का परीक्षण क्यों नहीं कर सकता?

मेरा सी प्रोग्राम बैच फ़ाइल में त्रुटि-रेखा को वापस करने के लिए ExitProcess का उपयोग करता है। कभी-कभी विंडोज 7 (माइक्रोसॉफ्ट विंडोज [संस्करण 6.1.7600]) पर, त्रुटि-रेखा का सही ढंग से व्याख्या नहीं किया जा रहा है।

मुझे लगता है कि यह हमेशा के लिए चलना चाहिए। विंडोज एक्सपी पर यह हमेशा के लिए चलाने के लिए प्रतीत होता है। दो अलग-अलग दोहरी कोर विंडोज 7 मशीनों (एक 64-बिट एक 32-बिट) पर यह कुछ मिनटों में विफल हो जाता है।

मैं कल्पना नहीं कर सकता कि मैं कुछ गलत कर रहा हूं, लेकिन यदि विंडोज 7 पर ExitProcess के बारे में कुछ मजाकिया है, तो मैंने सोचा कि मैं पूछूंगा। क्या यहां कुछ भी है जो मैंने अवैध तरीके से किया है? cmd.exe के लिए

बैच फ़ाइल test.bat:

@ECHO OFF 
SET I=0 
:pass 
SET /A I=I+1 
Title %I% 
start/wait level250 
if errorlevel 251 goto fail 
if errorlevel 250 goto pass 
:fail 

कार्यक्रम level250.c:

#include "windows.h" 

static volatile int Terminate = 0; 

static unsigned __stdcall TestThread(void * unused) 
    { 
    Terminate = 1; 
    return 0; 
    } 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) 
    { 
    CreateThread(NULL, 0, TestThread, NULL, 0, NULL); 

    while (Terminate == 0) Sleep(1); 
    ExitProcess(250); 
    } 

मेरे संकलक संस्करण और मंगलाचरण हैं:

Microsoft (R) 32-बिट सी/सी ++ ऑप्टिमाइज़िंग कंपाइलर संस्करण 12.00.8804 80x86

कॉपीराइट (सी) माइक्रोसॉफ्ट कॉर्प 1984-1998। सर्वाधिकार सुरक्षित।

सीएल/मीट्रिक टन level250.c

अन्य जानकारी: मैं भी JPSoft के TCC के तहत चल रहा करने की कोशिश की और अध्यक्ष एवं प्रबंध निदेशक का उपयोग कर के रूप में समान व्यवहार प्राप्त किया है। मैं एक सीधा .c प्रोग्राम का उपयोग कर रहा हूँ, नहीं .cpp। मुझे एक थ्रेडेड संस्करण में कोई असफलता दिखाई नहीं दे रही है। मैंने स्रोतों और बाइनरी को http://jcook.info/win7fail पर रखा और ज़िप फ़ाइल MD5 57 9F4FB15FC7C1EA454E30FDEF97C16B और सीआरसी 32 सी 27 सीबी 73 डी है।

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

#include "windows.h" 

static unsigned __stdcall TestThread(void * unused) 
    { 
    return 0; 
    } 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) 
    { 
    CreateThread(NULL, 0, TestThread, NULL, 0, NULL); 
    return(250); 
    } 
+1

क्या आप ExitProcess() को कॉल करने से पहले इसे पूरा करने के बाद अपने धागे में शामिल होने की प्रतीक्षा नहीं कर रहे हैं? – IanNorton

+0

आपको थ्रेड समाप्ति के लिए प्रतीक्षा करने के लिए व्यस्त लूप के बजाय WaitForSingleObject() का उपयोग करना चाहिए। इसके अलावा, ExitProcess() को सीधे कॉल करने के बजाय WinMain() से 250 वापस लौटें। WinMain() बाहर निकलने के बाद कंपाइलर का स्टार्टअप कोड ExitProcess() को कॉल करेगा। –

+0

@IanNorton: मुझे विश्वास नहीं है कि धागे को समाप्त करने और/या शामिल होने के लिए प्रतीक्षा करना आवश्यक है। हमारे पूरे कार्यक्रम में कुछ धागे हैं जो या तो लटका I/O या सिस्टम कॉल या अन्य कारणों से समाप्त नहीं हो सकते हैं। क्या माइक्रोसॉफ्ट से कुछ दस्तावेज हैं जो आप मुझे इंगित कर सकते हैं कि धागे को फिर से जोड़ने के लिए आवश्यकताओं को दिखाता है? @ रेमी: हमारा वास्तविक कार्यक्रम कहीं अधिक जटिल है और प्रत्यक्ष परीक्षण का एक कारण है। जैसे-जैसे यह निकलता है, टर्मिनेट वैरिएबल के सभी उल्लेखों को हटाकर समस्या का समाधान नहीं होता है। यानी एक थ्रेड जो आसानी से लौटाता है और एक WinMain जो थ्रेड बनाता है तो बाहर निकलता है भी विफल रहता है। – piCookie

उत्तर

1

प्रिंट क्या वापसी कोड वास्तव में है। इस बात की कोई गारंटी नहीं है कि अगर कुछ गलत हो जाता है, तो आपको 251 और 250 मिलेंगे जो आप उम्मीद करते हैं, जैसे सेगमेंटेशन गलती या अन्य त्रुटियों के बारे में जिन्हें आप जानते नहीं हैं। इसके अलावा मैं नहीं देख सकता कि आप अपने कोड में 251 कहां लौट रहे हैं। उच्च निकास कोड से सावधान रहें, मेरा मानना ​​है कि 255 सुरक्षित पोर्टेबल सीमा है, कुछ सिस्टमों पर यह 64 से कम हो सकता है, या < = 127. (यह स्पष्ट रूप से देख सकता है क्योंकि आप स्पष्ट रूप से विंडोज का उपयोग कर रहे हैं लेकिन यह ध्यान देने योग्य है।)

प्रक्रिया को अप्रत्याशित मौत पर एक डीबगर का आविष्कार करने या कोर डंप लोड करने का भी प्रयास करें।

+0

बैच फ़ाइल में "अगर त्रुटि 251" त्रुटि करता है तो त्रुटि त्रुटि 251 या उससे अधिक है। इसलिए इसका पालन करने के बाद "अगर एररलेवल 250" बिल्कुल 250 के लिए परीक्षण करने का तरीका है। हमारे पास सेगफॉल्ट के लिए सभी तरह के हैंडलिंग हैं और इस तरह, लेकिन मैंने यह आसान मामला जानने के लिए एक बहु-लाइन लाइन समस्या को कम कर दिया है, यह जानने के लिए कि यह आसान क्यों है मामला विफल रहता है। – piCookie

1

ऐसा लगता है कि यह विफल होने के समय धागे के परिणाम को वापस कर रहा है। मैंने थ्रेड के वापसी मूल्य को 37 में बदल दिया और बैच फ़ाइल के अंत में echo %errorlevel% जोड़ा। जब यह मेरे पीसी पर रुक गया, तो यह 37 मुद्रित हुआ। तो ऐसा लगता है कि कुछ प्रकार की सिंक्रनाइज़ेशन समस्या है।इसे ठीक करने के लिए, मैं निम्नलिखित करने के लिए मुख्य में कोड बदल दिया है:

HANDLE h = CreateThread(NULL, 0, TestThread, NULL, 0, NULL); 
while (Terminate == 0) Sleep(1); 
WaitForSingleObject(h, INFINITE); 
ExitProcess(250); 

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

मैंने कार्यक्रम बनाया और वीसी 6 (जिस संस्करण का आपने उपयोग किया था), वीएस2005, और वीएस -2008 के साथ समस्या का पुनरुत्पादन किया। मैंने इसे 2-कोर win7 लैपटॉप और 4-कोर win7 डेस्कटॉप मशीन पर जिज्ञासा से बाहर चलाया। यह पुराने एकल-कोर हाइपरथ्रेडेड एक्सपी मशीन पर पुन: उत्पन्न नहीं हुआ था, लेकिन यह कहना नहीं है कि यह अंत में विफल नहीं होगा; शायद इसे वहां बस दौड़ने की जरूरत है।

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

+0

आपके प्रयासों के लिए बहुत बहुत धन्यवाद! दुर्भाग्यवश हम अपने वास्तविक कार्यक्रम में धागे को खत्म करने की प्रतीक्षा नहीं कर सकते हैं (कुछ ओएस में लटकाए गए हैं, आदि) लेकिन मैं ExitProcess को कॉल करने से पहले चीजों के बारे में अधिक जानकारी दूंगा। हमारा कार्यक्रम विंडोज एनटी 4.0 पर कई सालों तक चल रहा है और बिना किसी त्रुटि के विफलता के; मुझे संदेह है कि आपकी एक्सपी मशीन कभी असफल नहीं होगी। – piCookie

+0

हां, आपका संपादन क्लज हमारे लाइव एप्लिकेशन में भी काम करने योग्य नहीं है क्योंकि कुछ थ्रेड जो उनके वापसी मूल्य में पास की गई जानकारी को समाप्त करते हैं। आपके निरंतर विचारों के लिए धन्यवाद! – piCookie

+0

@piCookie: वास्तविक दुनिया आसान समाधान के खिलाफ षड्यंत्र करता है :) मुझे लगता है कि आप सही हैं कि यह विशेष रूप से Win7 समस्या है। या कम से कम मैं आपको गलत साबित करने में असमर्थ हूं। मैंने बिना किसी विफलता के दो कोर एक्सपी मशीन पर आधे मिलियन पुनरावृत्तियों को चलाने दिया। यह एक दिलचस्प समस्या है (आपके लिए मेरे लिए अधिक मुझे यकीन है क्योंकि यह मेरी सीधी समस्या नहीं है)। –

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