Що викликає надсилання різних сигналів?


28

Я іноді трохи заплутався у всіх сигналах, які може отримати процес. Як я розумію, процес має оброблювач за замовчуванням ( диспозиція сигналу ) для кожного з цих сигналів, але він може надати власний обробник за допомогою виклику sigaction().

Тож ось моє запитання: що викликає надсилання кожного з сигналів? Я розумію, що ви можете вручну надсилати сигнали запущеним процесам через -sпараметр kill, але які природні обставини, за яких ці сигнали надсилаються? Наприклад, коли вас SIGINTнадсилають?

Також чи існують обмеження щодо того, якими сигналами можна керувати? Чи можна навіть SIGSEGVобробляти сигнали та повертати контроль до програми?


Правильна відповідь на це буде епічною і в основному повторюватиме інформацію з цього питання у статті Вікіпедії , тому я просто зазначу.
Шон Дж. Гоф

@Shawn: У статті Вікіпедії є перелік сигналів, але чітке представлення того, хто надсилає сигнали.
Жил "ТАК - перестань бути злим"

Відповіді:


41

Окрім викликів процесів kill(2), деякі сигнали ядро (або іноді сам процес) надсилає ядро ​​за різних обставин:

  • Водії терміналів надсилають сигнали, що відповідають різним подіям:
    • Ключові повідомлення про натискання: SIGINT(поверніться до основного циклу) на Ctrl+ C, SIGQUIT(негайно вийдіть) на Ctrl+ \, SIGTSTP(призупиніть) на Ctrl+ Z. Клавіші можна змінити за допомогою sttyкоманди.
    • SIGTTINі SIGTTOUнадсилаються, коли фоновий процес намагається прочитати або записати на свій керуючий термінал.
    • SIGWINCH надсилається для сигналу про те, що розмір вікна терміналу змінився.
    • SIGHUPнадсилається сигнал про те , що термінал зник (історично , тому що ваш модем мав ч тичная вгору , в даний час , як правило , тому що ви закрили вікно емуляції терміналу).
  • Деякі процесорні пастки можуть генерувати сигнал. Деталі залежать від архітектури та системи; ось типові приклади:
    • SIGBUS для нерівномірної пам'яті доступу;
    • SIGSEGV для доступу до сторінки, що не має карти;
    • SIGILL за незаконну інструкцію (неправильний код);
    • SIGFPEдля інструкції з плаваючою комою з поганими аргументами (наприклад sqrt(-1)).
  • Ряд сигналів повідомляє цільовий процес про те, що сталася якась системна подія:
    • SIGALRMповідомляє про те, що встановлений процесом таймер закінчився. Таймери можуть бути встановлені з допомогою alarm, setitimerі інші.
    • SIGCHLD повідомляє про процес, що один з його дітей помер.
    • SIGPIPEгенерується, коли процес намагається записати в трубку, коли кінець читання закритий (ідея полягає в тому, що якщо запустити foo | barта barвийти, то fooвбивається a SIGPIPE).
    • SIGPOLL(також називається SIGIO) повідомляє процес, що відбулася подія, що запитується. POSIX вказує події, що запитуються, зареєстровані через I_SETSIG ioctl. Багато систем дозволяють полатируеми події на будь-якому дескрипторі файлів, встановленому через O_ASYNC fcntlпрапор. Пов'язаний сигнал - SIGURGце повідомлення про термінові дані на пристрої (зареєстрованому через I_SETSIG ioctl) або сокет .
    • У деяких системах SIGPWRнадсилається всім процесам, коли ДБЖ сигналізує про те, що неминуче припинення живлення .

Ці списки не є вичерпними. Стандартні сигнали визначені в signal.h.

Більшість сигналів додаток може вловлювати та обробляти (або ігнорувати). Єдині два портативних сигналу, які неможливо зловити, є SIGKILL(просто померти) та STOP(зупинити виконання).

SIGSEGV( помилка сегментації ) та його двоюрідного брата SIGBUS( помилка шини ) можна зловити, але це погана ідея, якщо ви дійсно не знаєте, що робите. Поширеним додатком для їх лову є друк сліду стека чи інша інформація про налагодження. Більш вдосконалене додаток - це реалізувати якесь управління пам’яттю під час роботи або вловлювати погані інструкції у двигунах віртуальної машини.

Нарешті, дозвольте згадати щось, що не є сигналом. Коли ви натискаєте Ctrl+ Dна початку рядка в програмі, яка зчитує вхід з терміналу, це повідомляє програмі, що кінець вхідного файлу досягнуто. Це не сигнал: він передається через вхід / вихід API. Як Ctrl+ Cі друзі, ключ можна налаштувати за допомогою stty.


І SIGHUP, ваш модем повісив трубку. :-)
Кіт

1
Ще одне, що слід зазначити: SIGFPEдещо ненавмисно, також подається сигнал про ціле число ділення на нуль, а іноді про підписане ціле число переповнення.
ефемієнт

18

Щоб відповісти на ваше друге запитання першим: SIGSTOPі програма SIGKILLне може бути спіймана, але кожен інший сигнал може навіть SIGSEGV. Це властивість корисно для налагодження - наприклад, за допомогою правильної підтримки бібліотеки ви можете слухати SIGSEGVта генерувати зворотній слід стека, щоб показати, де саме відбулося це сегментаріум.

Офіційне слово (так чи інакше для Linux) про те, що робить кожен сигнал, можна отримати, ввівши man 7 signalкомандний рядок Linux. http://linux.die.net/man/7/signal має ту саму інформацію, але таблиці важче читати.

Однак, не маючи досвіду сигналів, важко зрозуміти з коротких описів, що вони роблять на практиці, тому ось моя інтерпретація:

Запускається з клавіатури

  • SIGINTтрапляється при ударі CTRL+C.
  • SIGQUITспрацьовує CTRL+\і скидає ядро.
  • SIGTSTPпризупиняє програму при натисканні CTRL+Z. На відміну від цього SIGSTOP, він доступний для сприйняття, що дає такі програми, як viшанс повернути термінал у безпечний стан, перш ніж призупиняти себе.

Термінальні взаємодії

  • SIGHUP ("зависання") - це те, що відбувається, коли ви закриваєте xterm (або іншим чином відключаєте термінал) під час роботи програми.
  • SIGTTINі SIGTTOUпризупиніть свою програму, якщо вона намагається читати або записувати в термінал, поки вона працює у фоновому режимі. Для того, SIGTTOUщоб це сталося, я думаю, що програмі потрібно писати /dev/tty, а не лише типовим stdout.

Запускається виключенням із процесора

Це означає, що ваша програма намагалася зробити щось не так.

  • SIGILLозначає незаконну чи невідому інструкцію процесора. Це може статися, якщо ви, наприклад, спробували отримати доступ до портів вводу / виводу процесора безпосередньо.
  • SIGFPEозначає, що сталася помилка з апаратної математики; швидше за все, програма намагалася розділити на нуль.
  • SIGSEGV означає, що ваша програма намагалася отримати доступ до незробленої області пам'яті.
  • SIGBUSозначає, що програма якось іншим чином отримала доступ до пам'яті; Я не буду вникати в деталі цього резюме.

Процес взаємодії

  • SIGPIPEтрапляється, якщо ви спробуєте записати в трубку після того, як зчитувач труб закрив їх кінець. Див man 7 pipe.
  • SIGCHLDтрапляється, коли дочірній процес, який ви створили, або припиняється, або призупиняється ( SIGSTOPабо схожим).

Корисно для самосигналізації

  • SIGABRTзазвичай викликається програмою, яка викликає abort()функцію, і за замовчуванням викликає дамп ядра. Сортування "кнопки паніки".
  • SIGALRMвикликається alarm()системним викликом, який призведе до того, що ядро ​​доставить a SIGALRMпрограмі через задану кількість секунд. Дивіться man 2 alarmі man 2 sleep.
  • SIGUSR1і SIGUSR2використовуються, проте програма подобається. Вони можуть бути корисні для сигналізації між процесами.

Надіслано адміністратором

Ці сигнали зазвичай надсилаються з командного рядка, через killкоманду, fgабо bgу випадку з SIGCONT.

  • SIGKILLі SIGSTOPє розблокованими сигналами. Перший завжди припиняє процес негайно; другий призупиняє процес.
  • SIGCONT відновлює призупинений процес.
  • SIGTERMце придатна версія SIGKILL.

Який сигнал надсилається при використанні shutdownкоманди?
Натан Осман

Це залежить від сценаріїв відключення. Як правило, SIGTERMвідправляється спочатку, після чого відбувається затримка, після чого SIGKILL. В принципі, для жорсткого негайного відключення ядра зовсім не потрібно надсилати сигнал; це може просто перестати запускати процес.
Джандер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.