mfussenegger / nvim-dap-python

An extension for nvim-dap, providing default configurations for python and methods to debug individual test methods or classes.
GNU General Public License v3.0
492 stars 46 forks source link

`os.fork` indefinitely waiting #124

Open neeldugar opened 5 months ago

neeldugar commented 5 months ago

Great project so far, but I've been having some difficulty in getting our project to work with forked processes.

Specifically the code below hangs indefinitely, was looking for any suggestions on what I can do to be able to debug it, even if both the child process isn't possible to get breakpoints within:

MRE:

import signal
import os

def signal_handler(signum, frame):
    try:
        pid, exit_code = os.waitpid(-1, os.WNOHANG)
    except Exception:
        return

    if os.WCOREDUMP(exit_code):
        raise Exception("Exception raised in child subprocess!")

    if os.WIFEXITED(exit_code):
        if os.WEXITSTATUS(exit_code) != 0:
            raise Exception("Child did not terminate with exit code 0!")

if __name__ == "__main__":
    pid = os.fork()
    signal.signal(signal.SIGCHLD, signal_handler)

    if pid > 0:
        print("I am parent process:")
        print("Process ID:", os.getpid())
        print("Child's process ID:", pid)
        status = os.wait()
        print(status)

    else:
        print("\nI am child process")
        print("Process ID:", os.getpid())
        print("Parent's process ID:", os.getppid())

Expected output:

I am parent process:
Process ID: XXXXX
Child's process ID: XXXXX

I am child process
Process ID: XXXXX
Parent's process ID: XXXXX
(XXXXX, 0)

Actual output:

I am parent process:
Process ID: XXXXX
Child's process ID: XXXXX
neeldugar commented 5 months ago

Also similarly using multiprocessing, the same issue persists, by looking at other issues this does seem to be resolved, so any help would be much appreciated:

from multiprocessing import Process
import os

def child():
    print("\nI am child process")
    print("Process ID:", os.getpid())
    print("Parent's process ID:", os.getppid())

def main():
    p = Process(target=child)
    p.start()
    print("I am parent process:")
    print("Process ID:", os.getpid())
    p.join()
    p.close()

if __name__ == "__main__":
    main()
mfussenegger commented 1 month ago

Just tried this and for me the examples work fine.

recording

Are you sure that both debugpy and nvim-dap are up2date and that you're using their default configurations?

The subProcess option must be true for this to work (that's the default for a while now)