Ctrl-C not handled at least in 64bits

Started by jullien, March 10, 2015, 05:46:26 PM

Previous topic - Next topic

jullien

The following code (compiled with RC8):
#include <stdio.h>
#include <signal.h>

void sig_handler(int signo)
{
  if (signo == SIGINT)
    printf("received SIGINT\n");
}

int main(void)
{
  if (signal(SIGINT, sig_handler) == SIG_ERR) {
    printf("\ncan't catch SIGINT\n");
  } else {
    int i;
    for (i = 0; i < 100; ++i)
      fgetc(stdin);
  }
  return 0;
}


Compiled with:
        cc -c -Ze -Zx -Gz -W0 -Go -Tamd64-coff bug.c
        polink  /out:bug.exe bug.obj

Should handle SIGINT and print "received SIGNIT" at it is the case with all C compiler (including VC++ and gcc).

It prints nothing and exit immediately

jullien

Hi,

No comment on this? It prevents Pelles C to be used to compile interpreters and script languages.
If a user writes a script code that enters an infinite loop or takes to long to execute, Ctrl-C exists the interpreter instead of returning to toplevel loop or entering to debugger.

There's no possible workaround.

Snowman

I cannot explain the problem, but it seems to be caused by your loop.
The following code seems to work correctly. I hope more experienced members will join this thread.

#include <stdio.h>
#include <signal.h>

void sig_handler(int signo)
{
  if (signo == SIGINT)
    fprintf(stderr, "received SIGINT\n");

  exit(1);
}

int main(void)
{
  if (signal(SIGINT, sig_handler) == SIG_ERR) {
    printf("\ncan't catch SIGINT\n");
  } else {
    while (1);
  }

  return 0;
}



jullien

It may be also related to I/O operations.
Here is the same sample without loop which is also unable to catch signal.


#include <stdio.h>
#include <signal.h>

void sig_handler(int signo)
{
  if (signo == SIGINT)
    printf("received SIGINT\n");
}

int main(void)
{
  if (signal(SIGINT, sig_handler) == SIG_ERR) {
    printf("\ncan't catch SIGINT\n");
  } else {
    fgetc(stdin);
  }
  return 0;
}


Snowman

I can confirm that this bug is also present on 32-bit Pelles C 8.00.60.

aardvajk

It might not do what the rest do, but it doesn't actually have to.

The C99 standard, (since I don't have access anything more current) section 7.14 says:
QuoteAn implementation need not generate any [...] signals, except as a result of explicit calls to the raise function.
e.g. it doesn't have to call any signal handlers unless you tell it to manually
QuoteThe complete set of signals, their semantics, and their default handling is implementation-defined
e.g. It doesn't have to even know what SIG_INT is, and if it does, it doesn't have to be Ctrl-C that causes it

So it 'not working' might be intentional.

jullien

Ctrl-C sending SIGINT
- it used to work with Pelles C
- it works with all Windows C I use (cl, gcc, TinyCC, Watcom, IBM VisualAge, dmc, Borland, LCC)
- it works with any combination of C compiler/processor/OS un*x I use (I use *many* of them).
- it even works with Pelles C if I don't call fgetc() (i.e. Pelles C sends SIGINT and correctly catches this signal when I press Ctrl-C)

TimoVJL

#7
last example works in Win 8.1 x64 32-bit and 64-bit single/multi-threaded lib and with multithreaded DLL.
May the source be with you

jullien

New test:
I compiled version doing:

  if (signal(SIGINT, sig_handler) == SIG_ERR) {
    printf("\ncan't catch SIGINT\n");
  } else {
    fgetc(stdin);
  }

On Windows 7 x64 and it does not catch signal as I said.
However, the exact same binary works on Windows 8.1 x64!
Very strange. No clue atm.

TimoVJL

#9
Last example.
In Win7 x64 both versions catch signal, but doesn't print that "received SIGINT" allways. Is it buffering problem?
May the source be with you

jullien

This of course a simplified test.
On my real program (which is a lisp toplevel shell), it hangs with GPF and returns to Windows command prompt.

Btw, I just ran my latest test on Windows 10 build 10041 x64 and signal is not handled.
Windows 8.1 x64 is the only version that does the right job but I only made this test on a VMware virtual machine. Other tests are done on a real x64 hardware.