Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
795 views
in Technique[技术] by (71.8m points)

c - Receiving SIGINT and exception Handles in Linux

Let's say we have a program in C that uses the sleep() function

The program executes and goes to sleep. Then we type Ctrl+C to send a SIGINT signal to the process.

We know that the default action upon receipt of a SIGINT is to terminate the process, we also know that the sleep() function resume the process whenever the sleeping process receives a signal.

And my textbook says in order to allow sleep() function to return, we must install a SIGINT handler like this:

void handler(int sig){
    return; /* Catch the signal and return */
}
...
int main(int argc, char **argv) {
   ...
   if (signal(SIGINT, handler) == SIG_ERR) /* Install SIGINT handler */
      unix_error("signal error
");
   ...
   sleep(1000)
}

Althouth the code seems to be straightforward, I still have questions if I want to dig deeper:

Background: When the process is sleeping and we type Ctrl+C to send SIGINT

Q1-My understanding is, Kernel sends SIGINT to the process by updating the SIGINT's corresponging pending bit in the pend bit vector, is my understanding correct?

Q2-The processor detects the existance of SIGINT, but since we overwrite the handler to make it return in stead of terminating the process, so our handler get executed, and then Kernel clears SIGINT's corresponging pending bit, is my understanding correct?

Q3- Since SIGINT's corresponging pending bit is cleared, then how can sleep() function gets return? I think it should be in sleep still because in theory, sleep() function has no way of knowing the existance of SIGINT(has been cleared)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Q3- Since SIGINT's corresponging pending bit is cleared, then how can sleep() function gets return?

Imagine the sleep() function in the kernel as a function that:

  • allocates and sets fields in some kind of "timer event" structure
  • adds the "timer event" to a list of timer events for the timer's IRQ handler to worry about later (when the expiry time has elapsed)
  • moves the task from the "RUNNING" state to the "SLEEPING" state (so the scheduler knows not to give the task CPU time), causing scheduler to do a task switch to some other task
  • configures return parameters for user-space (the amount of time remaining or 0 if the time expired)
  • figures out why the scheduler gave it CPU time again (did the time expire or was the sleep interrupted by a signal?)
  • potentially mangles the stack a bit (so that the kernel returns to the signal handler if the sleep() was interrupted by a signal instead of returning to the code that called sleep())
  • returns to user-space

Also imagine that there's a second function (that I'm going to call wake() for no particular reason) that:

  • removes the "timer event" from the list of timer events (for the timer's IRQ handler to worry)
  • moves the task from the "SLEEPING" state to the "READY TO RUN" state (so the scheduler knows that the task can be given CPU time again)

Naturally, if the timer's IRQ handler notices that the "timer event" has expired then the timer's IRQ handler would call the wake() function to wake the task up again.

Now imagine there's a third function (that I'm going to call send_signal()) which might be called by other functions (e.g. called by kill()). This function might set a "pending signal" flag for the task that's supposed to receive the signal, then check what state the receiving task is in; and if the receiving task is in the "SLEEPING" state it calls the wake() function to wake it up (and then lets the latter part of the sleep() function worry about delivering the signal back to user-space whenever the scheduler feels like giving the task CPU time later).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...