- Debugging ของ David J. Agans ว่าด้วย พื้นฐานการดีบัก สำหรับการค้นหาสาเหตุและแก้ไขหลังพบบั๊ก โดยมอบหลักการที่ทั้งนักพัฒนามือใหม่ ระดับกลาง และผู้มีประสบการณ์สามารถย้อนกลับมาทบทวนได้ซ้ำๆ
- หนังสือประกอบด้วย กฎ 9 ข้อ ที่เชื่อมโยงความเข้าใจระบบ การทำให้ความล้มเหลวเกิดซ้ำ การสังเกต การแบ่งแยกปัญหา การควบคุมการเปลี่ยนแปลง การเก็บร่องรอยตรวจสอบ การตรวจสมมติฐาน มุมมองจากภายนอก และการยืนยันผลการแก้ไข เข้ากับกรณีศึกษาจากงานจริง
- แม้จะมีทั้งเทคโนโลยีเก่าและกรณีตัวอย่างนอกโลกคอมพิวเตอร์ แต่แก่นสำคัญไม่ใช่เครื่องมือเฉพาะทาง หากเป็น วิธีคิดเพื่อค่อยๆ ตีวงปัญหาให้แคบลง จึงประยุกต์ใช้ได้กับการดีบักทั้งฮาร์ดแวร์และซอฟต์แวร์
- สำหรับบั๊กที่รับมือยากอย่างปัญหาที่เกิดเป็นครั้งคราว คำแนะนำใน Make it Fail มีประโยชน์เป็นพิเศษ แต่ก็น่าเสียดายที่ไม่ได้พูดถึงคำว่า Heisenbug โดยตรง
- ต่างจากหนังสือที่สอนการใช้ GDB หรือการเขียนเทสต์ หนังสือเล่มนี้เน้น ภาพใหญ่ของการดีบัก จึงควรเสริมด้วยแหล่งข้อมูลอื่นสำหรับวิธีใช้เครื่องมือและ regression test
ปัญหาที่หนังสือเล่มนี้มุ่งแก้
- Debugging: The 9 Indispensable Rules for Finding Even the Most Elusive Software and Hardware Problems ของ David J. Agans ว่าด้วยกระบวนการค้นหาสาเหตุและแก้ไขจริงหลังจากตรวจพบบั๊กแล้ว
- แทนที่จะเน้นเทคโนโลยีหรือเครื่องมือเฉพาะ หนังสือเล่มนี้สรุป หลักการดีบัก ที่จำเป็นสำหรับ นักพัฒนาซอฟต์แวร์และฮาร์ดแวร์คอมพิวเตอร์
- เหมาะอย่างยิ่งสำหรับนักพัฒนามือใหม่และระดับกลาง และยังช่วยให้ผู้มีประสบการณ์รื้อฟื้นพื้นฐานที่มักหลุดไปในสถานการณ์เร่งด่วน
- จุดแข็งคือการกลั่นประสบการณ์ดีบักที่ปกติต้องเรียนรู้จากการลงมือทำ ให้กลายเป็นหลักการและกรณีศึกษาอย่างกระชับ
กฎการดีบัก 9 ข้อ
-
จงเข้าใจระบบ
- อ่านคู่มือ ทำความเข้าใจโครงสร้างทั้งหมด และเข้าใจทั้งหลักการพื้นฐานกับพฤติกรรมรายละเอียด
- ตรวจดูไปพร้อมกันว่าเครื่องมือที่ใช้แสดงอะไร และซ่อนอะไรไว้บ้าง
-
จงทำให้มันล้มเหลว
- รันปัญหาซ้ำและเริ่มใหม่ตั้งแต่ต้น เพื่อกระตุ้น เงื่อนไขที่ทำให้ล้มเหลว โดยตรง
- อย่าจำลองความล้มเหลว แต่จงทำให้ความล้มเหลวจริงเกิดขึ้น และค้นหาเงื่อนไขที่ไม่ถูกควบคุมซึ่งทำให้บั๊กที่เกิดเป็นครั้งคราวปรากฏ
- บันทึกทุกอย่าง อย่าเชื่อสถิติมากเกินไป และยอมรับว่าสิ่งที่เกิดขึ้นน้อยก็อาจเกิดขึ้นจริงได้
- อย่าทิ้งเครื่องมือดีบัก แต่จงใช้มันเพื่อทำให้ปัญหาปรากฏชัด
-
หยุดคิดแล้วดู
- ก่อนจะเริ่มซ่อมแบบซับซ้อนจากการคาดเดา ให้หา ข้อมูลที่สังเกตได้จริง ก่อน
- ตรวจดูความล้มเหลวและรายละเอียดต่างๆ พร้อมสร้างการวัดจากภายในหรือเพิ่มการวัดจากภายนอก
- อย่าหลีกเลี่ยงการขุดลึกลงไป แต่ต้องระวังผลแบบ Heisenberg ที่การสังเกตเองอาจเปลี่ยนพฤติกรรมการทำงานได้
- ใช้การคาดเดาเป็นเพียงเครื่องมือช่วยตีวงการค้นหาให้แคบลง ไม่ใช่ข้อสรุป
-
แบ่งแล้วพิชิต
- ใช้การประมาณค่าแบบต่อเนื่อง (successive approximation) เพื่อลดขอบเขตการค้นหา และตัดสินว่าบั๊กอยู่ฝั่งไหน
- ใช้รูปแบบการทดสอบที่สังเกตได้ง่าย และเริ่มจากสภาวะที่ผิดเพื่อค่อยๆ หาสาเหตุให้แคบลง
- กำจัดบั๊กที่รู้อยู่แล้วและสัญญาณรบกวนออกก่อน เพื่อให้สิ่งที่ต้องสืบสวนง่ายขึ้น
-
เปลี่ยนทีละอย่าง
- แยกปัจจัยหลักออกจากกัน และทำความเข้าใจก่อนว่าผิดตรงไหนก่อนลงมือแก้
- เปลี่ยนการทดสอบทีละอย่าง และเปรียบเทียบกับกรณีปกติ
- ตรวจสอบว่านับจากครั้งสุดท้ายที่มันยังทำงานได้ มีอะไรเปลี่ยนไปบ้าง
-
จงเก็บร่องรอยตรวจสอบไว้
- บันทึกว่าได้ทำอะไรบ้าง ตามลำดับไหน และผลเป็นอย่างไรในรูปของ audit trail
- แม้รายละเอียดเล็กน้อยที่ดูไม่สำคัญก็อาจเป็นสาเหตุได้ จึงควรเชื่อมโยงเหตุการณ์ต่างๆ แล้วจดไว้
- audit trail ของกระบวนการออกแบบเองก็ช่วยในการทดสอบได้ จึงต้องบันทึกไว้ด้วย
-
ตรวจปลั๊กก่อน
- ตั้งข้อสงสัยกับสมมติฐานที่คิดว่าแน่นอน และกลับไปตรวจใหม่ตั้งแต่ต้น
- แม้แต่เครื่องมือที่ใช้ค้นหาปัญหาเองก็ต้องรวมอยู่ในขอบเขตของสิ่งที่ต้องทดสอบ
-
หามุมมองใหม่
- เมื่อคิดคนเดียวแล้วตัน ให้ลองรับข้อมูลเชิงลึกใหม่จากคนอื่น หรือจากวิธีอธิบายอีกแบบหนึ่ง
- แค่ลองอธิบายปัญหาให้หุ่นจำลองฟังก็อาจช่วยจัดระเบียบความคิดได้
- ใช้ประโยชน์จากความเชี่ยวชาญ รับฟังผู้มีประสบการณ์ และให้ความสำคัญกับการแบ่งปันอาการกับการขอความช่วยเหลือมากกว่าอัตตา
-
ถ้ายังไม่ได้แก้ ก็แปลว่ายังไม่หาย
- หลังแก้ไขแล้ว ต้องตรวจสอบว่าแก้ได้จริงหรือไม่ และยืนยันว่าการเปลี่ยนแปลงของเรากำจัดสาเหตุที่แท้จริงได้จริง
- ปัญหาไม่ได้หายไปเอง ดังนั้นต้องแก้ทั้งสาเหตุและกระบวนการร่วมกัน
วิธีที่กรณีศึกษาช่วยให้หลักการมีชีวิต
- ถ้ามองแค่รายการกฎอาจดูแห้งแล้ง แต่คำอธิบายอย่างละเอียดและ เรื่องเล่ากรณีศึกษา ช่วยดึงหลักการลงสู่สถานการณ์จริง
- หลายกรณีลงลึกถึงรายละเอียดทางเทคนิค จึงอาจหนักไปสำหรับผู้อ่านบางคน
- แม้จะมีตัวอย่างที่ใช้เทคโนโลยีเก่า แต่หัวใจอยู่ที่หลักการ ไม่ใช่เทคโนโลยีเฉพาะ จึงไม่ใช่ปัญหาใหญ่
- ไม่ใช่ทุกกรณีศึกษาจะเกี่ยวกับคอมพิวเตอร์ และยังมีกรณีสนุกๆ เกี่ยวกับการเดินสายไฟในบ้านด้วย
- หากไม่มีพื้นฐานฮาร์ดแวร์และซอฟต์แวร์คอมพิวเตอร์เลย อาจตามตัวอย่างจำนวนมากได้ยาก
- หลังคำอธิบายของแต่ละกฎ ยังมีเรื่องเล่าที่ใช้หลายกฎร่วมกัน แบบฝึกหัดง่ายๆ สำหรับผู้อ่าน เคล็ดลับจาก help desk และคำกล่าวสรุปตามมา
จุดเด่นและข้อจำกัดที่เห็นชัด
- หลักการ “หยุดคิดแล้วดู” สำคัญเป็นพิเศษ
- เพราะหลายคนพยายามแก้ปัญหาจากการคาดเดาก่อนจะรวบรวมข้อมูลที่จะใช้พิสูจน์หรือหักล้างสมมติฐาน
- “ถ้ายังไม่ได้แก้ ก็แปลว่ายังไม่หาย” ก็เป็นอีกหลักการที่ทิ้งความประทับใจอย่างมาก
- เพราะไม่ใช่แค่ต้องตรวจว่าแก้แล้วหรือยัง แต่ต้องรู้ด้วยว่าอะไรคือสาเหตุ และทำไมมันจึงถูกแก้ได้
- ประเด็น “กระตุ้นให้ความล้มเหลวเกิดขึ้น อย่าจำลองความล้มเหลว” อธิบายได้ไม่ชัดเท่าส่วนอื่นของหนังสือ แต่ก็ยังเป็นจุดที่ควรค่าแก่การทำความเข้าใจ
- ปัญหาที่เกิดเป็นครั้งคราวมักจัดการยากที่สุด และหนังสือเล่มนี้ให้คำแนะนำตรงไปตรงมาในการรับมือผ่าน Make it Fail
- มีการกล่าวถึง Heisenberg แต่ไม่ได้พูดถึงคำที่ใช้กันบ่อยในงานพัฒนาซอฟต์แวร์อย่าง Heisenbug
- Heisenbug หมายถึงบั๊กที่หายไปหรือเปลี่ยนพฤติกรรมเมื่อพยายามสังเกตหรือแยกมันออกมาตรวจ
ความต่างจากแหล่งข้อมูลอื่น
- หนังสือเล่มนี้แตกต่างจากคู่มือเครื่องมือหรือหนังสือเรื่องเทสต์ตรงที่เน้น หลักการพื้นฐานของการดีบัก เป็นศูนย์กลาง
- Debugging with GDB: The GNU Source-Level Debugger ของ Richard Stallman และคนอื่นๆ อธิบายเทคนิคหรือคำสั่งของเครื่องมือเฉพาะเป็นหลัก
- แม้จะมีแหล่งข้อมูลที่รวมคำแนะนำทั่วไปอย่าง Guide to Faster, Less Frustrating Debugging ของ Norman Matloff แต่ก็ยังไม่ครอบคลุมกว้างเท่าหนังสือของ Agans
- หนังสือด้านเทสต์อย่าง Software Testing Techniques ของ Boris Beizer เน้นการเขียนเทสต์เพื่อค้นหาบั๊ก ขณะที่วิธีแก้บั๊กที่พบแล้วถูกกล่าวถึงน้อยกว่า
- หลังพบบั๊กแล้ว ควรเพิ่มเทสต์ของบั๊กนั้นเข้าไปใน regression test suite แต่เรื่องการทดสอบและ regression test อยู่นอกขอบเขตของหนังสือเล่มนี้
แหล่งเสริมและจุดที่น่าเสียดาย
- เว็บไซต์คู่หนังสือ debuggingrules.com มีลิงก์ข้อมูลที่เกี่ยวข้อง และโปสเตอร์กฎทั้ง 9 ข้อที่ดาวน์โหลดไปพิมพ์ได้
- น่าเสียดายที่ รายการกฎย่อยทั้งหมด ซึ่งสำคัญต่อการทำความเข้าใจกฎหลัก ไม่ได้ถูกรวบรวมไว้ในหน้าเดียวทั้งในหนังสือหรือบนเว็บไซต์
- ถ้ามีคำแนะนำและตัวอย่างที่เฉพาะเจาะจงกว่านี้เกี่ยวกับเครื่องมือทั่วไปและประเภทปัญหา เช่น symbolic debugger, digital logic probe หรือ ddd on gdb ก็จะมีประโยชน์มากขึ้น
- ดูเหมือนว่าจะควรมีหนังสืออีกเล่มที่ขยายกฎชุดเดียวกันนี้ไปสู่การแก้ปัญหาทั่วไปนอกโลกคอมพิวเตอร์ แต่กรณีศึกษาของหนังสือเล่มนี้มีความเทคนิคมากเกินไปสำหรับผู้อ่านที่ไม่ใช่สายคอมพิวเตอร์
- หลักการพื้นฐานเหล่านี้แม้ภายนอกจะดูเหมือนสามัญสำนึก แต่ผู้เริ่มต้นจำเป็นต้องเรียนรู้ และผู้มีประสบการณ์ก็ต้องคอยทบทวนซ้ำๆ ซึ่งหนังสือเล่มนี้เหมาะกับทั้งการเรียนรู้และการทบทวนดังกล่าว
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ผมคิดว่าสิ่งที่เป็นพิษที่สุดคือความเย้ายวนที่จะเติม “การแก้ไข” ลงไปใน โค้ดที่พังอยู่แล้ว เพื่อให้มันทำงานได้
โค้ดที่พังมีจุดที่เปลี่ยนได้มากเกินไปจนแก้ยาก และการทำให้โค้ดที่ทำงานอยู่พังนั้นง่ายกว่ามาก
วิธีไล่เปลี่ยนหลอดไฟทีละดวงเมื่อไฟคริสต์มาสทั้งสายไม่ติด จะล้มเหลวถ้ามีหลอดเสียหลายดวง
แทนที่จะทำแบบนั้น ควรเริ่มจาก ตัวอย่างขั้นต่ำที่ทำงานได้ แล้วค่อย ๆ เพิ่มเข้าไปจนเจอจุดที่เกิดข้อผิดพลาด และในทางปฏิบัติ บ่อยครั้งการเริ่มใหม่ตั้งแต่ต้นกลับช่วยประหยัดเวลาได้มากกว่า
เคยมีกรณีปัญหาในโปรดักชันที่จับได้ยาก สมาชิกทีมบางคนเขียนรูทีนที่มีปัญหาใหม่ และเวอร์ชันที่เขียนใหม่นั้นถูกปล่อยใช้งานก่อน ในขณะที่คนอื่น ๆ ยังดีบักอยู่
อย่างน้อยครั้งหนึ่ง เราไม่สามารถใช้เวลากับปัญหาที่ “แก้แล้ว” ได้ไม่จำกัด จึงไม่เคยหาบั๊กเดิมเจอจนจบ
กฎข้อ 0 คือ อย่าตื่นตระหนก
เดดไลน์และลูกค้าที่โกรธจะขัดขวางการคิดอย่างชัดเจน ดังนั้นผู้จัดการที่ดีและไว้ใจได้ควรกันวิศวกรออกจากแรงกดดันนั้น เพื่อให้พวกเขาโฟกัสกับการแก้ปัญหาได้
ผู้จัดการที่ดีคนหนึ่งย้ายพวกเราไปอีกสายแล้วบอกว่า “ไม่ต้องสนใจที่คนพวกนั้นพูด ตั้งสมาธิไป เดี๋ยวผมจัดการเอง” หลังจากนั้นความเคารพที่มีต่อผู้จัดการคนนั้นก็เพิ่มขึ้นมาก
ถ้าไม่มีเวลาทำให้ถูกต้อง แล้วทำไมถึงคิดว่าจะมีเวลาทำซ้ำสองรอบ
หมายถึงบทบาทที่คอยกันสิ่งที่หล่นลงมาจากข้างบน เพื่อให้วิศวกรโฟกัสกับงานหลักได้
ถ้าย้อนกลับไปยังเวอร์ชันที่ทำงานได้ แล้วดีบักโดยไม่ต้องเจอแรงกดดันระดับวิกฤตได้ จะดีกว่ามาก
สำหรับข้อ 4 “แบ่งแล้วพิชิต”
git bisectช่วยได้มากถ้ามีคอมมิตที่ปกติหนึ่งอัน และในบรรดาคอมมิตถัดมาอีกหลายสิบถึงหลายร้อยอันมีคอมมิตเสียอยู่หนึ่งอัน ก็สามารถตีวงคอมมิตหรือโค้ดที่เป็นปัญหาให้แคบลงได้ในไม่กี่ขั้น
ตัวอย่างการใช้งานอยู่ที่ https://nickjanetakis.com/blog/using-git-bisect-to-help-find...
ผมเคยใช้วิธีนี้ตีวงปัญหาในโค้ดเบสขนาดใหญ่ที่ไม่คุ้นเคยได้อย่างรวดเร็วระหว่างให้คำปรึกษาแบบสด ๆ ไม่อย่างนั้นขอบเขตที่อาจพังได้คงกว้างเกินไปมาก
git bisectผมจึงรักษาวินัยว่า ทุกคอมมิตที่เข้าไปในแบรนช์ “จริง” ต้อง build ได้เป็นรายคอมมิต ผ่านเทสต์ที่รู้จักในเวลานั้น และตามความรู้ที่มีควร deploy ได้ผมให้ความสำคัญกับเรื่องนี้มากกว่าหลักการอย่างการเก็บทุกการกดคีย์ไว้ หรือคงคอมมิต “Fixes.” สุดท้ายเอาไว้ เพราะหลักการแบบนั้นทำให้การค้นหาแบบทวิภาคใช้การไม่ได้
ไม่ได้ใช้บ่อยนัก แต่กับบั๊กที่ใหญ่และลึกลับที่สุด แค่ใช้ถูกสักครั้งก็ให้เบาะแสที่เทียบเท่าหลายวันในคราวเดียว จึงคุ้มค่ามากพอ
git bisectให้คือวิธี เปรียบเทียบระบบที่พังกับระบบที่ทำงานได้ แล้วกำจัดความแตกต่างอย่างเป็นระบบเพื่อหาข้อบกพร่อง
ใช้ได้ไม่ใช่แค่กับซอฟต์แวร์หรือฮาร์ดแวร์ และเมื่อก่อนตอนมีเจ็ตสกีรุ่นเดียวกันสองลำ การซ่อมลำหนึ่งโดยเทียบกับอีกลำก็ช่วยได้มาก
git bisectเอง แต่เป็นหลักการ ค้นหาแบบทวิภาค ที่ทั่วไปกว่าใช้ได้ไม่เพียงกับช่วงของคอมมิต แต่ยังใช้แบ่งพื้นที่ของระบบได้ด้วย
ตัวอย่างเช่น ถ้าเวิร์กโฟลว์ 10 ขั้นตอนพัง ก็ตรวจว่าขั้นที่ 5 ยังปกติไหม หรือค่อย ๆ ตีวงว่าเป็นปัญหาฮาร์ดแวร์หรือไม่ใช่
เรื่องนี้สำคัญเป็นพิเศษเมื่อสาเหตุของปัญหาอาจไม่ใช่คอมมิตของโค้ดในรีโพซิทอรีที่กำลัง bisect อยู่
bisectยอดเยี่ยม แต่ต้องแยกระหว่าง “กฎ” ซึ่งเป็น ปรัชญาและวิธีคิด ของหนังสือเล่มนี้ กับ “เครื่องมือ” ซึ่งเป็นคำแนะนำเชิงปฏิบัติคนที่เริ่มจากคำถามว่า “จะใช้เครื่องมืออะไรดี” เสียเปรียบคนที่เริ่มจาก “อันนี้เมื่อก่อนมันไม่ได้ทำงานอยู่เหรอ?”
โลกเต็มไปด้วยเครื่องมือ และถ้าพยายามเก็บเครื่องมือทั้งหมดไว้ในหัวก็คงเป็นบ้าไปก่อน ดังนั้นรับเอาปรัชญาไว้ก่อนจะดีกว่า
git bisect runเป็นเครื่องมือเล็ก ๆ ที่น่าทึ่งจริง ๆhttps://andrewrepp.com/git_bisect_run
ต้องแน่ใจว่ากำลังแก้ ไฟล์ที่ถูกต้อง บน เครื่องที่ถูกต้อง
ทุกวันนี้ผมมักเพิ่มบรรทัดที่จงใจให้เกิดข้อผิดพลาดร้ายแรงชั่วคราว เพื่อยืนยันว่าไฟล์ที่แก้อยู่ถูกต้อง และในบางกรณีก็ยืนยันว่าบรรทัดถูกต้องด้วย
เพื่อยืนยันว่าการเปลี่ยนแปลงของเรามีผลจริง
มีกฎเพิ่มเติมอยู่
“ทั้งหมดเป็นความผิดของฉันเอง”: อาจเป็นบั๊กของคอมไพเลอร์หรือข้อผิดพลาดของฮาร์ดแวร์ก็ได้ แต่พบได้น้อยมาก ดังนั้นก่อนอื่นควรสงสัยการเปลี่ยนแปลงในโค้ดของตัวเองก่อน
“ถ้าเจอบั๊ก ให้ตามหาครอบครัวและเพื่อน ๆ ของมันด้วย”: ต้องคิดและตรวจสอบว่าสิ่งประเภทเดียวกันอาจเกิดขึ้นที่ไหนอีกบ้าง
“ปรับให้เหมาะที่สุดเพื่อผู้ใช้ก่อน โปรแกรมเมอร์ที่ดูแลรักษาเป็นลำดับสอง และคอมพิวเตอร์เป็นลำดับสุดท้าย”
มีสรุปอยู่ที่ https://blog.codinghorror.com/the-first-rule-of-programming-...
โดยปกติระหว่างกระบวนการลดโค้ดที่ทำให้เกิดข้อผิดพลาดให้เหลือกรณีที่ง่ายขึ้น จะพบว่าบั๊กอยู่ในตรรกะของตัวเอง
มีครั้งสองครั้งที่เหลือผลลัพธ์ที่ควรรายงานให้นักพัฒนาจริง ๆ และส่วนใหญ่เป็นไลบรารีที่มีผู้ใช้ไม่เกินหลักร้อยจึงมีการทดสอบไม่มาก
สุดท้ายพอรู้ว่าไม่ใช่ข้อผิดพลาดในโค้ดที่ดูเป็นไปไม่ได้ แต่เป็นปัญหาของ CPU ก็โล่งใจมาก
ถึงอย่างนั้น สิ่งที่ดีที่สุดคือทำ binary search ไล่หาสายโซ่เหตุ-ผลเพิ่มอีกสักสองสามรอบเพื่อให้แน่ใจ
คำแนะนำที่ว่า “จงเข้าใจระบบ: อ่านคู่มือ อ่านทุกอย่างอย่างลึกซึ้ง รู้พื้นฐาน รู้ roadmap เข้าใจเครื่องมือ และค้นหารายละเอียด” ฟังดูค่อนข้างแปลก
ถ้ามีบั๊กในโค้ด มันดูเหมือนหมายความว่าต้องอ่านคู่มือ 700 หน้าของไลบรารีที่ใช้ทั้งหมดก่อน อ่านหนังสือที่เกี่ยวข้องอีก 7 เล่ม แล้วอีกหนึ่งหรือสองเดือนค่อยไปดูบั๊ก
ผมสงสัยว่ามีโปรแกรมเมอร์สักคนไหมที่ทำตามคำแนะนำนี้จริง ๆ
Atwood กับ Spolsky สร้าง Stack Overflow ในปี 2008 และเป็นยุคที่ผู้คนรู้จักหนังสือด้วยชื่ออย่าง “Camel book” และมีความรู้อยู่แล้ว
0. https://stackoverflow.blog/2021/12/14/podcast-400-an-oral-hi...
“อ่านทุกอย่างอย่างลึกซึ้ง” ไม่ได้จำเป็นต้องหมายความว่า “อ่านคู่มือ 700 หน้าทั้งหมดของไลบรารีที่ใช้ก่อน”
ถ้ามีปัญหากับ
git bisectแทนที่จะเอาเศษคำตอบจาก Stack Overflow มาต่อกันสองสามชิ้น ก็สามารถทำความเข้าใจหัวข้อนั้นให้ลึกขึ้นอีกหน่อยได้ที่ https://git-scm.com/docs/git-bisectเพียงแต่ความผิดพลาดคือการคิดว่าผลงานของการทำงานหลายเดือนคือการแก้บั๊กเดียวแบบคร่าว ๆ
เป้าหมายคือการแก้บั๊กประเภทนั้นให้หมดเท่าที่ทำได้จริง ๆ และทำให้ไม่ต้องเขียนมันขึ้นมาตั้งแต่แรก
ทางเลือกคือกระโดดร่มลงไปในระบบที่ไม่รู้จัก แตะนั่นแตะนี่โดยไม่เข้าใจ พอ test เป็นสีเขียวก็เปิด PR แล้วหวังว่าจะไม่ได้ทำให้พังยิ่งกว่าเดิม ซึ่งการต้องทำแบบนั้นเป็นกิจวัตรแทบจะเป็นฝันร้าย
อีกอย่าง ถ้าคู่มือของไลบรารีที่ใช้อยู่มี 700 หน้า ก็มีความเป็นไปได้สูงว่าคุณอาจกำลังใช้ไลบรารีผิดตัว
ในฐานะขั้นตอนที่ 10 ไม่ควรเพิ่มบั๊กเข้าไปใน CI test เพื่อป้องกัน regression หรือ
ต้องตรวจสอบว่าก่อนแก้ CI ล้มเหลว และหลังแก้แล้วผ่าน
โดยเฉพาะเพราะมี commit ที่เก่ากว่า 5 ปี และเพราะเป็น component/library จึงมี hack แปลก ๆ สำหรับ IE อยู่ไม่น้อย
บาง test ใช้เวลานานหรือซับซ้อนในการเขียน และยังต้องดูแลรักษา อีกทั้งต้องยอมรับด้วยว่าชุด test ไม่สามารถตรวจสอบเงื่อนไขขอบเขตทั้งหมดได้
นั่นอาจหมายความว่าบั๊กที่ไปถึง production อาจกลับมาเกิดอีก แต่ถ้าเป็นความผิดพลาดง่าย ๆ ก็อาจไม่ได้มีโอกาสเกิดซ้ำสูงกว่าความผิดพลาดที่อาจเกิดขึ้นอีกเป็นร้อยแบบ
สุดท้ายก็ขึ้นอยู่กับสถานการณ์ และการเขียน test ไม่ได้ฟรี
เห็นมานับครั้งไม่ถ้วนว่าต้นเหตุเชิงลึกถูกเปิดใช้งานอีกครั้งจนปัญหาเดิมกลับมา หรือไม่มีใครรู้ว่าผมแก้ไปแล้ว ทุกคนจึงยังใช้ workaround ต่อไปราวกับบั๊กยังอยู่
แม้หลังจากไปถึงจุด “แก้แล้ว!” การทิ้งบันทึกสั้น ๆ และ root cause analysis ไว้ก็ช่วยคนอื่นได้
หลังจาก test สะสมมานาน CI จะรันได้เร็วแค่ไหน และในระยะยาวการเก็บไว้ต่อไปยังมีความหมายอยู่หรือไม่
หากอยากปลูกฝังวิธีคิดแบบนี้ให้เด็ก ๆ ให้ตัวเอง หรือให้คนอื่น ๆ อย่างน้อยก็ขอแนะนำสิ่งต่อไปนี้
The Martian by Andy Weir https://en.wikipedia.org/wiki/The_Martian_(Weir_novel)
https://en.wikipedia.org/wiki/Zen_and_the_Art_of_Motorcycle_...
https://en.wikipedia.org/wiki/The_Three-Body_Problem_(novel)
To Engineer Is Human - The Role of Failure in Successful Design By Henry Petroski
https://pressbooks.bccampus.ca/engineeringinsociety/front-ma...
https://en.wikipedia.org/wiki/Surely_You%27re_Joking,_Mr._Fe...!
โดยเฉพาะแนวคิดเรื่อง “gumption traps” นั้นดีมาก
ถ้าตกอยู่ในกับดักของความแข็งทื่อทางคุณค่า ยังไงก็ต้องช้าลงอยู่แล้ว จึงควรตั้งใจชะลอความเร็วลง ย้อนกลับไปดูจุดที่ผ่านมาว่าสิ่งที่เราเคยคิดว่าสำคัญนั้นสำคัญจริงหรือไม่
การแค่มองเครื่องจักรอยู่สักพักก็ไม่ใช่เรื่องผิด และประโยคที่ว่า หากเฝ้าดูเหมือนมองสายเบ็ด ก็จะมีช่วงเวลาที่ข้อเท็จจริงเล็ก ๆ ข้อหนึ่งค่อย ๆ ถามว่าเราสนใจมันไหมนั้น แทบจะเป็นหลักในการใช้ชีวิตเลย
มองว่าเหตุการณ์ต่าง ๆ แค่เกิดขึ้นจากการกระโดดทางตรรกะอย่างหยาบ ๆ และจริง ๆ แล้วใกล้เคียงกับแฟนตาซีที่คลุมทับด้วยการเล่นคำทางวิทยาศาสตร์แบบบางมาก ๆ
เมื่อหลายปีก่อนเคยเขียนบทความคล้าย ๆ กันไว้ ตอนนั้นยังไม่ได้อ่านหนังสือต้นฉบับที่กล่าวถึงในนี้
https://explog.in/notes/debugging.html
zine เรื่องการดีบักของ Julia Evans ก็ดีมากเช่นกัน: https://wizardzines.com/zines/debugging-guide/
แม้จะดีบักสำเร็จแล้ว งานก็ยังไม่จบ
แก่นของ “Three Questions About Each Bug You Find” <http://www.multicians.org/thvv/threeq.html> มีอยู่สามข้อ
ข้อผิดพลาดนี้มีอยู่ที่อื่นด้วยหรือไม่ บั๊กถัดไปที่ซ่อนอยู่เบื้องหลังบั๊กนี้คืออะไร และควรทำอะไรเพื่อป้องกันบั๊กแบบนี้