我有一个非常复杂的程序失败了,我已经用批处理文件和C程序将它简化为这个测试集。为什么我无法在Windows 7中测试返回码?
我的C程序使用ExitProcess将错误级别传递回批处理文件。有时在Windows 7(Microsoft Windows [版本6.1.7600])上,错误级别未被正确解释。
我认为这应该永远运行。在Windows XP上它似乎永远运行。在两台不同的双核Windows 7机器上(一台64位,一台32位),几分钟内就会失败。
我无法想象自己做错了什么,但如果在Windows 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);
}
我的编译器版本和调用是:
微软(R) 32位C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
版权所有(C)微软公司1984-1998。版权所有。
CL/MT level250.c
其他信息:我也尝试下JPSoft的TCC运行并获得相同的行为,使用CMD。我正在使用一个直接的.c程序,而不是.cpp。我没有看到任何单线程版本的失败。我把源代码和二进制文件放在http://jcook.info/win7fail上,zip文件MD5是579F4FB15FC7C1EA454E30FDEF97C16B,CRC32是C27CB73D。
编辑经过建议后,我进一步改变了测试用例,仍然看到了失败。在我们的实际应用中,有数百个线程。有些线程会以各种重要的返回码退出,有些线程会永远运行,有些线程挂在操作系统调用或dll中,并且很难(如果不是不可能的话)终止。
#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);
}
在调用ExitProcess()之前,您是否在等待线程完成之后加入? – IanNorton 2010-07-20 22:58:40
您应该使用WaitForSingleObject()而不是繁忙循环来等待线程终止。此外,只需从WinMain()返回250而不是直接调用ExitProcess()。编译器的启动代码将在WinMain()退出后调用ExitProcess()。 – 2010-07-21 00:16:08
@IanNorton:我不认为有必要等待线程终止和/或加入。我们的整个程序有一些线程无法终止,无论是由于I/O挂起或系统调用还是其他原因。是否有一些来自Microsoft的文档可以让我指出,它显示了重新加入线程的要求? @Remy:我们的实际程序要复杂得多,而且有直接测试的原因。事实证明,删除所有提到的Terminate变量并不能解决问题。即一个简单返回的线程和一个创建该线程然后退出的WinMain也失败。 – piCookie 2010-07-21 13:20:08