ros2 / launch

Tools for launching multiple processes and for writing tests involving multiple processes.
Apache License 2.0
126 stars 144 forks source link

`ExecuteProcess` with `shell=True` gets incorrect exit code from the executed process #757

Open azeey opened 10 months ago

azeey commented 10 months ago

Bug report

Required Info:

Steps to reproduce issue

Create test.py

import time
import sys

try:
    time.sleep(100)
except KeyboardInterrupt:
    print("Exiting due to interrupt")
    sys.exit(0)

In the same directory, create test.launch.py

from launch import LaunchDescription
from launch.actions import ExecuteProcess

def generate_launch_description():
    return LaunchDescription([
        ExecuteProcess(
            cmd=['python3', './test.py'],
            shell=True,
            output='screen',
        )
    ])

Run ros2 launch test.launch.py. After a few seconds, type Ctrl-C.

Expected behavior

The test.py process to exit cleanly.

Actual behavior

It shows an error saying the process has died

[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [python3-1]: process started with pid [1524803]
^C[WARNING] [launch]: user interrupted with ctrl-c (SIGINT)
[python3-1] Exiting due to interrupt
[ERROR] [python3-1]: process has died [pid 1524803, exit code -2, cmd 'python3 ./test.py'].

Additional information

Running python3 test.py itself and interrupting with Ctrl-c results in a 0 exit code, so it's not clear why the behavior is different when run through launch. This also only happens if shell=True. When shell=False or omitted, I get

[INFO] [python3-1]: process started with pid [1524563]
^C[WARNING] [launch]: user interrupted with ctrl-c (SIGINT)
[python3-1] Exiting due to interrupt
[INFO] [python3-1]: process has finished cleanly [pid 1524563]
Mildred34 commented 9 months ago

Hello, I've come to a Bug that looks related to yours.

Required Info:

If I take the same example as you when I run the launch file with shell=True. In another terminal, I run the following command:

ps -aux | pgrep -f test.py

I can see two pid, as if the process was launched twice.

user      159666  0.0  0.0   2896  1600 pts/0    S+   09:22   0:00 /bin/sh -c python3 ./test.py
user      159668  0.2  0.0  22608  9440 pts/0    S+   09:22   0:00 python3 ./test.py

Maybe it's totally normal, but the thing is when I called that same launch through another launch file (that I will call main.launch.py) where I add :

    event_handlers.append(
        RegisterEventHandler(
            event_handler=OnProcessExit(
                target_action=onenode,
                on_exit=[EmitEvent(event=Shutdown())],
            )
        )
    )

That allows me to shutdown all the process launched by main.launch.py whenever one particular node is shutting down

Expected behavior The test.py process to exit cleanly.

Actual behavior Only the command /bin/sh -c python3 ./test.py is killed not the command launched by the shell: python3 ./test.py.

If you don't think that is related, i will ask in another ticket.

BR,

Alexis

azeey commented 5 months ago

It looks like the signal is actually not propagated to the subprocess properly. This might actually be the root cause of the problem.