2010-07-20 14 views
5

Başarısız olan çok karmaşık bir programım var ve bunu bir toplu iş dosyası ve C programı ile bu sınama kümesine göre basitleştirdim.Neden Windows 7'de dönüş kodunu test edemiyorum?

C programım, hata düzeyini bir toplu iş dosyasına geri döndürmek için ExitProcess kullanır. Bazen Windows 7'de (Microsoft Windows [Sürüm 6.1.7600]), hata seviyesi doğru şekilde yorumlanmıyor.

Sanırım bu sonsuza dek koşmalı. Windows XP'de sonsuza kadar çalıştığı görülüyor. İki farklı çift çekirdekli Windows 7 makinesinde (bir 64 bit bir 32 bit), birkaç dakika içinde başarısız olur.

Yanlış bir şey yaptığımı hayal edemiyorum, ancak Windows 7'de ExitProcess ile ilgili komik bir şey olması durumunda, sormam gerektiğini düşündüm. Burada yasadışı olarak yaptığım bir şey var mı? cmd.exe için

Toplu dosya 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 

Programı 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); 
    } 

Benim derleyici sürümü ve çağırma şunlardır:

Microsoft (R) 32-bit C/C++ Derleyici Sürüm 12.00.8804 için En İyi duruma getirme 80x86 için

Telif hakkı (C) Microsoft Corp 1984-1998. Her hakkı saklıdır.

cl/MT level250.c

Diğer bilgiler: Ben de JPSoft en TTK altında çalışan denenmiş ve CMD kullanarak aynı davranışı elde var. Düz bir .c programı kullanıyorum, değil .cpp. Tek bir dişli sürümde herhangi bir başarısızlık görmüyorum. Kaynakları ve ikili dosyaları http://jcook.info/win7fail'a koydum ve MD5 zip dosyası 579F4FB15FC7C1EA454E30FDEF97C16B ve CRC32 C27CB73D.

EDIT Önerilerden sonra, daha fazla test durumunu değiştirdim ve hala hataları görüyorum. Bizim gerçek uygulamada yüzlerce konu var. Bazı iplikler, bazı önemli dönüş kodları ile çıkmaktadır, bazıları sonsuza dek sürmektedir ve bazıları işletim sistemi çağrılarına veya dll'lerine asılmaktadır ve öldürmek için (imkansız değilse) zor olmaktadır. dönüş kodu aslında ne

#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() 'ı aramadan önce iş parçacığının tamamlandıktan sonra katılmasını beklemiyor musunuz? – IanNorton

+0

İş parçacığı sonlandırmasını beklemek için yoğun bir döngü yerine WaitForSingleObject() yöntemini kullanmalısınız. Ayrıca, doğrudan ExitProcess() 'i çağırmak yerine doğrudan WinMain()' dan 250 döndürün. Derleyicinin başlangıç ​​kodu, WinMain() çıktıktan sonra ExitProcess() öğesini çağırır. –

+0

@IanNorton: Konuların sonlandırılmasını ve/veya katılmasını beklemenin gerekli olduğuna inanmıyorum. Tüm programımız, ya asılı G/Ç veya sistem çağrıları ya da diğer nedenlerden dolayı sonlanamayan bazı iş parçacıklarına sahiptir. Microsoft'un bazı belgeleri var mı, bana bu konuya yeniden katılma gereksinimlerini gösterir? @Remy: Gerçek programımız çok daha karmaşık ve doğrudan test için bir sebep var. Sonuç olarak, Terminate değişkeninin tümünün kaldırılması sorunu çözmez. Yani, basitçe dönen bir iş parçacığı ve çıkıntıyı oluşturan bir WinMain çıkmaz. – piCookie

cevap

1

Baskı. Bir şeyler ters giderse, bölümleme hatası veya farkında olmadığınız diğer hatalar gibi beklediğiniz 251 ve 250'yi alacağınızın garantisi yoktur. Ayrıca kodunuzda 251'i nereye döndüğünüzü göremiyorum. yüksek çıkış kodları karşı dikkatli olun, bazı sistemlerde daha az 64 veya < = 127. olabilir 255 güvenli taşınabilir sınırı olduğuna inanıyoruz (tabii ki Windows kullanıyorsanız gibi bu alakasız gören olabilir ama belirtmek gerekir.)

da bir hata ayıklayıcı yürütmesini ya da işlemin beklenmedik ölümü üzerine bir çekirdek dökümü yükleme deneyin.

+0

Bir toplu iş dosyasında "errorlevel 251 ise" hata seviyesi 251 veya daha fazlaysa eylemi gerçekleştirir. Bu nedenle, "errorlevel 250" ile bunu takip etmek, tam olarak 250 test etme yoludur. Segmentler için her türlü işleme sahibiz ve böyle basit bir duruma neden olan çok basit bir çizgi problemini azalttık. dava başarısız. – piCookie

1

İş parçacığının sonucunun başarısız olduğu zamanlarda döndüğü anlaşılıyor. İş parçacığının dönüş değerini 37 olarak değiştirdim ve toplu iş dosyasının sonuna echo %errorlevel% ekledim. Bilgisayarımda durduğunda 37 basıldı. Yani bir çeşit senkronizasyon problemi var gibi görünüyor.Bunu düzeltmek için, ben aşağıdakilere ana kod değiştirdi:

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

ExitProcess belgeleri açıkça çıkış kodu "süreci ve tüm parçacıkları için" olduğunu söylüyor. Öyleyse bir hata var gibi görünüyor, ancak tüm iplikleri öldürmek için ExitProcess'e güvenmek en iyi plan gibi görünmüyor. Bu yüzden bitirmelerini beklemek muhtemelen makul bir harekettir.

Programı oluşturdum ve sorunu VC6 (kullandığınız sürümün), VS2005 ve VS2008 ile yeniden oluşturdum. Ben 2 çekirdekli bir win7 dizüstü bilgisayar ve 4 çekirdekli bir win7 masaüstü bilgisayarında merak ettim. Eski bir tek çekirdekli hiper iş parçacıklı XP makinesinde çoğaltılmadı, ancak bunun sonunda sonuçta başarısız olmayacağı söylenemez; Belki de orada daha uzun koşmak gerekiyordu.

Düzenleme Bu kludge biraz olurdu, ama belki bir çözüm uygulamada genel değişken çıkış kodu depolamak ve tüm ipliklerden o değeri döndürmek olacaktır. Daha sonra, bu problemin/hatanın oluştuğu durumda, uygulamanın çıkış kodu hala istenen değer olacaktır.

+0

Çabalarınız için çok teşekkür ederim! Ne yazık ki, asıl programımızdaki iş parçacıklarının bitmesini bekleyemeyiz (bazıları OS'de, vs.), ancak ExitProcess'i aramadan önce yapacakları şeyler hakkında daha fazla şey keşfedeceğim. Programımız, Windows NT 4.0'da yıllarca çalışıyor ve hiç böyle bir hata hatası yaşamadan; XP makinenizin asla başarısız olacağından şüpheleniyorum. – piCookie

+0

Ne yazık ki, düzenleme kludge uygulamanız canlı uygulamada da kullanılamaz çünkü bazı bilgiler geri dönüş bilgisini sonlandırır. Devam eden fikirleriniz için teşekkürler! – piCookie

+0

@piCookie: Gerçek dünya, kolay çözümlere karşı geliyor :) Bence özellikle bir Win7 problemi olduğunu biliyorsunuz. Ya da en azından yanlış olduğunu kanıtlayamıyorum. İki çekirdekli XP makinesinde yarım milyon iterasyonun hatasız çalışmasına izin verdim. Bu ilginç bir sorundur (benim için daha fazla sorun çünkü benim doğrudan problemim olmadığından eminim). –

İlgili konular