ระบบจะส่ง SIGTERM ไปยังกระบวนการเมื่อใด


24

โปรแกรมเซิร์ฟเวอร์ของฉันได้รับ SIGTERM และหยุดทำงาน (ด้วยรหัสออก 0) ฉันประหลาดใจกับสิ่งนี้เนื่องจากฉันค่อนข้างมั่นใจว่ามีหน่วยความจำมากมายสำหรับมัน linux (busybox) ส่ง SIGTERM ไปยังกระบวนการใดภายใต้เงื่อนไขใด


ฉันไม่สามารถนึกถึงกรณีใด ๆ เมื่อเคอร์เนลหรือเครื่องมือมาตรฐานจะส่ง SIGTERM ไปยังกระบวนการแบบสุ่ม คุณสามารถบอกอะไรเราได้บ้างเกี่ยวกับโปรแกรมที่กำลังทำอยู่และวิธีเริ่มทำงาน คุณทราบเกี่ยวกับสถานะการออกของโปรแกรมได้อย่างไร คุณสามารถสร้างปัญหาขึ้นมาใหม่ได้หรือไม่? คุณมีบันทึกที่คุณสามารถตรวจสอบได้หรือไม่?
Gilles 'หยุดความชั่วร้าย'

มันคือการอ่านและเขียนไปยังสายอนุกรมและกำลังตอบสนองต่อการร้องขอ UDP และ TCP ฉันได้ปิดการทำงานของสคริปต์ทุบตีแล้วดังนั้นฉันจึงรู้รหัสออก
michelemarcon

1
เอกสาร Posix ระบุว่า SIGTERM เป็นเหตุการณ์ระดับผู้ใช้อย่างเคร่งครัด เป็นไปได้ไหมที่คนอื่น ๆ สามารถฆ่าโปรแกรมเซิร์ฟเวอร์ของคุณได้?
shellter

3
คุณคือ! รหัสส่งคืน 0 หมายถึงทางออกปกติ หากมี SIGTERM $?จะถูกตั้งค่าเป็น 143 (หมายเลขสัญญาณ 128 +)
Gilles 'หยุดความชั่วร้าย'

1
นอกจากนี้ ^ C คือ SIGINT ไม่ใช่ SIGTERM และนั่นจะออกด้วยรหัส 130
flarn2006

คำตอบ:


13

ฉันจะโพสต์สิ่งนี้เป็นคำตอบเพื่อให้มีวิธีแก้ปัญหาบางอย่างหากนี่เป็นปัญหา

สถานะการออกเป็น 0 หมายถึงการออกปกติจากโปรแกรมที่ประสบความสำเร็จ โปรแกรมออกสามารถเลือกจำนวนเต็มใด ๆ ระหว่าง 0 และ 255 ออกจากสถานะของมัน โดยทั่วไปโปรแกรมใช้ค่าน้อย เชลล์ใช้ค่า 126 ขึ้นไปเพื่อรายงานเงื่อนไขพิเศษดังนั้นจึงเป็นการดีที่สุดที่จะหลีกเลี่ยง

ที่ระดับ C API โปรแกรมจะรายงานสถานะ 16 บิตที่เข้ารหัสทั้งสถานะการออกของโปรแกรมและสัญญาณที่ฆ่าหากมี

ในเชลล์สถานะการออกของคำสั่ง (บันทึกใน$?) ทำให้สถานะการออกจริงของโปรแกรมและค่าสัญญาณ: หากโปรแกรมถูกฆ่าโดยสัญญาณ$?ถูกตั้งค่าเป็นค่าที่มากกว่า 128 (กับเชลล์ส่วนใหญ่ค่านี้คือ 128 บวกกับหมายเลขสัญญาณ ATT ksh ใช้หมายเลขสัญญาณ 256 + และ yash ใช้หมายเลขสัญญาณ 384 + ซึ่งหลีกเลี่ยงความคลุมเครือ แต่เชลล์อื่นไม่ได้ทำตามความเหมาะสม)

โดยเฉพาะอย่างยิ่งถ้า$?เป็น 0 โปรแกรมของคุณจะออกตามปกติ

โปรดทราบว่านี่รวมถึงกรณีของกระบวนการที่ได้รับ SIGTERM แต่มีตัวจัดการสัญญาณสำหรับมันและในที่สุดก็จะออกตามปกติ (อาจเป็นผลทางอ้อมของสัญญาณ SIGTERM ซึ่งอาจไม่ใช่)


ในการตอบคำถามในชื่อของคุณระบบจะไม่ส่ง SIGTERM อัตโนมัติ มีสัญญาณบางอย่างที่ส่งโดยอัตโนมัติเช่น SIGHUP เมื่อเทอร์มินัลหายไป SIGSEGV / SIGBUS / SIGILL เมื่อกระบวนการทำสิ่งที่ไม่ควรทำ SIGPIPE เมื่อเขียนไปยังท่อ / ซ็อกเก็ตที่ชำรุดเป็นต้นและมี สัญญาณเล็กน้อยที่ถูกส่งเนื่องจากการกดปุ่มในเทอร์มินัลส่วนใหญ่ SIGINT สำหรับCtrl+ C, SIGQUIT สำหรับCtrl+ \และ SIGTSTP สำหรับCtrl+ Zแต่ SIGTERM ไม่ใช่หนึ่งในนั้น หากกระบวนการได้รับ SIGTERM กระบวนการอื่นจะส่งสัญญาณนั้น

¹ พูดประมาณ


คำอธิบายที่ดีเกี่ยวกับการพิจารณาสถานะทางออกเมื่อรับสัญญาณ อย่างไรก็ตามคำตอบนี้ไม่ได้ตอบคำถามของ OP
codeforester

1
@codeforester ฉันตอบคำถามในเนื้อหาไม่ใช่คำถามในชื่อ หนึ่งในคำถามในร่างกาย - เนื่องจากมันตั้งอยู่บนพื้นฐานของความเข้าใจผิดมันค่อนข้างยุ่งเหยิง ฉันจะเพิ่มคำสองสามคำเกี่ยวกับส่วนที่เหลือ
Gilles 'ดังนั้นหยุดความชั่วร้าย'

ขึ้นอยู่กับเปลือก ใน ksh93 มี 256 + signum ใน yash เป็น
384+

โปรดทราบว่าการใช้ค่าข้างต้น 256 ลา ksh exitไม่จำเป็นต้องดีเป็นป้องกันที่จะถูกส่งผ่านไปยัง yashวิธีการคือการประนีประนอมที่ดี แต่เห็น RC สำหรับอีกคนหนึ่ง ดูเพิ่มเติมที่รหัสเริ่มต้นออกเมื่อกระบวนการสิ้นสุดลง?
Stéphane Chazelas

10

SIGTERM เป็นสัญญาณที่มักใช้ในการยกเลิกกระบวนการ

นั่นไม่ใช่สัญญาณที่เคอร์เนลจะส่ง แต่นั่นเป็นสัญญาณที่กระบวนการมักจะส่งเพื่อยกเลิก (อย่างสง่างาม) กระบวนการอื่น

นั่นเป็นสัญญาณที่ถูกส่งโดยค่าเริ่มต้นโดยkill, pkill, killall, fuser -k... คำสั่ง

นั่นเป็นสัญญาณที่ถูกส่งไปยัง daemons เพื่อหยุดพวกเขา (เช่นเดียวกับservice some-service stop) หรือส่งinitก่อนที่จะปิด (ตามด้วย SIGKILL สำหรับกระบวนการเหล่านั้นที่ไม่ได้มีการจัดการที่จะยุติในเวลากับ SIGTERM)

หมายเหตุ SIGTERM ที่เป็นไม่ได้^Cสัญญาณที่ถูกส่งไปอยู่กับ สัญญาณที่ส่งไป^Cคือ SIGINT

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.