อ่าน 4 นาที
กลไกการจัดการข้อยกเว้นเฉพาะของ Microsoft
ระบบปฏิบัติการ ตระกูลMicrosoft Windows ใช้กลไก การจัดการข้อผิดพลาด เฉพาะบางอย่าง
กลไกการจัดการข้อยกเว้นเฉพาะของ Microsoft
ระบบปฏิบัติการตระกูลMicrosoft Windowsใช้กลไก การจัดการข้อผิดพลาด เฉพาะบางอย่าง
การจัดการข้อยกเว้นแบบมีโครงสร้าง
Microsoft Structured Exception Handling เป็นกลไกการจัดการข้อยกเว้นดั้งเดิมสำหรับ Windows และเป็นเทคโนโลยีต้นแบบของVectored Exception Handling (VEH) [ 1 ]กลไกนี้finallyไม่มีอยู่ในข้อยกเว้นมาตรฐานของ C++ (แต่มีอยู่ใน ภาษา เชิงคำสั่ง ส่วนใหญ่ ที่นำเสนอในภายหลัง) SEH จะถูกตั้งค่าและจัดการแยกต่างหากสำหรับแต่ละเธรดของการดำเนินการ
การใช้งาน
Microsoft สนับสนุน SEH เป็นเทคนิคการเขียนโปรแกรมในระดับคอมไพเลอร์เท่านั้น คอมไพเลอร์ MS Visual C++ มีคีย์เวิร์ดที่ไม่เป็นมาตรฐานสามคำ ได้แก่__try, __exceptและ — เพื่อจุดประสงค์นี้ ด้านการจัดการข้อยกเว้นอื่นๆ ได้รับการสนับสนุนโดย ฟังก์ชันWin32 API__finallyจำนวนหนึ่ง[ 2 ]ตัวอย่างเช่นเพื่อยกข้อยกเว้น SEH ด้วยตนเอง RaiseException
int filterExpression ( EXCEPTION_POINTERS * ep ) { ep -> ContextRecord -> Eip += 8 ; // คำสั่งหารอาจถูกเข้ารหัสตั้งแต่ 2 ถึง 8 ไบต์return EXCEPTION_CONTINUE_EXECUTION ; }int main ( void ) { static int zero = 0 ; __try { zero = 1 / zero ; asm { nop nop nop nop nop nop nop } printf ( "ผ่านข้อยกเว้นแล้ว\n " ) ; } __except ( filterExpression ( GetExceptionInformation ())) { printf ( "เรียกใช้แฮนด์เลอร์แล้ว\n " ); } return 0 ; }การดำเนินการ
ไอเอ-32
แต่ละเธรดการทำงานใน Windows IA-32 edition หรือเลเยอร์การจำลองWoW64 สำหรับเวอร์ชัน x86-64มีลิงก์ไปยังรายการ_EXCEPTION_REGISTRATION_RECORD ที่ไม่ได้บันทึก ไว้ที่จุดเริ่มต้นของบล็อกข้อมูลเธรดคำสั่งดังกล่าวเรียกฟังก์ชันที่กำหนดโดยคอมไพเลอร์ฟังก์ชันนั้นจะจัดสรร_EXCEPTION_REGISTRATION_RECORD บนสแต็กที่ชี้ไปยัง ฟังก์ชัน [ a ] ใน[ b ]จากนั้นเพิ่มเรคอร์ดลงในส่วนหัวของรายการ ในตอนท้ายของบล็อก จะมีการเรียกฟังก์ชัน ที่กำหนดโดยคอมไพเลอร์ซึ่งดำเนินการย้อนกลับ รูทีนที่กำหนดโดยคอมไพเลอร์เหล่านี้สามารถอยู่ในบรรทัดเดียวกันได้ บล็อก และที่กำหนดโดยโปรแกรมเมอร์ทั้งหมดจะถูกเรียกจากภายในหากมีบล็อกที่กำหนดโดยโปรแกรมเมอร์อยู่_EXCEPTION_REGISTRATION_RECORDที่สร้างโดยจะถูกขยายด้วยฟิลด์เพิ่มเติมบางส่วนที่ใช้โดย[ 3 ]__tryEH_prolog__except_handler3msvcrt.dll__tryEH_epilog__except__finally__except_handler3EH_prolog__except_handler3
ในกรณีที่เกิดข้อยกเว้นใน โค้ด โหมดผู้ใช้ระบบปฏิบัติการ[ c ] จะวิเคราะห์รายการ _EXCEPTION_REGISTRATION_RECORDของเธรดและเรียกตัวจัดการข้อยกเว้นแต่ละตัวตามลำดับจนกว่าตัวจัดการจะส่งสัญญาณว่าได้จัดการข้อยกเว้นแล้ว (โดยค่าส่งคืน ) หรือรายการหมดลง ตัวจัดการตัวสุดท้ายในรายการจะเป็นตัวที่แสดงข้อความแสดงข้อผิดพลาดGeneral protection fault เสมอ [ d ]จากนั้นรายการจะถูกวนซ้ำอีกครั้งเพื่อให้ตัวจัดการมีโอกาสทำความสะอาดทรัพยากรที่ใช้ไป สุดท้าย การทำงานจะกลับไปยังโหมดเคอร์เนล[ e ]ซึ่งกระบวนการจะดำเนินการต่อหรือยุติลง kernel32!UnhandledExceptionFilter
สิทธิบัตรเกี่ยวกับโหมด SEH นี้ หมายเลข US5628016 หมดอายุในปี 2014
x86-64
SEH บน Windows 64 บิตไม่เกี่ยวข้องกับรายการตัวจัดการข้อยกเว้นขณะรันไทม์ แต่จะใช้ ตาราง การคลายสแต็ก ( UNWIND_INFO) ที่ระบบตีความเมื่อเกิดข้อยกเว้น[ 4 ] [ 5 ] ซึ่งหมายความว่าคอมไพเลอร์ไม่จำเป็นต้องสร้างโค้ดเพิ่มเติมเพื่อทำการคลายสแต็กด้วยตนเองและเรียกตัวจัดการข้อยกเว้นอย่างเหมาะสม เพียงแค่ต้องส่งข้อมูลในรูปแบบของตารางการคลายเกี่ยวกับเค้าโครงเฟรมสแต็กและตัวจัดการข้อยกเว้นที่ระบุไว้
สนับสนุน
GCC 4.8+ จากMingw-w64รองรับการใช้ SEH 64 บิตสำหรับข้อยกเว้น C++ LLVM clang รองรับ__tryทั้ง x86 และ x64 [ 6 ]
การจัดการข้อยกเว้นแบบเวกเตอร์
การจัดการข้อยกเว้นแบบเวกเตอร์ได้รับการแนะนำในWindows XP [ 7 ] การจัดการข้อยกเว้นแบบเวกเตอร์มีให้สำหรับโปรแกรมเมอร์ Windows ที่ใช้ภาษาต่างๆ เช่นC++และVisual Basic VEH ไม่ได้แทนที่การจัดการข้อยกเว้นแบบมีโครงสร้าง (SEH) แต่ VEH และ SEH ทำงานร่วมกัน โดยตัวจัดการ VEH มีลำดับความสำคัญเหนือตัวจัดการ SEH [ 1 ] [ 7 ] เมื่อเปรียบเทียบกับ SEH แล้ว VEH ทำงานคล้ายกับสัญญาณ Unixที่ ส่งมาจากเคอร์เนลมากกว่า [ 8 ]
หมายเหตุ
- ^ชื่ออาจแตกต่างกันไปใน VC runtime เวอร์ชันต่างๆ
- ^
ntdll.dllและkernel32.dllโปรแกรมอื่นๆ ที่เชื่อมโยงแบบคงที่กับรันไทม์ VC จะมีการคอมไพล์ฟังก์ชันนี้เข้าไปด้วย - ^โดยเฉพาะอย่างยิ่ง
ntdll!RtlDispatchExceptionรูทีนระบบที่ถูกเรียกจากntdll!KiUserExceptionDispatcherนั้นก็ถูกเรียกต่อจากnt!KiDispatchExceptionฟังก์ชันเคอร์เนล (ดู Ken Johnson (16 พฤศจิกายน 2007). "A catalog of NTDLL kernel mode to user mode callbacks, part 2: KiUserExceptionDispatcher" )(สำหรับรายละเอียดเพิ่มเติม) - ^สามารถปิดเสียงข้อความได้โดยการเปลี่ยนโหมดข้อผิดพลาด ของกระบวนการ ตัวจัดการข้อผิดพลาดตัวสุดท้ายเริ่มต้นสามารถแทนที่ได้ด้วยAPI SetUnhandledExceptionFilter
- ^
ntdll!KiUserExceptionDispatcherเรียกอย่างใดอย่างหนึ่งnt!ZwContinueหรือnt!ZwRaiseException
ลิงก์ภายนอก
- Microsoft Corp. (2009-11-12). "การจัดการข้อยกเว้นแบบมีโครงสร้าง" . MSDN Library . สืบค้นเมื่อ 2022-07-23 .
- Matt Pietrek (มกราคม 1997). "หลักสูตรเร่งรัดเกี่ยวกับการจัดการข้อยกเว้นเชิงโครงสร้างของ Win32" . MSJ . 12 (1). เก็บถาวรจากต้นฉบับเมื่อ 2003-08-10.โปรดทราบว่าตัวอย่างที่ให้ไว้ในนั้นใช้งานไม่ได้โดยตรงบนระบบ Windows รุ่นใหม่ๆ (หลัง XP SP2) เนื่องจากการเปลี่ยนแปลงที่ Microsoft ทำขึ้นเพื่อแก้ไขปัญหาด้านความปลอดภัยที่มีอยู่ในดีไซน์ SEH รุ่นแรกๆ ตัวอย่างเหล่านี้ยังคงใช้งานได้บน Windows เวอร์ชันที่ใหม่กว่า หากคอมไพล์ด้วย
/link /safeseh:no. - "win32: การจัดการข้อยกเว้นที่มีโครงสร้างอย่างปลอดภัย"คู่มือYasm
- สิทธิบัตรสหรัฐอเมริกาหมายเลข 7,480,919 - ข้อยกเว้นที่ปลอดภัย
- โยฮันเนส พาสซิง (20 พฤษภาคม 2551) "สนุกกับ SEH ระดับต่ำ "เนื้อหาครอบคลุมรายละเอียดที่ซับซ้อนซึ่งจำเป็นต่อการทำให้โค้ด SEH ระดับต่ำ (และโดยเฉพาะ SafeSEH) ทำงานได้บน Windows รุ่นใหม่ๆ
- Igor Skochinsky (6 มีนาคม 2549). "การวิเคราะห์ย้อนกลับ Microsoft Visual C++ ตอนที่ 1: การจัดการข้อยกเว้น" . OpenRCE . สืบค้นเมื่อ17 พฤศจิกายน 2552 .
- Matt Miller (2 กุมภาพันธ์ 2552). "การป้องกันการใช้ประโยชน์จากการเขียนทับ Structured Exception Handler (SEH) ด้วย SEHOP" . Technet.
- Stéfan Le Berre, Damien Cauquil (22 ธันวาคม 2009). "การหลีกเลี่ยง SEHOP" (PDF) . Sysdream. เก็บถาวรจากต้นฉบับ(PDF)เมื่อ 7 กันยายน 2012
- Joshua J. Drake (10 มกราคม 2012). "ของเก่าพบของใหม่: ความไม่เข้ากันของ Microsoft Windows SafeSEH" . เก็บถาวรจากต้นฉบับเมื่อ 9 มกราคม 2017 . เรียกดูเมื่อ9 มกราคม 2017 .บทความนี้อธิบายว่าเหตุใด Windows 7 SP1 จึงไม่สนใจ SafeSEH สำหรับไฟล์ไบนารีเก่าบางไฟล์ ในขณะที่ Windows XP SP3 กลับใช้งานได้
สรุปเนื้อหา
ข้อมูลสำคัญจากบทความ
ข้อมูลสำคัญเกี่ยวกับ กลไกการจัดการข้อยกเว้นเฉพาะของ Microsoft
ระบบปฏิบัติการ ตระกูลMicrosoft Windows ใช้กลไก การจัดการข้อผิดพลาด เฉพาะบางอย่าง
การจัดการข้อยกเว้นแบบมีโครงสร้าง
Microsoft Structured Exception Handling เป็นกลไกการจัดการข้อยกเว้นดั้งเดิมสำหรับ Windows และเป็นเทคโนโลยีต้นแบบของ Vectored Exception Handling (VEH) [ 1 ] กลไกนี้ finally ไม่มีอยู่ในข้อยกเว้นมาตรฐานของ C++ (แต่มีอยู่ใน ภาษา เชิงคำสั่ง ส่วนใหญ่...
การใช้งาน
Microsoft สนับสนุน SEH เป็นเทคนิคการเขียนโปรแกรมในระดับคอมไพเลอร์เท่านั้น คอมไพเลอร์ MS Visual C++ มีคีย์เวิร์ดที่ไม่เป็นมาตรฐานสามคำ ได้แก่ __try , __except และ — เพื่อจุดประสงค์นี้ ด้านการจัดการข้อยกเว้นอื่นๆ ได้รับการสนับสนุนโดย ฟังก์ชัน Win32 API...
การดำเนินการ
แต่ละ เธรดการทำงาน ใน Windows IA-32 edition หรือเลเยอร์การจำลอง WoW64 สำหรับเวอร์ชัน x86-64 มีลิงก์ไปยัง รายการ _EXCEPTION_REGISTRATION_RECORD ที่ไม่ได้บันทึก ไว้ที่จุดเริ่มต้นของ บล็อกข้อมูลเธรด...