Re: Win32 TerminateProcess problem

Phillip Palk <[email protected]>
Newsgroups gmane.games.devel.sweng
Message-ID <[email protected]>
For what it's worth this works 100% of the time (ie. output is always 0,0) on my system, Windows 7 64-bit on a quad-core machine.  Not very useful to you on XP SP3 though.

I'd imagine this would only be a problem when terminating the process before it's gotten a time slice. Here's a few things you could try:
    * Lower the creator's priority and yield to try and give the new process a time slice (unless that counts as 'wait a little')?
    * Close the process handle and re-open it
    * Query something about the process before terminating it (eg GetProcessWorkingSetSize)

Of course, I've no idea if any of these would apply to your actual use case even if they did work.


Phil.


-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Emil Dotchevski
Sent: Thursday, 4 February 2010 5:52 AM
To: [email protected]
Subject: [Sweng-Gamedev] Win32 TerminateProcess problem

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
_______________________________________________
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.