Send Signal To Process - NOT received by process

Hi,

I am using robot framework(7.2.2) to start and stop my application, while running traffic tests with the SIPp binary.

Once I am done, I signal my application to shut down via

Send Signal To Process so that it sends SIGHUP and waits a while.

But the problem is, that in Ubuntu, running in either :

  • WSL
  • HyperV
  • VirtualBox

The signal is never received! If I instead, “more manually” trigger pkill -HUP <pid>, the signal is received fine.

The same code works fine with opensuse tumbleweed in WSL.

Can anyone give me any explanation for this?

I cant say i know what could be the reason but i did a brief googling and infact, you don’t seem to be the only one who has seen similar issue.

There was this SO post with the answer: c - Bash on Ubuntu on Windows: Signal handler does not work - Stack Overflow

And on accepted answer there’s a comment:

WSL implements Linux system calls from scratch. Apparently it’s less forgiving of invalid parameters in this case, i.e. failing to zero initialize the

And checking out SIPp code, it infact does not zero the structure: sipp/src/sipp.cpp at dde43e1a4c0a2747ca64b72664b7326d086e86b1 · SIPp/sipp · GitHub

I would at least try by adding following code to line 1188

memset( &action_quit, '\0', sizeof( action_quit ) );
memset( &action_file_size_exceeded, '\0', sizeof( action_file_size_exceeded ) );

and recompile sipp to rule out the issue mentioned in that SO post ..

Unfortunately, or, maybe even fortunately, I think I might be onto the cause of this, since I finally tested on an Ubuntu running in Libvirtd, and I get the same behavior.

The cause, I think, is the fact that when I check the process tree with pstree, on ubuntu, I can see that my application is started via sh, whereas on suse, its running directly under robot.

Since the signal is sent from robot to the shell, it will not propagate the signal to its child process.

The question now is, why does the same robot version, behavior differently on these OS:s.

What kw do you use to start the process ?

    ${ccm} =         Start Process        ${RunCommand} ${startParams}
    ...                                   shell=true  stdout=${LOG_PATH}/ccm_${TEST_NAME}.stdOut    stderr=${LOG_PATH}/ccm_${TEST_NAME}.stdErr

with shell=True, the main process definitely should be sh. Weird if Suse based wsl is not showing that. Can you verify if your suse has /bin/sh and if not, maybe symlink bash into it ? Another thing that would be interesting is that are you running robot inside WSL and if not, whats the value of ${RunCommand}

Anyway, for now, all i can help with is showing you this; robotframework-seleniumtestability/src/Helpers/__init__.py at master · MarketSquare/robotframework-seleniumtestability · GitHub

When i was working on seleniumtestability, i had to write this because i wasn’t able to kill all childprocesses (it was probably flask) on Windows and this caused hangs in test execution. Essentially that Die Die Die keyword will take a pid and forcefully kill a process and all of its child processes. Worth probably mentioning is that Jenkins has a hack that relates to similar issues. Jenkins “slave” sets a unique environment value - and when pipeline finishes, all the processes with env “X” is set to that unique value are killed.

Its native suse, nothing virtualized.

Normally, ${runCommand} just contains bin/ccm. And note that on SUSE, its not running via bash, its running directly under the robot fw process.

$> pstree -uh | grep -C3 ccm
|                 |-kglobalacceld---2*[{kglobalacceld}]
|                 |-konsole-+-bash-+-geany-+-bash
|                 |         |      |       `-5*[{geany}]
|                 |         |      `-robot-+-ccm---12*[{ccm}]
|                 |         |              |-python3
|                 |         |              `-2*[sipp]

Just in case someone else runs into this issue, and the reason you’re using shell=true, is because you’ve got a gazillion parameters inside various ${strings} (which makes in messy and complicated to supply them separately to Start Process)… I started using:

${ccmParamsAsList}=    Split Command Line   ${startParams}
${ccm} =         Start Process        ${RunCommand}   @{ccmParamsAsList}
...                                   stdout=${LOG_PATH}/ccm_${TEST_NAME}.stdOut    stderr=${LOG_PATH}/ccm_${TEST_NAME}.stdErr

Instead, which avoids the shell=True.