Skip to content

setproctitle does not work together with systemd socket support #3430

@sigprof

Description

@sigprof

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:
    pass

In 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)?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions