Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't stop debugger on signals #7546

Closed
Leadwerks opened this issue May 18, 2021 · 1 comment
Closed

Don't stop debugger on signals #7546

Leadwerks opened this issue May 18, 2021 · 1 comment

Comments

@Leadwerks
Copy link

Leadwerks commented May 18, 2021

Bug type: Debugger

I am implementing a timer in Linux. Every time a timer tick occurs the Debug Console prints a message saying "Program received signal SIG34..." and the debugger tries to stop on recvmsg.c, a file that does not exist on this machine. I think by default GDB must be stopping on all signals, which I definitely don't want when a timer is emitting signals at a regular interval. This makes working with the program impossible.

  • OS and Version: Ubuntu 20.04 64-bit running in Hyper-V.
  • VS Code Version:- C/C++ Extension Version: VSCode 1.56.2, C/C++ extension version 1.3.1
  • Other extensions you installed (and if the issue persists after disabling them): None

To Reproduce
Steps to reproduce the behavior: Run the code sample in the debugger.

#include <stdint.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <stdio.h>
       #include <signal.h>
       #include <time.h>

       #define CLOCKID CLOCK_REALTIME
       #define SIG SIGRTMIN
       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)

       static void
       print_siginfo(siginfo_t *si)
       {
           timer_t *tidp;
           int orr;

           tidp = (timer_t*)si->si_value.sival_ptr;

           printf("    sival_ptr = %p; ", si->si_value.sival_ptr);
           printf("    *sival_ptr = %#jx\n", (uintmax_t) *tidp);

           orr = timer_getoverrun(*tidp);
           if (orr == -1)
               errExit("timer_getoverrun");
           else
               printf("    overrun count = %d\n", orr);
       }

       static void
       handler(int sig, siginfo_t *si, void *uc)
       {
           /* Note: calling printf() from a signal handler is not safe
              (and should not be done in production programs), since
              printf() is not async-signal-safe; see signal-safety(7).
              Nevertheless, we use printf() here as a simple way of
              showing that the handler was called. */

           printf("Caught signal %d\n", sig);
           print_siginfo(si);
           signal(sig, SIG_IGN);
       }

       int main(int argc, char *argv[])
       {
            long long msecs = 500;

           timer_t timerid;
           struct sigevent sev;
           struct itimerspec its;
           long long freq_nanosecs;
           sigset_t mask;
           struct sigaction sa;

           /* Establish handler for timer signal. */

           printf("Establishing handler for signal %d\n", SIG);
           sa.sa_flags = SA_SIGINFO;
           sa.sa_sigaction = handler;
           sigemptyset(&sa.sa_mask);
           if (sigaction(SIG, &sa, NULL) == -1)
               errExit("sigaction");

           /* Block timer signal temporarily. */

           printf("Blocking signal %d\n", SIG);
           sigemptyset(&mask);
           sigaddset(&mask, SIG);
           if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)
               errExit("sigprocmask");

           /* Create the timer. */

           sev.sigev_notify = SIGEV_SIGNAL;
           sev.sigev_signo = SIG;
           sev.sigev_value.sival_ptr = &timerid;
           if (timer_create(CLOCKID, &sev, &timerid) == -1)
               errExit("timer_create");

           printf("timer ID is %#jx\n", (uintmax_t) timerid);

           /* Start the timer. */

           freq_nanosecs = msecs * 1000000;
           its.it_value.tv_sec = freq_nanosecs / 1000000000;
           its.it_value.tv_nsec = freq_nanosecs % 1000000000;
           its.it_interval.tv_sec = its.it_value.tv_sec;
           its.it_interval.tv_nsec = its.it_value.tv_nsec;

           if (timer_settime(timerid, 0, &its, NULL) == -1)
                errExit("timer_settime");

           /* Sleep for a while; meanwhile, the timer may expire
              multiple times. */

           printf("Sleeping for 5 seconds\n");
           sleep(5);

           /* Unlock the timer signal, so that timer notification
              can be delivered. */

           printf("Unblocking signal %d\n", SIG);
           if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
               errExit("sigprocmask");

           exit(EXIT_SUCCESS);
       }
@Leadwerks
Copy link
Author

Here is the solution:

  • Create a file named ".gdbinit" in the home directory.
  • Place this text in the file, without quotes: "handle SIG34 nostop noprint pass"

@github-actions github-actions bot locked and limited conversation to collaborators Jul 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant