I am trying to initialize a daemon using daemon context, but when I try to initialize the daemon it crashes (even in pdb. No exception, no catch, just crash. The interpreter goes down to.)
Steps to reproduce. Initialize pipenv with pipfile. Start Ipython. import stripped_daemon import pdb args=["thing","start"] pdb.run('stripped_daemon.main(args)') c
Stepping into the script I can determine the line that breaks is with context: Following until the exact line that breaks, it is
with context:
stripped_daemon:40 daemon.py:397 daemon.py:382 (close_all_open_files(exclude=exclude_fds)) daemon.py:869 (close_file_descriptor_if_open(fd))
The crash occurs at the last iterator of the loop. This happens when fd==1.
My script https://paste.fedoraproject.org/paste/KNbU4q7x4~6200ycqUkn0g My Pipfile https://paste.fedoraproject.org/paste/owApbrrBe0eXZW1HPKzkcg
Thanks for the bug report. Some questions to diagnose further:
On 31-Jul-2018, Jason Stock wrote:
Steps to reproduce. Initialize pipenv with pipfile.
Does this occur when you instead write a script that only needs =E2=80=98python-daemon=E2=80=99 (i.e. that does not need a pip configuratio= n)?
Start Ipython.
Why is this part of the reproduction steps? I would expect that a daemon process would no longer communicate with IPython, unless you make some special means for them to communicate.
Can you instead make the reproduction steps involve only running the script directly?
import stripped_daemon
Can you attach the (minimal) example script here on this bug report, to ensure it stays with the discussion for later?
Stepping into the script I can determine the line that breaks is with co= ntext: Following until the exact line that breaks, it is=20 stripped_daemon:40 daemon.py:397 daemon.py:382 (close_all_open_files(exclude=3Dexclude_fds)) daemon.py:869 (close_file_descriptor_if_open(fd))
with co= ntext:
stripped_daemon:40 daemon.py:397 daemon.py:382 (close_all_open_files(exclude=3Dexclude_fds)) daemon.py:869 (close_file_descriptor_if_open(fd))
Yes. Closing file descriptors is necessary to detach the daemon process from its initial parent. This includes detaching the standard streams from the parent process, because that's part of how a daemon process gains independence from the parent which started it.
This means, of course, that if you want to have a daemon continue communicating with the system, it needs to arrange that communication separately from any connection through its parent process.
I look forward to seeing a minimal script that can run directly, and demonstrate the behaviour, that you attach to this bug report.
--=20 \ =E2=80=9CMy doctor told me to stop having intimate dinners for fo= ur. | `\ Unless there are three other people.=E2=80=9D =E2=80=94O= rson Welles | _o__) | Ben Finney ben@benfinney.id.au
Thanks for your reply.
I have been exclusively trying to test this daemon in ipython as I am still developing the code. I did not expect it to detach until the end of the action it was asked to do. I believe it is very possible that this bug is in fact just my own misunderstanding of the workflow of python-daemon.
I must run this in a pip virtualenv. The system policy for the machine I am building this for requires that all built python code be run in a pip virutalenv. (In short, I am unable to test the behaviour of this script without pipenv, so I cannot guarantee that the issue does or doesn't occur. I also provide the Pipfile to make sure that the environment I am using is easily duplicated.).
It does not need to be run in ipython. I did so to try and debug another issue. I found myself entirely unable to debug anything started through the daemon because the process died (or, as now appears more likely simply detached as planned) before I could observe the action being executed with pdb. I do set detach_process to false though. Should it still be detaching itself?
#''' #author: JStock # Stripped down version of my daemon initializer to reproduce the error with minimal code. #''' import daemon import lockfile def p_do(): print("This is a dummy function to hold place for reporting to python-daemon.") bdir='/tmp/' pidfile=bdir+"/stock.pid" context = daemon.DaemonContext( working_directory=bdir, umask=0o022, pidfile=lockfile.FileLock(''), detach_process=False ) def main(args): print("args is:", args) print("len(args): ",len(args)) #Error happens here, during `with context` with context: print("In context.") if len(args)==2: print("Checking commands") com=args[1] if 'start'==com: context.open() p_do else: #Uknown command here print("Message will go here") else: #Show usage here print("Message will go here") if __name__=="__main__": main(sys.argv)
See the specification that the library is designed to implement: PEP 3143 , in particular the specification for the DaemonContext.open method.
DaemonContext.open
I do set detach_process to false though. Should it still be detaching itself?
Before concluding what's happening, you could try getting the program to write diagnostic messages somewhere and see where it gets to before stopping.
Make sure to include that log file in files_preserve.
files_preserve
--=20 \ =E2=80=9CTrue greatness is measured by how much freedom you give= to | `\ others, not by how much you can coerce others to do what you | _o__) want.=E2=80=9D =E2=80= =94Larry Wall | Ben Finney ben@benfinney.id.au
In the absence of more diagnostic information, I am closing this bug report.
If this behaviour can be reproduced, please feel free to open a new bug report.
Metadata Update from @bignose: - Issue close_status updated to: Insufficient data - Issue status updated to: Closed (was: Open)