2012-12-19 3 views
5

나는 하루 20,000 회 정도의 시간이 소요되는 독점 어플리케이션을 실행해야하는 파이썬 어플리케이션을 가지고있다. 응용 프로그램 충돌이, Windows가 자동으로 프로그램에 매달려 계속됩니다 WerFault는, 따라서 python's subprocess.call() 해당 응용 프로그램이 공휴일, 24에, 주말에 실행할 수있다 (사용자 입력을 영원히 대기 트리거 할 때서브 프로세스에서 크래시 (드물게) 어플리케이션을 시작하는 방법

문제는 그래서 이것은 ...입니다 받아 드릴 수없는).

sleep; poll; kill; terminate를 사용하지만이 communicate()를 사용하는 능력을 잃고 의미에 대해, 응용 프로그램이 2 시간 몇 밀리 초에서 실행할 수 있지만, 그래서 고정 설정을 제한 시간 (어느 것 스크립트를 사용

가 나는 또한 turning on automatic debugging을 시도 효과가 없을 경우

응용 프로그램의 크래시 덤프 걸리고 ID 종료)하지만 어떻게 든이 howto 내 서버에서 작동하지 않습니다 (WerFault 여전히 나타나고 사용자 입력을 기다리는).

this과 같은 몇 가지 다른 자습서도 효과가 없습니다.

질문 : WerFault가 표시되지 않도록하는 방법이 있습니다 (사용자 입력 대기 중)? 이 다음 질문을 프로그래밍 더 많은 시스템이다

대체 질문 : (WerFault가 표시되었는지 여부)

+0

wer 제외 목록에 충돌 응용 프로그램을 추가 한 다음 로컬 덤프에서 충돌 덤프를 사용할 수 있습니다. http://msdn.microsoft.com/en-us/library/windows/desktop/bb513617%28v=vs.85%29.aspx – nanda

+0

을 (를) 보았습니까? http://stackoverflow.com/questions/5069224/handling -subprocess-crash-in-windows – n611x007

답변

2

간단한 (못생긴) 대답, 수시로 WerFault.exe 인스턴스에 대한 잘못된 응용 프로그램의 PID과 관련된 특별히 하나를 모니터링 할 수 있습니다. 그리고 그것을 죽여라. WerFault.exe을 처리하는 것은 복잡하지만 사용을 원하지 않습니다. Windows Error Reporting 서비스를 참조하십시오.

  1. WerFault.exe과 일치하는 이름으로 프로세스 목록을 가져옵니다. 나는 psutil 패키지를 사용한다. 프로세스가 캐시되기 때문에 psutil과 조심하십시오. psutil.get_pid_list()을 사용하십시오.
  2. argparse을 사용하여 명령 줄을 디코딩합니다. 이것은 잔인 할 수도 있지만 기존의 파이썬 라이브러리를 활용합니다.
  3. PID에 따라 응용 프로그램을 보유하고있는 프로세스를 식별하십시오.

이것은 간단한 구현입니다.

def kill_proc_kidnapper(self, child_pid, kidnapper_name='WerFault.exe'): 
    """ 
    Look among all instances of 'WerFault.exe' process for an specific one 
    that took control of another faulting process. 
    When 'WerFault.exe' is launched it is specified the PID using -p argument: 

    'C:\\Windows\\SysWOW64\\WerFault.exe -u -p 5012 -s 68' 
          |    | 
          +-> kidnapper +-> child_pid 

    Function uses `argparse` to properly decode process command line and get 
    PID. If PID matches `child_pid` then we have found the correct parent 
    process and can kill it. 
    """ 
    parser = argparse.ArgumentParser() 
    parser.add_argument('-u', action='store_false', help='User name') 
    parser.add_argument('-p', type=int, help='Process ID') 
    parser.add_argument('-s', help='??') 

    kidnapper_p = None 
    child_p = None 

    for proc in psutil.get_pid_list(): 
     if kidnapper_name in proc.name: 
      args, unknown_args = parser.parse_known_args(proc.cmdline) 
      print proc.name, proc.cmdline 

      if args.p == child_pid: 
       # We found the kidnapper, aim. 
       print 'kidnapper found: {0}'.format(proc.pid) 
       kidnapper_p = proc 

    if psutil.pid_exists(child_pid): 
     child_p = psutil.Process(child_pid) 

    if kidnapper_p and child_pid: 
     print 'Killing "{0}" ({1}) that kidnapped "{2}" ({3})'.format(
      kidnapper_p.name, kidnapper_p.pid, child_p.name, child_p.pid) 
     self.taskkill(kidnapper_p.pid) 
     return 1 
    else: 
     if not kidnapper_p: 
      print 'Kidnapper process "{0}" not found'.format(kidnapper_name) 
     if not child_p: 
      print 'Child process "({0})" not found'.format(child_pid) 

    return 0 

지금, taskkill 기능은 올바른 PIDtaskkill Section 명령을 호출합니다.

def taskkill(self, pid): 
    """ 
    Kill task and entire process tree for this process 
    """ 
    print('Task kill for PID {0}'.format(pid)) 
    cmd = 'taskkill /f /t /pid {0}'.format(pid) 
    subprocess.call(cmd.split()) 
+1

아주 좋은 첫 번째 대답 :) 나는 기본적으로 이미 이와 같은 것을하고 있지만 프로세스를 죽이는 대신 관리자에게 nagios를 통해 알리고 있으므로 크래시 덤프를 만들 수 있습니다. – Vyktor

-2

나는에 관해서는 이유를 볼 응용 프로그램 충돌을 감지하는 방법을 파이썬에서 우아한 방법이 왜 프로그램이 충돌을 일으켜 코드 조각을 찾아서 try-statement에 넣어야하는지.

http://docs.python.org/3.2/tutorial/errors.html#handling-exceptions

+0

문제는 독점 응용 프로그램이 충돌하는 것입니다. 우리는 그것에 대해 아무 것도 할 수 없습니다. (가난한 지원) : ( – Vyktor

+0

응용 프로그램이 충돌합니다. 그것은 사실입니다. 응용 프로그램이며 충돌을 수정할 수 있더라도 충돌을 처리하는 것이 일반적입니다.이 경우 타사 응용 프로그램입니다. –

관련 문제