Kapan sistem mengirim SIGTERM ke suatu proses?

24

Program server saya menerima SIGTERM dan berhenti (dengan kode keluar 0). Saya terkejut dengan ini, karena saya cukup yakin bahwa ada banyak memori untuk itu. Dalam kondisi apa linux (busybox) mengirim SIGTERM ke suatu proses?

michelemarcon
sumber
Saya tidak dapat memikirkan kasus apa pun ketika kernel atau alat standar akan mengirim SIGTERM ke proses acak. Apa yang bisa Anda ceritakan kepada kami tentang apa yang sedang dilakukan program dan bagaimana program itu dimulai? Bagaimana Anda mengetahui tentang status keluar program? Bisakah Anda mereproduksi masalahnya? Apakah Anda memiliki log yang dapat Anda periksa?
Gilles 'SO- stop being evil'
Itu membaca dan menulis ke baris serial, dan menanggapi permintaan UDP dan TCP. Saya telah membungkus eksekusi pada skrip bash dan karena itu saya tahu kode keluar.
michelemarcon
1
Dokumentasi Posix menunjukkan bahwa SIGTERM hanyalah acara tingkat pengguna. Apakah mungkin orang lain dapat membunuh program server Anda?
shellter
3
Kamu adalah! Kode pengembalian 0 berarti keluar normal. Jika ada SIGTERM, $?akan diatur ke 143 (128 + nomor sinyal).
Gilles 'SANGAT berhenti menjadi jahat'
1
Juga, ^ C adalah SIGINT, bukan SIGTERM, dan itu akan keluar dengan kode 130.
flarn2006

Jawaban:

13

Saya akan memposting ini sebagai jawaban sehingga ada semacam resolusi jika ini ternyata menjadi masalah.

Status keluar dari 0 berarti keluar normal dari program yang sukses. Program yang keluar dapat memilih integer antara 0 dan 255 sebagai status keluarnya. Secara konvensional, program menggunakan nilai-nilai kecil. Nilai 126 dan di atas digunakan oleh shell untuk melaporkan kondisi khusus, jadi yang terbaik adalah menghindarinya.

Pada tingkat C API, program melaporkan status 16-bit¹ yang menyandikan status keluar program dan sinyal yang membunuhnya, jika ada.

Dalam shell, status keluar perintah (disimpan dalam $?) mengkonfigurasi status keluar sebenarnya dari program dan nilai sinyal: jika suatu program terbunuh oleh sinyal, $?diatur ke nilai yang lebih besar dari 128 (dengan sebagian besar shell, nilai ini adalah 128 ditambah nomor sinyal; ATT ksh menggunakan 256 + nomor sinyal dan yash menggunakan 384 + nomor sinyal, yang menghindari ambiguitas, tetapi cangkang lain belum mengikutinya).

Khususnya, jika $?0, program Anda keluar secara normal.

Perhatikan bahwa ini termasuk kasus proses yang menerima SIGTERM, tetapi memiliki pengendali sinyal untuk itu, dan akhirnya keluar secara normal (mungkin sebagai konsekuensi tidak langsung dari sinyal SIGTERM, mungkin tidak).


Untuk menjawab pertanyaan dalam judul Anda, SIGTERM tidak pernah dikirim secara otomatis oleh sistem. Ada beberapa sinyal yang dikirim secara otomatis seperti SIGHUP ketika terminal hilang, SIGSEGV / SIGBUS / SIGILL ketika suatu proses melakukan hal-hal yang seharusnya tidak dilakukan, SIGPIPE ketika menulis ke pipa / soket yang rusak, dll. Dan ada beberapa sinyal yang dikirim karena penekanan tombol di terminal, terutama SIGINT untuk Ctrl+ C, SIGQUIT untuk Ctrl+ \dan SIGTSTP untuk Ctrl+ Z, tetapi SIGTERM bukan salah satunya. Jika suatu proses menerima SIGTERM, beberapa proses lain mengirim sinyal itu.

¹ secara kasar

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Penjelasan yang bagus tentang bagaimana status keluar ditentukan saat menerima sinyal. Namun, jawaban ini tidak menjawab pertanyaan OP.
codeforester
1
@ kodeforester Saya menjawab pertanyaan di tubuh, bukan pertanyaan di judul. Nah, salah satu pertanyaan dalam tubuh - mengingat bahwa itu didasarkan pada kesalahpahaman, itu agak berantakan. Saya akan menambahkan beberapa kata tentang sisanya.
Gilles 'SO- stop being evil'
Itu tergantung pada shell. Di ksh93, ini 256 + signum, di yash, 384 + signum
Stéphane Chazelas
Perhatikan bahwa menggunakan nilai di atas 256 a la ksh tidak selalu lebih baik karena mencegahnya diteruskan exit. The yashpendekatan adalah kompromi yang baik, tapi lihat rc untuk satu sama lain. Lihat juga Kode keluar default saat proses dihentikan?
Stéphane Chazelas
10

SIGTERM adalah sinyal yang biasanya digunakan untuk mengakhiri proses secara administratif.

Itu bukan sinyal bahwa kernel akan mengirim, tapi itu sinyal proses biasanya akan mengirim untuk menghentikan (anggun) proses lain.

Itulah sinyal yang dikirimkan secara default oleh kill, pkill, killall, fuser -k... perintah.

Itu adalah sinyal yang dikirim ke daemon untuk menghentikannya (seperti pada a service some-service stop), atau dikirim initsebelum shutdown (diikuti oleh SIGKILL untuk proses-proses yang belum berhasil berakhir pada waktu setelah SIGTERM).

Perhatikan bahwa SIGTERM bukan sinyal yang dikirimkan ^C. Sinyal yang dikirim ^Cadalah SIGINT.

Stéphane Chazelas
sumber