如何启动的子进程崩溃(很少)应用程序(How to launch crashing (rarely)

2019-08-04 07:48发布

我有一个需要执行专有应用(从时间到崩溃的时间),每天约20万次Python应用程序。

问题是,当应用程序崩溃时,Windows会自动触发WerFault这将让程序挂,从而Python的subprocess.call()将永远等待用户输入(即应用程序在假日,全天候在周末运行,......所以这是不能接受的)。

如果虽然关于使用sleep; poll; kill; terminate sleep; poll; kill; terminate sleep; poll; kill; terminate但这将意味着失去运用能力communicate()应用程序可以从几毫秒到2小时运行,所以设置固定超时将是无效的

我也试过接通自动调试 (使用一个脚本这将需要一个应用程序的崩溃转储和终止ID),但不知何故,这个HOWTO没有我的服务器上运行(WerFault仍出现并等待用户输入)。

其他几个教程像这样没有采取任何效力,要么。

:有没有办法如何防止WerFault从显示(等待用户输入)? 这是更多的系统那么编程问题

另类的问题 :有没有在Python 优雅的方式如何检测应用程序崩溃(WerFault是否被显示)

Answer 1:

简单(丑)的答案,监控WerFault.exe情况下不时,特别是与相关的一个PID问题的应用程序中。 把它杀了。 与处理WerFault.exe是复杂的,但你不希望禁用它-看到Windows错误报告服务。

  1. 获取的名字匹配的进程列表WerFault.exe 。 我用psutil包。 小心psutil因为过程缓存,使用psutil.get_pid_list()
  2. 通过使用解码其命令行argparse 。 这可能是矫枉过正,但它利用现有的Python库。
  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函数调用taskkill与正确条命令PID

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())


Answer 2:

我看不出有什么理由,为什么你的程序需要崩溃,找到有问题的代码,并把它变成一个try语句。

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



文章来源: How to launch crashing (rarely) application in subprocess