Saturday, January 26, 2013

Segmentation fault / program has stopped working in C

//เดี๋ยวเอารูปมาลงน๊ะจ๊ะ ^^

บ่อยครั้งที่เราเขียนโปรแกรมด้วยภาษา C แล้ว พยายามมานานแสนนาน สุดท้ายเมื่อโปรแกรมคอมไพล์ผ่านแล้ว แต่เมื่อใช้งานจริงพบว่าโปรแกรมขึ้นข้อความประมาณนี้
//ภาพ segmentation fault ใน linux
//ภาพโปรแกรมล่มใน window

ถามว่าอาการนี้คืออะไร มันคืออาการที่โปรแกรมได้รันคำสั่งตามที่เราเขียนไว้ทุกประการแล้ว แต่เกิดเหตุการณ์ร้ายแรงที่ทำให้มันทำงานต่อไม่ได้ แล้วเหตุการณ์ร้ายแรงพวกนี้คืออะไรบ้าง
  • หารจำนวนเต็มด้วย 0 
เราต้องอย่าลืมว่าเมื่อเราประกาศตัวแปรแบบ int แล้ว เมื่อตัวแปร int เก็บเลข 0 เนี่ย มันเก็บเลข 0 แท้ๆ ไม่ใช่ค่าน้อยมากๆเหมือนที่พบในวิชาแคลคูลัส ดังนั้นเมื่อเรานำเลขอะไรก็ตามมาหารด้วยเลข 0 แล้ว ก็จะหาค่าไม่ได้ คอมพิวเตอร์จึงไม่รู้ว่าจะทำอย่างไรต่อเพื่อให้โปรแกรมสามารถดำเนินต่อไปได้ จึงตัดสินใจหยุดโปรแกรมเอาไว้เพียงเท่านั้น
// สำหรับโปรแกรมภาษาอื่นๆอาจจะมีวิธีรับมือกับการหารเลขด้วย 0 ต่างกันไปแล้วแต่ภาษาที่ใช้
  • มี pointer พิการแต่อยากไปใช้มัน
สมมติเรามี pointer อยู่ตัวหนึ่ง แต่มันยังไม่ถูกกำหนดค่า หรือกำหนดค่าเป็น NULL หรือว่าง่ายๆ ยังไม่ได้ชี้ไปที่กล่องเก็บข้อมูล แต่เราต้องการจะอ่านค่าช่องที่ pointer มันชี้ คำถามคือ มันจะส่งค่าอะไรกลับมาให้เรา
คำตอบคือ มันไม่มีค่าอะไรจะส่งมาให้เรา ดังนั้นโปรแกรมก็ไม่รู้ว่าจะทำอย่างไรต่อดี ก็เลยหยุดไว้ก่อนเพียงเท่านั้น
ตัวอย่างเหตุการณ์ที่ทำให้เกิดอาการนี้
    • ลืมเช็ค pointer ว่าเป็น null หรือชี้ไปยังข้อมูลก้อนไหนแล้ว
    • malloc หรือ calloc ช่องเก็บข้อมูลแล้วแต่ล้มเหลว (อาจจะเพราะ ram หมด)
    • เพิ่งจะ free ช่องเก็บข้อมูลที่มาจากการ calloc ไปหยกๆแต่เรียกช่องเก็บข้อมูลชุดเดิมกลับมาใช้อีก
    • ปัญหาวน loop จัดการกับ pointer แล้วเงื่อนไขเพี้ยนไม่เป็นไปตามที่ออกแบบ
    • ใช้ array ช่องที่เกินขนาดที่จองไว้ (อาจจะเกิดเหตุการณ์ประหลาดหรืออาจจะไม่เกิดก็ได้ และอย่าลืมว่า array สำหรับภาษา c เดิมทีก็ประกอบมาจาก pointer) 
ในต่อเมื่อเราพอคาดเดาได้ว่าปัญหาอาจจะเกิดกับอะไรได้บ้าง ที่เหลือก็แค่ลองไปย้อนดูโปรแกรมที่เราเขียนว่ามีช่องโหว่ข้อผิดพลาดตรงไหนบ้าง
อย่าตกใจกับการที่โปรแกรมล่มด้วยลักษณะนี้ เพราะอย่างน้อยเราก็ยังจะมองย้อนไปหาได้ว่ามันผิดพลาดแถวๆไหน ดีกว่าโปรแกรมทำงานผ่านแต่ได้ผลเพี้ยนๆนะครับ

ป.ล. ที่เราเรียกกันติดปากว่า core dumped นั้น จริงๆนั่นไม่ใช่ชื่อของสิ่งที่เกิดขึ้น ในลินุกซ์สิ่งที่เกิดขึ้นเมื่อเกิดอาการนี้คือ Segmentation fault ส่วนคำว่า core dumped นั้นคือลินุกซ์ได้เก็บบันทึกทุกอย่างที่มีในหน่วยความจำของโปรแกรมตอนโปรแกรมล่มเอาไว้เพื่อให้เรานำไปใช้แก้ไขโปรแกรมเรา แต่มันเก็บบันทึกข้อมูลส่วนนี้ไว้ไหนนั้น เราก็ไม่รู้.....

No comments:

Post a Comment