Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I test the return code in Windows 7?

I have a very complicated program that is failing, and I've simplified it to this test set with a batch file and C program.

My C program uses ExitProcess to pass back the errorlevel to a batch file. Sometimes on Windows 7 (Microsoft Windows [Version 6.1.7600]), the errorlevel is not being interpreted correctly.

I think this should run forever. On Windows XP it appears to run forever. On two different dual-core Windows 7 machines (one 64-bit one 32-bit) it fails within a couple minutes.

I can't imagine that I'm doing something wrong, but in case there is something funny about ExitProcess on Windows 7, I thought I'd ask. Is there anything here I've done illegally?

Batch file test.bat for cmd.exe:

@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);
    }

My compiler version and invocation are:

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86

Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

cl /MT level250.c

Other information: I have also tried running under JPSoft's TCC and get the same behavior as using CMD. I am using a straight .c program, not .cpp. I do not see any failures in a single threaded version. I put the sources and binaries on http://jcook.info/win7fail and the zip file MD5 is 579F4FB15FC7C1EA454E30FDEF97C16B and CRC32 is C27CB73D.

EDIT After suggestions, I have further changed the test case and still see the failures. In our actual application, there are hundreds of threads. Some threads exit with various significant return codes, some run forever, and some are hung in operating system calls or dlls and are difficult (if not impossible) to kill.

#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);
    }
like image 662
piCookie Avatar asked Nov 06 '22 10:11

piCookie


1 Answers

Print what the return code actually is. There's no guarantee that if something goes wrong, you will get the 251 and 250 that you expect, such as through segmentation fault, or other errors you're not aware of. Furthermore I can't see where you're returning 251 in your code. Be wary of high exit codes, I believe 255 is safe portable limit, on some systems it may be less than 64, or <= 127. (This might be irrelevant seeing as you're obviously using Windows but it's worth noting.)

Also try invoking a debugger, or loading a core dump upon the process' unexpected death.

like image 180
Matt Joiner Avatar answered Nov 12 '22 21:11

Matt Joiner