-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Using gunicorn 23.0.0 on Linux with systemd service+socket unit setup similar to the one described in docs, I found that the setproctitle support does not work (ps still shows full command lines). After adding SPT_DEBUG=1 to the environment, I see the following in the errorlog file:
[2025-10-21 16:14:46 +0300] [8803] [INFO] Starting gunicorn 23.0.0
[2025-10-21 16:14:46 +0300] [8803] [INFO] Listening at: unix:/run/REDACTED.sock (8803)
[2025-10-21 16:14:46 +0300] [8803] [INFO] Using worker: sync
[SPT]: reading argc/argv from Python main
[SPT]: found 4 arguments
[SPT]: walking from environ to look for the arguments
[SPT]: found environ at 0x7ffc84a43d16
[SPT]: found argv[3] at 0x7ffc84a43d09: LISTEN_FDS=1
[SPT]: found argv[2] at 0x7ffc84a43cdc: /REDACTED/gunicorn.conf.py
[SPT]: found argv[1] at 0x7ffc84a43cd9: -c
[SPT]: argv[0] should be at 0x7ffc84a43cc8
[SPT]: argv[0] '/REDACTED/gunicorn' doesn't match '/usr/bin/python3'
[SPT]: couldn't find argv from environ
[SPT]: get_argc_argv failed
[SPT]: failed to initialize setproctitle
Apparently setproctitle starts looking for argv in a wrong place (it thinks that LISTEN_FDS=1 is the last item in argv when it's actually the first item in environ passed by systemd), therefore it does not find a proper argv[0] and fails.
The problem is probably caused by the environment manipulation in gunicorn.systemd.listen_fds() which happens before the first setproctitle() call — popping the first item in environ probably changes the environ pointer at the C level, breaking the setproctitle init code which runs at the first call and searches for argv[0] backwards from environ. So it looks like all environ changes before the first call to setproctitle() need to be avoided.
I have been able to find a workaround — adding the following piece of code to gunicorn.conf.py makes setproctitle work again:
try:
from setproctitle import setproctitle
setproctitle("gunicorn: init")
except Exception:
passIn this case the initialization of setproctitle happens before the environ change, and subsequent calls to setproctitle() can work properly. The SPT_DEBUG=1 info now gets captured in the systemd journal (timestamp and hostname fields trimmed):
systemd[1]: Starting [email protected] - gunicorn@REDACTED daemon...
start-gunicorn[8858]: [SPT]: module init
start-gunicorn[8858]: [SPT]: reading argc/argv from Python main
start-gunicorn[8858]: [SPT]: found 4 arguments
start-gunicorn[8858]: [SPT]: walking from environ to look for the arguments
start-gunicorn[8858]: [SPT]: found environ at 0x7fff79b6cd09
start-gunicorn[8858]: [SPT]: found argv[3] at 0x7fff79b6ccdc: /REDACTED/gunicorn.conf.py
start-gunicorn[8858]: [SPT]: found argv[2] at 0x7fff79b6ccd9: -c
start-gunicorn[8858]: [SPT]: found argv[1] at 0x7fff79b6ccc7: /REDACTED/gunicorn
start-gunicorn[8858]: [SPT]: argv[0] should be at 0x7fff79b6ccb6
start-gunicorn[8858]: [SPT]: found argv[0]: /usr/bin/python3
systemd[1]: Started [email protected] - gunicorn@REDACTED daemon.
Should gunicorn itself have a workaround for this problem (calling setproctitle() early enough, so that it has a chance to init properly)?