Windows下父进程监视子进程状态

最近研究自动化测试,需要获取程序的运行状态及结果,下面是些参考资料。

原文地址:http://blog.csdn.net/ariesjzj/article/details/7226443 

Linux下有功能强大ptrace,用于让父进程监视/修改/控制子进程的状态。Windows也提供了类似的接口,那就是Debuging API,用它可以编写用户级的调试器。

 下面是一个例子,用以实现父进程创建并监视子进程运行状态。 

  1. #include <stddef.h>  
  2. #include <stdio.h>  
  3. #include <string.h>  
  4. #include <stdlib.h>  
  5. #include <stdint.h>  
  6. #include <assert.h>  
  7. #include <windows.h>  
  8.   
  9. #define MAX_PARAM_LEN       4096  
  10.   
  11. int main( int argc, char ** argv )  
  12. {  
  13.     int i, j = 0, len;  
  14.     char command_buf[MAX_PARAM_LEN];  
  15.   
  16.     STARTUPINFO si;  
  17.     PROCESS_INFORMATION pi;  
  18.     DEBUG_EVENT de;  
  19.     BOOL stop = FALSE;  
  20.   
  21.     ZeroMemory( &si, sizeof(si) );  
  22.     si.cb = sizeof(si);  
  23.     ZeroMemory( &pi, sizeof(pi) );  
  24.   
  25.     if (argc<2) {  
  26.         printf("Usage: %s <app_name> [arguments ...] ", argv[0]);  
  27.         return 0;  
  28.     }  
  29.   
  30.     // Combine the module name and params into one string.  
  31.     for (i = 1; i < argc; ++i) {  
  32.         len = strlen(argv[i]);  
  33.         if (len >= MAX_PARAM_LEN - j - 1) {  
  34.             printf("buffer overflow ");  
  35.             exit(-1);  
  36.         }  
  37.         j += _snprintf(command_buf + j, MAX_PARAM_LEN - j, "%s ", argv[i]);  
  38.         command_buf[j] = '';  // just for sure  
  39.     }  
  40.   
  41.     if( !CreateProcess(NULL, command_buf, NULL, NULL, FALSE,            
  42.         DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi ) ) {  
  43.             printf( "CreateProcess failed (%d). ", GetLastError() );  
  44.             exit(-1);  
  45.     }  
  46.   
  47.     while (TRUE) {  
  48.         WaitForDebugEvent (&de, INFINITE);  
  49.   
  50.         switch (de.dwDebugEventCode) {  
  51.         case EXCEPTION_DEBUG_EVENT:         /* exception */  
  52.             switch (de.u.Exception.ExceptionRecord.ExceptionCode) {   
  53.             case   EXCEPTION_INT_DIVIDE_BY_ZERO:    /* #DE */  
  54.                 // Do what the parent process want to do when the child process gets #DE interrupt.  
  55.                 TerminateProcess(pi.hProcess,1);   
  56.                 break;   
  57.             case   EXCEPTION_BREAKPOINT:            /* #BP */  
  58.                 // Do what the parent process want to do when the child process gets #BP interrupt.  
  59.                 break;  
  60.   
  61.             default:   
  62.                 printf("Unknown Exception ");   
  63.                 break;  
  64.             }      
  65.   
  66.             ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_EXCEPTION_HANDLED);  
  67.             continue;  
  68.   
  69.         case CREATE_PROCESS_DEBUG_EVENT:        /* child process created */  
  70.   
  71.             // Do what the parent process want to do when the child process was created.  
  72.             break;  
  73.   
  74.         case EXIT_PROCESS_DEBUG_EVENT:          /* child process exits */  
  75.             stop = TRUE;  
  76.   
  77.             // Do what the parent process want to do when the child process exits.  
  78.             break;  
  79.   
  80.         default:  
  81.             printf("Unknown Event! ");  
  82.             break;  
  83.         }  
  84.   
  85.         if (TRUE == stop) {  
  86.             //printf("Process exit ");  
  87.             break;  
  88.         }  
  89.   
  90.         ContinueDebugEvent (de.dwProcessId, de.dwThreadId, DBG_CONTINUE);  
  91.   
  92.     } // end of loop  
  93.   
  94.     assert(stop);  
  95.   
  96.     CloseHandle( pi.hProcess );  
  97.     CloseHandle( pi.hThread );  
  98.   
  99.     return 0;  
  100. }  

程序参数为要监视的子进程及子进程的参数。注意一个正常的进程被创建出来后会先后收到CREATE_PROCESS_DEBUG_EVENT, EXCEPTION_DEBUG_EVENT中的EXCEPTION_BREAKPOINT和EXIT_PROCESS_DEBUG_EVENT。所以如果你不想子进程创建起来就出错,那就让处理断点的分支跳去执行ContinueDebugEvent(..., DBG_EXCEPTION_HANDLED)。

例子仅含框架,如要attach到已有进程请参见DebugActiveProcess,要修改子进程状态请参见RriteProcessMemory和WriteProcessMemory等函数。

一些参考资料:

Debugging API examples: http://www.debuginfo.com/examples/dbgexamples.html

Writing the Debugger's Main Loop: http://msdn.microsoft.com/en-us/library/windows/desktop/ms681675(v=vs.85).aspx

Using the Windows Debugging API: http://www.howzatt.demon.co.uk/articles/SimpleDebugger.html

Debugging Functions: http://msdn.microsoft.com/en-us/library/ms679303

Win32调试API:http://hi.baidu.com/combojiang/blog/item/efb56e8ff0ebbfebf11f3654.html

利用Win32 Debug API打造自己的Debugger: http://hi.baidu.com/olhack/blog/item/c1e896508250e86284352407.html

The Debugging Application Programming Interface: http://msdn.microsoft.com/en-us/library/ms809754.aspx

在主进程中捕获子进程的异常:http://blog.csdn.net/simbi/article/details/3705719

Windows Debugging API: http://my.safaribooksonline.com/book/networking/intrusion-detection/9780321446114/in-memory-fuzzing-automation/ch20lev1sec3

原文地址:https://www.cnblogs.com/gomen/p/3506196.html