Win32 TerminateProcess problem

Emil Dotchevski <[email protected]>
Newsgroups gmane.games.devel.sweng
Message-ID <[email protected]>
I want to terminate a process with an exit code, and I want that exit
code to be returned by the process being killed. Note that I can't
synchronize with the process and I can't "wait a little" before I kill
it.

On my system (XP SP3) the test below fails nearly 100% of the time.
When it fails, the process being killed returns zero (instead of 42.)

Any ideas?

#include <string>
#include <sstream>
#include <iostream>
#include <assert.h>
#include <windows.h>

void check_call( bool result, char const * call, char const * file, int line );
#define CHECK_CALL(call) check_call(call,#call,__FILE__,__LINE__);

int
main( int argc, char const * argv[] )
    {
    if( argc>1 )
        {
        assert( !strcmp(argv[1],"inf") );
        for(;;)
            {
            }
        }
    int errors=0, zeroes=0;
    for( int i=0; i!=100; ++i )
        {
        STARTUPINFO sinfo;
        ZeroMemory(&sinfo,sizeof(STARTUPINFO));
        sinfo.cb=sizeof(STARTUPINFO);
        PROCESS_INFORMATION pe;
        char cmd_line[32768];
        strcat(strcpy(cmd_line,argv[0])," inf");
        CHECK_CALL((CreateProcess(0,cmd_line,0,0,TRUE,0,0,0,&sinfo,&pe)!=0));
        CHECK_CALL((CloseHandle(pe.hThread)!=0));
        CHECK_CALL((TerminateProcess(pe.hProcess,42)!=0));
        CHECK_CALL((WaitForSingleObject(pe.hProcess,INFINITE)==WAIT_OBJECT_0));
        DWORD ec=0xFFFFFFFF;
        CHECK_CALL((GetExitCodeProcess(pe.hProcess,&ec)!=0));
        assert(ec!=0xFFFFFFFF);
        CHECK_CALL((CloseHandle(pe.hProcess)!=0));
        errors += (ec!=42);
        zeroes += (ec==0);
        }
    std::cout << errors << ',' << zeroes << std::endl;
    return 0;
    }

std::string
get_last_error_str( DWORD err )
    {
    std::ostringstream s;
    s << err;
    LPVOID lpMsgBuf=0;
    if( FormatMessageA(
            FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
            0, err, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
(LPSTR)&lpMsgBuf, 0, 0) )
        {
        assert(lpMsgBuf!=0);
        std::string msg;
        try
            {
            std::string((LPCSTR)lpMsgBuf).swap(msg);
            }
        catch(
        ... )
            {
            }
        LocalFree(lpMsgBuf);
        if( !msg.empty() && msg[msg.size()-1]=='\n' )
            msg.resize(msg.size()-1);
        if( !msg.empty() && msg[msg.size()-1]=='\r' )
            msg.resize(msg.size()-1);
        s << ", \"" << msg << '"';
        }
    return s.str();
    }

void
check_call( bool result, char const * call, char const * file, int line )
    {
    assert(call && *call);
    assert(file && *file);
    assert(line>0);
    DWORD le=GetLastError();
    if( !result )
        {
        std::cerr << file << '(' << line << "):\n" << call << "
failed\nand GetLastError returned:" <<
            get_last_error_str(le) << std::endl;
        exit(2);
        }
    else if( le )
        {
        std::cerr << file << '(' << line << "):\n" << call << "
succeeded,\nbut GetLastError returned" <<
            get_last_error_str(le) << std::endl;
        exit(3);
        }
    }

-- 
Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode
_______________________________________________
Sweng-Gamedev mailing list
[email protected]
http://lists.midnightryder.com/listinfo.cgi/sweng-gamedev-midnightryder.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.