From: Emil Dotchevski on 3 Feb 2010 19:21 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
From: David Lowndes on 3 Feb 2010 19:40 >On my system (XP SP3) the test below fails nearly 100% of the time. So presumably, once in a blue moon it's OK? >When it fails, the process being killed returns zero (instead of 42.) > >Any ideas? What happens if you wait a short time after starting the process before terminating it? Dave
From: Nobody on 3 Feb 2010 19:54 "Emil Dotchevski" <emildotchevski(a)gmail.com> wrote in message news:95e9d35d-60e0-414d-81bb-cef3c12d485b(a)k2g2000pro.googlegroups.com... >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.) Is the call to TerminateProcess successful?
From: Emil Dotchevski on 3 Feb 2010 20:01 On Feb 3, 4:40 pm, David Lowndes <Dav...(a)example.invalid> wrote: > >On my system (XP SP3) the test below fails nearly 100% of the time. > So presumably, once in a blue moon it's OK? Right. I suspect it succeeds if the system randomly happens to do something else that slows the TerminateProcess down. Like me hitting Ctrl+F5 frantically. :) > >When it fails, the process being killed returns zero (instead of 42.) > > What happens if you wait a short time after starting the process > before terminating it? The more Sleep I add before calling TerminateProcess, the more likely it is for the program to work correctly; Sleep of about 5 ms makes it work almost always on my computer. However, my real use case is such that I can't afford to Sleep, and the process I'm killing is launched by a 3rd party program. By the way, I get feedback that the code I posted works on Win7. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
From: Emil Dotchevski on 3 Feb 2010 20:04
On Feb 3, 4:54 pm, "Nobody" <nob...(a)nobody.com> wrote: > "Emil Dotchevski" <emildotchev...(a)gmail.com> wrote in message > > news:95e9d35d-60e0-414d-81bb-cef3c12d485b(a)k2g2000pro.googlegroups.com... > > >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.) > > Is the call to TerminateProcess successful? Yes. All function calls succeed. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode |