เครื่องดับ/ค้างตอนกลางคืน: อ่านสาเหตุจาก crash dump (bugcheck 0x154)
เครื่องที่ค้างตอนเช้าไม่ได้แปลว่าไฟดับหรือค้างตอนนั้นพอดี Windows จดเหตุการณ์ไว้ให้เกือบทุกครั้ง ถ้ารู้ว่าต้องเปิดตรงไหนก็แยกได้ว่าเป็นจอฟ้าหรือแค่ไฟตก และเดาต่อได้ว่าต้นเหตุอยู่ฝั่งไหนของเครื่อง
สรุปใน 1 นาที
- อาการ/ปัญหา
- โน้ตบุ๊กดับหรือค้างตอนรันงานข้ามคืน และไม่รู้ว่าไฟดับหรือจอฟ้า
- ใครควรอ่าน
- คนที่เครื่อง Windows ค้างหรือดับตอนกลางคืนและอยากรู้สาเหตุ
- ทางแก้แบบสั้น
- เปิด log ย้อนหลังดูรหัส bugcheck 0x1A กับ 0x154 อ่าน MEMORY.DMP ด้วย kd และตัดตัวแปร Intel XTU กับ XMP โดยยังไม่พิสูจน์ต้นเหตุ
พอดีโน้ตบุ๊กเกมมิ่งที่ผมรันงานข้ามคืนเป็นประจำ ค้างจนต้องกดปุ่มปิดเปิดเองตอนเช้า ผมเลยสั่งให้ไล่ log ย้อนหลังสองสัปดาห์ แทนที่จะเดาว่าเป็นที่ไฟหรือเป็นที่ซอฟต์แวร์ ผลที่ได้คือเครื่องดับสามครั้งในสิบสี่วัน และทั้งสามครั้งเป็นจอฟ้า (bugcheck) ไม่ใช่ไฟดับ
บทความนี้เล่าวิธีอ่านเรื่องแบบนี้จาก log และ dump ตามที่ผมทำจริงเมื่อต้นเดือนตุลาคม ตอนท้ายเขียนตรง ๆ ว่าเคสนี้ยังไม่ปิด ผมไม่รู้ต้นเหตุราก แค่ตัดตัวแปรบางตัวออกไปได้ และมีบางจุดที่เป็นแค่สมมติฐานของผมกับผู้ช่วยตอนนั้น ซึ่งผมจะติดป้ายไว้ รุ่นเครื่องกับชื่อผู้ใช้ผมไม่ใส่ ใช้คำว่าโน้ตบุ๊กเกมมิ่งเฉย ๆ
ขั้นแรก: ตารางเหตุการณ์ว่าดับเพราะอะไร
ถ้าเครื่องดับเอง คำถามแรกคือไฟดับ หรือซอฟต์แวร์/ฮาร์ดแวร์ล้ม สองกรณีนี้ทิ้งร่องรอยไม่เหมือนกัน ถ้าไฟดับหรือกดปิดเครื่องแรง ๆ Windows จะจดแค่ว่าเครื่องปิดผิดปกติ (Kernel-Power event 41) โดยไม่มีสาเหตุ แต่ถ้าเป็นจอฟ้า จะมี event จาก WER-SystemErrorReporting ตามมาตอนบูตครั้งถัดไป พร้อมรหัส bugcheck
# ตัวอย่างทั่วไป: ดึง bugcheck ย้อนหลัง 14 วัน (PowerShell แบบ admin)
$since = (Get-Date).AddDays(-14)
Get-WinEvent -FilterHashtable @{
LogName = 'System'
ProviderName = 'Microsoft-Windows-WER-SystemErrorReporting'
StartTime = $since
} | Select-Object TimeCreated, Id, @{n='Message';e={ $_.Message -replace '\s+',' ' }} |
Format-Table -AutoSize -Wrap
คำสั่งนี้เป็นรูปแบบมาตรฐานของ Windows ไม่ใช่ผลลัพธ์ของเคสผม ถ้าอยากดูผ่านหน้าจอ เปิด Event Viewer แล้วค้น Event ID 1001 (ผลของ bugcheck) กับ 41 (Kernel-Power) ในล็อก System จะได้ข้อมูลเดียวกัน
ผลที่ผมได้จากตารางเหตุการณ์ของเครื่องนี้คือสามแถว
| วันที่ | เวลา | รหัส | ชื่อ |
|---|---|---|---|
| 23 ก.ย. | 09:54 | 0x1A | MEMORY_MANAGEMENT |
| 29 ก.ย. | 18:51 | 0x154 | UNEXPECTED_STORE_EXCEPTION |
| 3 ต.ค. | 04:18 | 0x154 | UNEXPECTED_STORE_EXCEPTION |
ครั้งแรกมี parameter ตัวแรกเป็น 0x41792 ซึ่งตามความหมายของ bugcheck 0x1A แล้วหมายถึงตาราง page ในหน่วยความจำเสียหาย ส่วนสองครั้งหลังเป็น 0x154 ซ้ำกัน ผมมีข้อสังเกตแค่ว่าทั้งสามรหัสมาจากฝั่งระบบหน่วยความจำ แต่ผมไม่กล้าบอกว่า 0x1A กับ 0x154 มีสาเหตุเดียวกัน นั่นเป็นแค่สมมติฐาน
ถ้ามีแค่ Kernel-Power 41 โดดเดี่ยว ไม่มี event ของ WER-SystemErrorReporting ตามมา นั่นคือสัญญาณของไฟดับ หรือเครื่องถูกตัดไฟกลางคัน เคสของผมมีรหัส bugcheck ครบทั้งสามครั้ง เลยตัดข้อสงสัยเรื่องไฟออกไปได้ แต่ถ้าเครื่องคุณเจอ 41 ล้วน ๆ ให้ไปดูเรื่องไฟ ปลั๊ก และอแดปเตอร์ก่อน
ค้างตอนเช้า กับ bugcheck ตอนตีสี่ ไม่ได้เป็นเรื่องเดียวกันเสมอไป
ตรงนี้มีรายละเอียดที่ผมอยากแยกให้ชัด ครั้งสุดท้ายเกิดตอน 04:18 แต่ผมมาเจอเครื่องค้างตอนเช้า ห่างกันหลายชั่วโมง ผู้ช่วยตอนนั้นอธิบายว่าที่เห็นเป็น "ค้าง" คือหน้าจอนิ่งขณะ Windows เขียน dump และเครื่องอาจค้างอยู่ที่หน้านั้นจนกว่าจะมีคนกดรีบูต ฟังดูเข้าที แต่ผมต้องบอกว่านี่เป็นสมมติฐาน ไม่ใช่ข้อพิสูจน์ ผมไม่มีหลักฐานว่าเครื่องค้างที่หน้าจอ dump จริง ผมรู้แค่ว่าตอนบูตใหม่มีไฟล์ dump ครบ
ข้อที่เป็นความรู้ทั่วไปของ Windows คือตอนเกิด bugcheck หน้าจออาจนิ่งขณะที่ระบบเขียนข้อมูลหน่วยความจำลงดิสก์ ซึ่งถ้าหน่วยความจำเยอะ ก็ใช้เวลาไม่น้อย แต่เวลาห่างหลายชั่วโมงก็ยังอธิบายได้อีกหลายแบบ เช่นเครื่องเขียน dump เสร็จแล้วค้างรอรีบูตอัตโนมัติที่ไม่ได้ตั้งไว้ ผมเลยเขียนได้แค่ว่าตอนเกิด bugcheck หน้าจออาจนิ่งแล้วเครื่องอาจค้างอยู่หน้านั้นจนกว่าจะรีบูต โดยไม่พิสูจน์ว่าเป็นอย่างนั้น
ขั้นสอง: ตั้งค่าให้ dump เก็บได้ แล้วเปิดด้วย kd
dump คือภาพถ่ายหน่วยความจำของเครื่อง ณ วินาทีที่ล้ม ถ้าไม่ได้ตั้งไว้ก็ไม่มีอะไรให้อ่านเลย ที่ System Properties > Advanced > Startup and Recovery ตรงหัวข้อ Write debugging information เลือกว่าจะเก็บแบบไหน เคสนี้ได้ไฟล์ C:\Windows\MEMORY.DMP ขนาด 4,318,318,535 ไบต์ ประมาณ 4.3 GB เขียนครบ
เครื่องมือที่ผมใช้เปิดคือ kd ในชุด Debugging Tools for Windows ซึ่งเป็นเวอร์ชันบรรทัดคำสั่งของ WinDbg เปิดไฟล์แล้วสั่งให้วิเคราะห์
# ตัวอย่างทั่วไป: เปิด dump แบบอ่านอย่างเดียว ไม่แตะไฟล์ต้นฉบับ
kd -z C:\Windows\MEMORY.DMP -c "!analyze -v; q"
# ตัวอย่างรูปแบบของผล !analyze -v — ไม่ใช่ผลเต็มของเคสนี้ แสดงเฉพาะบรรทัดที่ควรมองหา
*******************************************************************************
* Bugcheck Analysis *
*******************************************************************************
UNEXPECTED_STORE_EXCEPTION (154)
...
BUGCHECK_CODE: 154
...
PROCESS_NAME: MemCompression
...
ผลเต็มของ kd รอบนั้นผมไม่ได้เก็บ stack หรือฟิลด์ที่ล้มไว้ เลยไม่ขอเดาเนื้อหาของมัน สิ่งที่ผมยืนยันได้จากการวิเคราะห์คือ process ที่เกี่ยวข้องเป็น MemCompression ซึ่งคือตัวบีบอัดหน่วยความจำของ Windows ที่ทำหน้าที่ย่อ page เก่าเก็บไว้ใน RAM แทนที่จะเขียนลงดิสก์ ผลที่ได้ชี้ไปที่ระบบหน่วยความจำและตัว store ไม่ใช่ไดรเวอร์การ์ดจอ ส่วนว่าราก ๆ แล้วเสียที่ RAM ตัวจริง ค่า undervolt หรือที่ดิสก์ที่เก็บ store ผมยังไม่รู้

รหัสสองตัวนี้บอกอะไรได้ และบอกอะไรไม่ได้
รหัส 0x1A (MEMORY_MANAGEMENT) บอกว่าตัวจัดการหน่วยความจำของเคอร์เนลเจอสิ่งที่ผิดปกติ เช่นโครงสร้างที่ใช้จัดการ page เสีย ส่วน 0x154 (UNEXPECTED_STORE_EXCEPTION) เกี่ยวกับ store component ซึ่งเป็นส่วนที่จัดการเก็บ page ที่ถูกบีบอัดหรือย้ายออก ดังนั้นทั้งคู่อยู่ในย่านเดียวกันคือการจัดการหน่วยความจำ แต่ย่านเดียวกันไม่ได้แปลว่าต้นเหตุเดียวกัน ที่ผิดอาจเป็น RAM ที่เสียจริง ค่าแรงดันหรือความถี่ที่ไม่เสถียร ดิสก์ที่เก็บไฟล์ page หรือบั๊กของไดรเวอร์ก็ได้ สองอย่างหลังโดยปกติจะเห็นร่องรอยใน stack ซึ่งผมไม่มีเก็บไว้
สิ่งที่เรียกว่า MemCompression เป็น process ระบบที่ Windows ใช้บีบ page ที่ไม่ได้ใช้ให้เล็กลงแล้วเก็บไว้ใน RAM ต่อ แทนที่จะเขียนออกดิสก์ทันที ถ้ามันเป็นตัวที่ล้ม หมายความว่าตอนอ่านหรือเขียนข้อมูลที่ถูกบีบอัดมีอะไรผิดคาด จุดนี้ทำให้ผมสงสัยหน่วยความจำก่อน แต่ก็เป็นแค่ตัวชี้ทิศ เพราะ process ที่โชว์ในผลวิเคราะห์คือ process ที่กำลังรันตอนล้ม ไม่จำเป็นต้องเป็นตัวต้นเหตุ
ชนิดของ dump ก็มีผลต่อสิ่งที่อ่านได้ ไฟล์แบบ kernel memory dump เก็บเฉพาะหน่วยความจำของเคอร์เนล ส่วนแบบ complete memory dump เก็บทั้งเครื่องและมีขนาดใกล้เคียงกับ RAM ที่ติดตั้ง ไฟล์ของผมขนาด 4.3 GB ผมไม่ได้เช็กว่าเป็นแบบไหนในเคสนี้ เลยไม่ขอบอก
ตัดตัวแปรที่ตัดได้โดยไม่เสียหาย
พอรู้ว่าชี้ไปที่หน่วยความจำ ผมทำสองอย่างเพื่อตัดตัวแปร อย่างแรกคือ Intel XTU ซึ่งเป็นเครื่องมือ undervolt/overclock ที่เคยตั้งค่าไว้ ผมหยุด service ของมัน (XTU3SERVICE ที่เดิมเป็น Running/Manual) แล้วตั้งเป็น Disabled เพื่อไม่ให้ค่าที่เคยตั้งถูกเขียนกลับตอนบูตใหม่ ต้องรีสตาร์ตหนึ่งครั้งถึงมีผล เพราะค่าที่ XTU ตั้งไว้จะค้างอยู่ใน CPU จนกว่าจะรีบูต
# PowerShell แบบ admin: หยุดและปิดการสตาร์ตของ XTU service
Stop-Service XTU3SERVICE
Set-Service XTU3SERVICE -StartupType Disabled
Get-Service XTU3SERVICE | Format-List Name,Status,StartType
# ย้อนกลับถ้าต้องการใช้อีก
Set-Service XTU3SERVICE -StartupType Manual
Start-Service XTU3SERVICE
ผลข้างเคียงที่เห็นคือหน้า Overclock ในซอฟต์แวร์ปรับแต่งของผู้ผลิตใช้ไม่ได้ แต่โหมดพัดลมกับความร้อนยังใช้ได้ เพราะสั่งผ่าน BIOS ไม่ผ่าน XTU
อย่างที่สองคือตรวจ RAM ซึ่งเครื่องนี้ใช้ DDR5 สองแท่ง แท่งละ 16 GB วิ่งที่ 4800 ตามสเปก JEDEC เต็มความเร็วที่ประกาศ ไม่มีโปรไฟล์ XMP ให้เปิด ดังนั้นข้อสงสัยเรื่อง "XMP ตั้งผิด" ตัดทิ้งได้ XMP มีประโยชน์เฉพาะเมื่อเปลี่ยนเป็น RAM ที่มีโปรไฟล์ในตัว
ตัวแปรที่ตรวจแล้ว
- ไฟดับ: ไม่ใช่ เพราะมี bugcheck ครบสามครั้ง
- ไดรเวอร์การ์ดจอ: process ที่เกี่ยวคือ MemCompression
- XMP: ไม่มีโปรไฟล์ RAM วิ่ง 4800 ตามสเปก
- ค่า undervolt จาก XTU: ปิด service แล้ว
ตัวแปรที่ยังค้าง
- RAM เสียจริงหรือไม่
- undervolt เดิมเป็นต้นเหตุหรือไม่
- ดิสก์ที่เก็บ store มีปัญหาหรือไม่
- ปิด XTU แล้วอาการหายไหม ยังไม่มีผลติดตาม
ถ้าเกิดอีก ให้ตรวจอะไรต่อ
ผู้ใช้ตัดสินใจทดสอบ RAM เอง แต่ในบันทึกยังไม่มีผล memtest เลยไม่มีอะไรให้ผมอ้าง ลำดับที่ผมจะทำต่อเมื่อเกิดซ้ำคือ
- เปิดตารางเหตุการณ์ย้อนหลังดูว่ารหัสยังเป็นกลุ่มหน่วยความจำ (0x1A, 0x154) หรือเปลี่ยนไปเป็นรหัสอื่น ถ้าเปลี่ยนไปก็เป็นเบาะแสว่าเรื่องไม่ได้อยู่ที่เดียว
- เปิด dump ใหม่ด้วย
kdดูว่า process ที่เกี่ยวยังเป็น MemCompression ไหม เก็บ stack ไว้คราวนี้ - รันเครื่องมือทดสอบ RAM ตั้งแต่บูต ให้ครบทุกรอบ ไม่ตัดกลางทาง
- ถ้าเปลี่ยนไปใช้ RAM ที่มีโปรไฟล์ XMP ให้เก็บค่าที่ตั้งไว้ในบันทึกก่อนเปิด จะได้ย้อนได้
- ถ้ารหัสหยุดเกิดหลังปิด XTU ค่อยกลับไปไล่ว่าค่า undervolt เดิมคืออะไร ก่อนจะเปิดมันกลับ

ผมยังไม่รู้ต้นเหตุราก ไม่รู้ว่า RAM เสีย ค่า undervolt ผิด หรือดิสก์ที่เก็บ store มีปัญหา ไม่มีการติดตามผลหลังปิด XTU ว่าอาการหายหรือไม่ และสมมติฐานที่ว่ารหัส 0x1A กับ 0x154 มาจากสาเหตุเดียวกันยังไม่ถูกพิสูจน์ ที่เขียนมาทั้งหมดคือวิธีอ่านและวิธีตัดตัวแปร ไม่ใช่วิธีแก้ที่ทำแล้วหาย
สรุปสิ่งที่ได้จากเคสนี้
ถ้าเอาเฉพาะวิธีมาใช้ต่อ ผมสรุปได้เป็นลำดับสั้น ๆ เปิดตารางเหตุการณ์ก่อนเสมอ เพราะมันบอกได้ในไม่กี่นาทีว่าเป็นไฟหรือเป็นจอฟ้า ถ้าเป็นจอฟ้าให้ดูรหัสกับชื่อของมัน เพราะแค่นั้นก็บอกกลุ่มต้นเหตุได้ว่าหน่วยความจำ ไดรเวอร์ หรือดิสก์ จากนั้นเปิด dump ดู process ที่เกี่ยวข้อง และตัดตัวแปรที่ตัดได้โดยไม่ทำลายอะไร อย่างการปิด service ที่ปรับแรงดัน อีกอย่างที่ผมเก็บไปคือแยก "สิ่งที่เห็น" ออกจาก "สิ่งที่ผู้ช่วยหรือตัวเองเดา" ให้ชัดตั้งแต่ตอนจด ไม่งั้นพอผ่านไปสักพัก สมมติฐานจะกลายเป็นข้อเท็จจริงในความจำ ใครมีผล memtest หรือเจอ dump ที่ stack ต่างจากนี้ก็ลองเทียบดูได้เลยครับ ตรงไหนผมสรุปตกหล่นหรือพิมพ์ผิด เดี๋ยวกลับมาแก้เพิ่มให้ภายหลังครับ
เคยเจองานแบบนี้ไหม? ติดตรงไหน?
มาแลกวิธีกันต่อในบอร์ด LinuxThai



ความคิดเห็น 0
ยังไม่มีความคิดเห็น — เป็นคนแรกเลย