SIGINT and SIGTSTP ignored by most common applications

2

After the last upgrade to my Fedora, a strange behaviour started occurring in X terminal applications. I can't seem to stop any process using Ctrl+C, it just results in printing ^C to the console. Similarly, Ctrl+Z prints ^Z and the process goes on. Both work well in non-graphical virtual consoles.

I checked stty -a and it seems perfectly normal:

speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?;
swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

This is independent of the terminal (gnome-terminal, XFCE4 terminal, xterm). I later noticed that it may not be caused by the terminal at all: INT or TSTP sent directly to the respective process are ignored, too. This comprises various applications I used to terminate using Ctrl+C on a regular basis (and which often don't have any better means of exiting): cat, find, tail -f, java, ping, mplayer when stuck on a broken file...

Even bash ignores Ctrl+C when I want to break a command line I have been entering and then changed my mind (no ^C is printed in this case). I need to delete it character by character (of which there may be hundreds if filename completion has been used) or intentionally run the unwanted command. Strangely enough, vim does recognize Ctrl+C — just to say its "use :quit", of course.

This is extremely annoying and prevents me from working efficiently. Everything had been working until lately, maybe a week ago or so. I can not find any possible causes in Google, perhaps I'm trying wrong search terms or misidentifying the main problem. What could be it and how could I revert the standard behaviour, please?

Update

Ctrl+Z works sometimes. It seems that in the very first terminal I launch after logging in it stops the running command but stops working after that.

The Vee

Posted 2013-10-30T13:27:19.787

Reputation: 170

If you ssh to localhost, does it work then? THen something in the path from init to your terminal sets SIGINT and SIGTSTP to SIG_IGN. You said you tried Gnome, so now I think the suspect is your xdm, gdm or whatever you use. – fstx – 2013-10-31T05:55:19.347

(c0dev, now this does not appear in my answer list, so I can't check there to see what happens to this question) – fstx – 2013-10-31T06:07:09.930

@fstx ssh to localhost works, wow! I'll try to replace the desktop manager but I guess that will take a while to figure out. Thanks! – The Vee – 2013-11-04T12:16:47.343

It is a bug. Report it and it will be fixed. If not, your distro is dead and you will need to change anyway. – fstx – 2013-11-05T08:24:08.033

@fstx Fedora project is perfectly well alive. I'm just afraid the error may be specific to my install and irreplicable. There are too many users not to have noticed this earlier if it affected everyone. Anyway I'll give it a try, thanks! – The Vee – 2013-11-05T14:08:38.390

Answers

1

I would suspect your desktop environment. Which do you use?

NEW answer.

Something on the path from init to your shell sets SIGINT and SIGTSTP to be ignored. This is eventually inherited by your shell. You can use this small program to spawn any program with the signals reset to default.

#include <signal.h>

int main(int argc, char **argv)
{
    signal(SIGTSTP, SIG_DFL);
    signal(SIGINT, SIG_DFL);
    execvp(argv[1], argv+1);
}

fstx

Posted 2013-10-30T13:27:19.787

Reputation: 932

XFCE4 with Compiz. I did check both of them for the extremely unlikely but possible keyboard shortcut collisions. – The Vee – 2013-10-30T13:50:28.247

Just tried relogging with Gnome, no difference. – The Vee – 2013-10-30T13:53:55.993

1This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – Christian – 2013-10-30T14:08:30.420

@fstx Thank you for the update! Strangely enough, your solution does not work for me—the error cause must be elsewhere! – The Vee – 2013-11-05T14:03:47.443

You use it like this: ./sigfix bash – fstx – 2013-11-05T14:23:22.397

1It could be that the signal is blocked using sigprocmask(2) – fstx – 2013-11-06T09:09:14.910

You are right! Using sigprocmask() instead of signal() in your snippet for unblocking the full set does the trick. I wonder what in the way sets the block wrong, and how to prevent that. But I guess I'll just end up finding a way to force this at every invocation of bash for now. – The Vee – 2013-11-10T21:28:01.147

So very strange, according to my trace of the PPid line in the \proc tree for SigBlk the blocked set changes at the point of the terminal emulator, regardless of whether compiz or sshd is its parent but equally regardless of the particular emulator being used. I'm puzzled. – The Vee – 2013-11-10T21:37:43.133

I had not seen those flags in /proc/pid/status before. Now I've learnt two things from this question. I thought blocking signals was something you did for a short time to ensure mutual exclusion to data that signal handlers access. But if a process would want to block signals for itself (but not its children), it should unblock them between fork and exec. – fstx – 2013-11-13T13:06:22.083

If compiz manipulates the mask, and provides the wrong mask for its children, you have (almost surely) found the culprit. – fstx – 2013-11-13T13:08:56.783

@fstx Finally I can upvote :-) Thanks again for all the help! If I have time, I'll check whether there's anything suspicious in compiz code. But even an ssh-launched Terminal (thus having no compiz in its "pedigree") shows that issue. I'm not sure if it technically is a child of compiz, just reparented – it does not seem so. – The Vee – 2013-11-14T13:52:53.580

0

For anyone who might face the same problem:

I have employed a variation of fstx's solution and it works well for me in all cases (nested logins, SSH, ...) right now.

A little utility needed to be written in C, compiled and put somewhere in the $PATH:

sig.c

#include <signal.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    sigset_t mask;
    sigfillset(&mask);
    sigprocmask(SIG_UNBLOCK, &mask, NULL);
    return execvp(argv[1], argv+1);
}

Then this little check in the very beginning of .bashrc ensures that no signals are blocked:

if ( grep SigBlk /proc/self/status | grep -qv 00000 )
then
    exec sig $0 $@
fi

The Vee

Posted 2013-10-30T13:27:19.787

Reputation: 170

0

Here's workaround similar to those already provided. It doesn't require you to compile a special program, so some people may find it more convenient.

exec ksh -c 'exec $SHELL'

Install ksh with yum install ksh if you don't have it already.

mavit

Posted 2013-10-30T13:27:19.787

Reputation: 541