undetected-chromedriver icon indicating copy to clipboard operation
undetected-chromedriver copied to clipboard

driver.quit doesnt work correctly and leaves zombie process

Open Sleeeepy7 opened this issue 1 year ago • 4 comments

I use django and celery task for execution UC, its start about 150-200 times a day, and each chrome leaves a zombie process. Does anyone know how to solve this problem? :(

Sleeeepy7 avatar Dec 24 '23 17:12 Sleeeepy7

I tried:

import subprocess

def kill_chrome_processes():
    # commands for delete Chrome и chromedriver
    for process_name in ['chrome', 'undetecte', 'undetected_chro', 'chromedriver']:
        try:
            subprocess.run(['pkill', '-f', process_name], check=True)
        except subprocess.CalledProcessError as e:
            print(f"Exception with a process {process_name}: {e}")

    print("Done")
def kill_zombie_processes():
    try:
        # Getting all zombie processes (with name = 'Z' (zombie) )
        zombies = subprocess.check_output(["ps", "-eo", "pid=,stat="]).decode().splitlines()
        zombie_pids = [line.split()[0] for line in zombies if 'Z' in line.split()[1]]

        for pid in zombie_pids:
            # trying to delete zombie process
            parent_pid = subprocess.check_output(["ps", "-o", "ppid=", "-p", pid]).decode().strip()
            subprocess.run(["kill", "-s", "SIGCHLD", parent_pid])
            print(f"Signal SIGCHLD were send to parent of zombie process with PID {parent_pid}.")

    except subprocess.CalledProcessError as e:
        print(f"Exception: {e}")

but that methods doesnt solve my problem, it still leaves zombie processes

Sleeeepy7 avatar Dec 24 '23 17:12 Sleeeepy7

Hey man, I had issues with zombie processes in the past while using uc and thought it was an issue with the library, but actually It was me not properly catching exceptions. Try implementing a try finally block to your code to see if the zombie processes go away.

If you are enabling cdp events, though, there actually is a bug when closing the driver and for that I use a custom function to close the drivers. In the code bellow I added both examples.

chrome_options = ChromeOptions()
driver= Chrome(
    options = chrome_options,
    enable_cdp_events=True
)
try:
    # do your stuff
    pass
finally:
    # close the driver
    if driver.reactor:
        while not driver.reactor.loop.is_closed():
            try:
                driver.reactor.loop.close()
            except:
                driver.reactor.event.set()
                time.sleep(0.5)
    driver.quit()

pedro-peixot0 avatar Dec 26 '23 13:12 pedro-peixot0

Hey man, I had issues with zombie processes in the past while using uc and thought it was an issue with the library, but actually It was me not properly catching exceptions. Try implementing a try finally block to your code to see if the zombie processes go away.

If you are enabling cdp events, though, there actually is a bug when closing the driver and for that I use a custom function to close the drivers. In the code bellow I added both examples.

chrome_options = ChromeOptions()
driver= Chrome(
    options = chrome_options,
    enable_cdp_events=True
)
try:
    # do your stuff
    pass
finally:
    # close the driver
    if driver.reactor:
        while not driver.reactor.loop.is_closed():
            try:
                driver.reactor.loop.close()
            except:
                driver.reactor.event.set()
                time.sleep(0.5)
        driver.quit()

you have saved my day. I've been struggling with this problem all day today and your code solved it perfectly. Thank you very much for your contribution

EDIT: Unfortunately, in the end the problem was not solved since with the proposed code the processes are not terminated, so they are effectively no longer zombies but they are still active and consuming resources, which eventually causes the memory to fill up and they cannot be created more instances

FRIKIdelTO avatar Jan 11 '24 16:01 FRIKIdelTO

Hey bro! I had same issue as you. I fixed it with this part of code: for proc in psutil.process_iter(['pid', 'name', 'cmdline', 'ppid']): if proc.info['name'] == 'chrome.exe': parent_pid = proc.info['ppid'] if not psutil.pid_exists(parent_pid): print(f"Stopping chrome.exe with PID {proc.info['pid']} (Parent PID {parent_pid} does not exist)") proc.kill() At the end of my script I trigger this part of code to close all chrome.exe processes that are without parent pid. Hope this will fix ur problem :)

frontenddevel0per avatar Apr 28 '24 17:04 frontenddevel0per