บั๊กที่แปลกที่สุดเท่าที่ฉันเคยเจอ
(engineering.gusto.com)การค้นพบบั๊กประหลาดและกระบวนการแก้ไข
- ระหว่างเข้าเวร on-call ของทีมเครื่องมือภายใน ผู้ใช้ที่ใช้งานซอฟต์แวร์ภายในของ Gusto พบปัญหาเบราว์เซอร์ Chrome ล่ม
- ปัญหานี้สร้างการรบกวนต่อการให้บริการลูกค้าในหลายด้าน
- เพื่อแก้ปัญหา จึงได้ความช่วยเหลือจากเพื่อนร่วมงานที่มีประสบการณ์ ทีมโครงสร้างพื้นฐานผลิตภัณฑ์ และทีม IT
เบาะแสแรก
- พยายามหาจุดร่วมของผู้ใช้ที่ได้รับผลกระทบ
- ไม่ใช่พนักงาน Gusto ทุกคนที่ได้รับผลกระทบ และซอฟต์แวร์ที่ต้องติดต่อกับลูกค้าโดยตรงก็ไม่มีปัญหา
- หน้าเว็บของซอฟต์แวร์ภายในอื่น ๆ ทำงานได้ตามปกติ
- การล่มเกิดขึ้นอย่างไม่สม่ำเสมอ และไม่พบปัญหาใน Safari หรือ Firefox
เบาะแสที่สอง
- ตั้งสมมติฐานว่าเวอร์ชันของ Chrome อาจเป็นปัญหา
- เมื่อผู้ใช้บางคนอัปเดต Chrome แล้ว ปัญหาดูเหมือนจะหายไป แต่ก็ไม่ได้แก้ได้สมบูรณ์
- เดาว่าส่วนขยายของ Chrome อาจเป็นสาเหตุ แต่ก็ยังทำให้เกิดปัญหาซ้ำได้แม้ไม่มีส่วนขยาย
ความยากในการทำให้บั๊กเกิดซ้ำ
- ทีมโครงสร้างพื้นฐานขอให้วิศวกรทุกคนลองทำให้ปัญหาเกิดซ้ำ
- ในทีมวิศวกร ไม่มีใครรายงานว่า Chrome ล่ม ยกเว้นวิศวกรสองคนในตุรกี
- ฟีเจอร์รายงานการล่มของ Chrome ถูกปิดไว้ด้วยเหตุผลด้านความปลอดภัย ทำให้แก้ปัญหาได้ยาก
จุดเปลี่ยนจากโชคช่วย
- วิศวกรคนหนึ่งในเดนเวอร์รายงานว่าปัญหาเริ่มเกิดหลังจากดาวน์โหลดแอปเดสก์ท็อป Grammarly
- พบว่าเมื่อลบแอป Grammarly และรีสตาร์ตคอมพิวเตอร์แล้ว ปัญหาก็หายไป
ความคืบหน้า
- เมื่อเริ่มดีบักได้ ก็ทดลองหลายอย่างเพื่อหาสาเหตุของปัญหา
- แอปพลิเคชันภายในหลักสร้างอยู่บนพื้นฐานของ ActiveAdmin แต่ส่วนใหม่ที่ใช้ React ไม่ทำให้เกิดการล่ม
- ระหว่างตรวจสอบโค้ดส่วนที่ใช้ร่วมกัน ก็พบว่าเมนูดรอปดาวน์ 'My History' เป็นสาเหตุของปัญหา
การแก้ปัญหา
- ยืนยันได้ว่าไฟล์รูปภาพ
loader-spinner.gifเป็นตัวก่อปัญหา - เมื่อเปลี่ยน GIF ดังกล่าวเป็นรูปภาพอื่น หน้าเพจก็ไม่ล่มอีกต่อไป
- ไม่แน่ชัดว่าเป็น Grammarly หรือ Chrome ที่แก้ปัญหานี้ เพราะตอนนี้ GIF เดิมก็ไม่ทำให้ Chrome ล่มแล้ว
บทสรุป
- GIF แบบเคลื่อนไหวที่ไม่มีใครคาดคิดกลับเป็นกุญแจของการดีบักครั้งนี้
- ปัญหาถูกแก้ไขได้ด้วยความช่างสงสัยและความร่วมมือ
- Gusto มอบโอกาสให้ได้ทำงานร่วมกับผู้คนที่ชอบร่วมมือและเปี่ยมด้วยความอยากรู้อยากเห็น
ความเห็นของ GN⁺
สิ่งสำคัญที่สุดในบทความนี้คือการอธิบายอย่างละเอียดถึงกระบวนการค้นพบและแก้ไขบั๊กที่มีสาเหตุมาจากสิ่งที่ไม่คาดคิด บทความนี้แสดงให้เห็นถึงความซับซ้อนและความคาดเดาไม่ได้ของวิศวกรรมซอฟต์แวร์ พร้อมทั้งเน้นย้ำว่าการทำงานเป็นทีมและความพากเพียรในการแก้ปัญหานั้นสำคัญเพียงใด นี่เป็นกรณีศึกษาที่น่าสนใจว่าทีมวิศวกรรมร่วมมือกันแก้ปัญหาที่เข้าใจได้ยากอย่างไร และเป็นเรื่องราวที่ดึงดูดมากสำหรับผู้ที่สนใจด้านวิศวกรรม
1 ความคิดเห็น
ความคิดเห็นใน Hacker News
ระหว่างอ่านอยู่ก็คิดว่าอาจเป็น ปัญหาเกี่ยวกับ Grammarly เพราะก่อนหน้านี้เคยเจอบั๊กที่มีอาการคล้ายกัน คือทำซ้ำไม่ได้ แต่ส่งผลกระทบกับคนจำนวนมากในแผนกหนึ่ง
สุดท้ายจุดร่วมคือการติดตั้ง ส่วนขยาย Grammarly และเกิดเฉพาะบน URL พรีวิวของ staging ไม่ใช่ไซต์ใช้งานจริง
สาเหตุคือ regex ที่ผิดพลาดในส่วนขยาย Grammarly และเมื่อชื่อโดเมนยาวเกินประมาณ 100 ตัวอักษร หน้าเว็บก็จะค้าง
ถ้าเคสนี้เกิดจากแอปเดสก์ท็อปจริง ๆ ก็รู้สึกน่ากลัวยิ่งกว่าเดิม
ปัญหาหลายอย่างถูกไล่จนแคบลงถึงชุดเงื่อนไขเฉพาะได้ แต่ถ้าไม่รู้ว่า ทำไมถึงเป็นแบบนั้น ก็ยังไม่ค่อยน่าพอใจ
เลยกำลังอ่านเรื่องเอนจิน regex อยู่: https://swtch.com/%7Ersc/regexp/regexp1.html
ระหว่างการอัปเกรด Windows 10 ทั่วทั้งบริษัท เราเปลี่ยนแล็ปท็อปเก่าของผู้จัดการคนหนึ่ง ขั้นตอนต่าง ๆ อย่างการตรวจสอบข้อกำหนดของซอฟต์แวร์และเครือข่าย การสำรองโปรไฟล์ผู้ใช้กับเอกสารก็เตรียมไว้ดี
ในแบบประเมินอุปกรณ์มีโน้ตว่าเป็น ThinkPad อายุ 10 ปี, RAM 4GB และถ้าถอดสายไฟจะดับ ดูแล้วนับถือความอดทนของเขาที่ใช้มันต่อมาได้
หลังแจกแล็ปท็อปใหม่ เกือบทุกอย่างทำงานปกติ เหลือแค่การย้ายไลเซนส์ Grammarly ที่ยังไม่ได้ จึงส่งคำขอไป และอีกหนึ่งสัปดาห์ต่อมาก็ใส่ license key ได้ ตรวจสอบแล้วว่า Grammarly ใช้งานได้ปกติ
แต่ต่อมาในวันนั้นเขาติดต่อมาว่าหน้าเว็บกล้องรักษาความปลอดภัยแครช ฝ่าย helpdesk ลองรีบูต ล้างแคช ติดตั้งเบราว์เซอร์ใหม่ ไปจนถึงสร้างโปรไฟล์ใหม่แล้วก็ยังแก้ไม่ได้ จึงส่งต่อมาให้ผม
ผมตรวจทั้งเครือข่าย log ของไฟร์วอลล์ พีซีเครื่องอื่น การเข้าจากหน้างาน/ภายนอก แต่ฝั่งผมทุกอย่างปกติ และคนอื่นก็ไม่มีปัญหา
พอถามว่า “ช่วงนี้มีอะไรเปลี่ยนในพีซีหรือออฟฟิศไหม” เขาก็พูดติดตลกว่า “วันนี้ติดตั้ง Grammarly ไป หรือจะเป็นอันนั้น?” พอไอเดียหมดแล้วเลยลองถอนออกจริง ๆ ปรากฏว่าใช้งานได้
พอเปิด Grammarly อีกครั้งแล้วกดลิงก์ ก็ล้มเหลวชัดเจน
ซอฟต์แวร์กล้องตัวนั้นเก่ามาก และลิงก์โฮมเพจแบบปรับแต่งเองมีหน้าตาเหมือน URL ที่ PHP สร้างขึ้นและยาวมาก อีกทั้งในหน้างานมีแค่เขาคนเดียวที่ใช้ Grammarly เลยเป็นปัญหาที่โผล่มาให้เห็นเพียงครั้งเดียว
นักพัฒนามักลืมคิดว่าส่วนขยายอาจเป็นสาเหตุได้ แต่ส่วนขยายสามารถทำสารพัดอย่างกับหน้าเว็บได้
อาจารย์มหาวิทยาลัยคนหนึ่งบอกว่าระหว่างเขียน论文 เส้นใต้ไม่คงอยู่ ผมคิดว่าเป็นความผิดพลาดของผู้ใช้ธรรมดา ๆ และน่าจะช่วยได้ใน 5 นาที
แต่ผ่านไปกว่า 3 ชั่วโมงถึงพบว่า การผสมกันของ เวอร์ชันไดรเวอร์การ์ดจอ เฉพาะกับ เวอร์ชันไดรเวอร์เครื่องพิมพ์ เฉพาะ ทำให้เฉพาะการพิมพ์เส้นใต้ไม่ออก
https://www.zdnet.com/article/xerox-scanners-alter-numbers-i...
แม้จะปิด crash reporting ไว้ ก็ยังมีความเป็นไปได้ว่าจะมีไฟล์ .dmp ถูกสร้างไว้ที่ไหนสักแห่งในไดเรกทอรีโปรไฟล์ผู้ใช้
ถ้าอัปโหลดไฟล์นั้นด้วยตนเองไปยังบั๊กที่ https://crbug.com/new นักพัฒนา Chrome ก็จะดีบักได้
หากไม่สามารถแชร์ dump ได้ด้วยเหตุผลคล้ายกับที่ปิด crash reporting ไว้ ก็สามารถ build
minidump_stackwalkจาก Chromium เพื่อสร้าง stack trace แบบไม่มี symbol แล้วแนบในบั๊กได้จากนั้นนักพัฒนา Chrome จะผูก symbol ให้ได้
รายละเอียดอยู่ที่ https://www.chromium.org/developers/decoding-crash-dumps/
ชุดเทคโนโลยีที่ทำให้เกิดบั๊กนี้น่าสนใจมาก เว็บในปี 2023 ก็ประมาณนี้แหละ
อยากรู้ว่าบั๊กของ Chromium แก้แล้วหรือยัง แต่ไล่ดูรายการนี้ไม่ง่ายเลย: https://bugs.chromium.org/p/chromium/issues/list?can=1&q=gif...
ผมชอบความรู้สึกที่ Gusto โพสต์บทความนี้เพื่อแสดงว่า “ไม่ใช่ความผิดเรา” พร้อมแซะ Grammarly แบบเบา ๆ
เคยมีปัญหาที่บางครั้งบูตเข้า Linux แล้วไม่มีเสียง ปรากฏว่าเกี่ยวข้องกับการตั้งค่า dual boot กับ Windows
ถ้ารีสตาร์ตจาก Windows มันจะไม่ปิดอุปกรณ์เสียง Realtek อย่างสมบูรณ์ แต่ปล่อยไว้แค่ในสถานะประหยัดพลังงาน แล้ว Linux ก็เริ่มใช้อุปกรณ์นั้นไม่ได้
วิธีแก้มีเพียงต้องปิดเครื่องจาก Windows เสมอ แล้วกดปุ่มเปิดเครื่องเพื่อเปิดใหม่ และปัญหานี้ก็ยังคงอยู่: https://askubuntu.com/questions/1032543/no-sound-in-ubuntu-1...
คนที่ dual boot Windows กับ Linux ต้องบูตเข้า Windows ก่อนแล้วรีสตาร์ตเข้า Linux เท่านั้น Wi‑Fi ถึงจะใช้งานได้
เพราะการติดตั้ง Linux ไม่มี แพ็กเกจเฟิร์มแวร์ สำหรับการ์ด Wi‑Fi พอรีบูตจาก Windows อุปกรณ์จึงอยู่ในสถานะพร้อมแล้ว แต่ถ้า cold boot เข้า Linux โดยตรงจะใช้ไม่ได้
เห็นด้วยว่าตอนจบทำให้กร่อยอย่างสิ้นเชิง
มันออกแนวว่าเข้าถึงซอร์สโค้ดของ Chrome ก็ไม่ได้ ซอร์สโค้ดของ Grammarly ก็ไม่ได้ เลยทำได้แค่เดา ซึ่งก็ชวนสงสัยว่านี่เป็นผลลัพธ์ที่ขบวนการ “โอเพนซอร์ส” สร้างขึ้นมาหรือเปล่า
กลายเป็นว่ามีนักพัฒนาที่พอไม่มีซอร์สโค้ดแล้วก็หลงทางไปหมด และปฏิเสธที่จะขุดลึกต่อ สำหรับบริษัทที่ไม่อยากให้ความจริงถูกเปิดเผย ท่าทีแบบนี้คงน่ายินดีมาก
สมัยก่อนมีคนจำนวนมากที่ disassemble โปรแกรม ทำความเข้าใจ และแพตช์ได้แม้ไม่มีซอร์สโค้ด และหลายคนในนั้นก็ไม่ใช่นักพัฒนาอาชีพด้วยซ้ำ
แค่มีแรงจูงใจอยากทำให้ซอฟต์แวร์ทำงานอย่างที่ต้องการ แล้วระหว่างทางก็เรียนรู้เท่าที่จำเป็นไปเอง
บทความนี้ยังแตะประเด็นว่าความซับซ้อนของทั้งสแตกมันบ้าคลั่งแค่ไหนด้วย พอเห็น framework ซ้อน framework ต่อกันเป็นทอด ๆ ก็รู้สึกว่าส่วนใหญ่เป็นเรื่องที่สร้างปัญหาให้ตัวเอง
เขาว่าแค่ลบ
loader-spinner.gifหรือ placeholder ที่แสดงระหว่างโหลดตัวเลือกเมนูออก หน้าเว็บก็หยุดแครชแล้ว แต่ก็ชวนสงสัยเหมือนกันว่าการโหลดตัวเลือกเมนูมันใช้เวลานานถึงขั้นต้องมีแอนิเมชันเลยหรือโลกของวิศวกรรมซอฟต์แวร์กว้างใหญ่มาก และการรู้ทุกส่วนของสแตกก็แทบเป็นไปไม่ได้มานานแล้ว
อีกอย่าง วิศวกรรมซอฟต์แวร์คือเส้นทางแห่งการเรียนรู้ และแต่ละคนก็อยู่คนละจุดบนเส้นทางนั้น
ไม่ต้องพูดถึงการเปิด disassembler หรือแนบ debugger เลย ทักษะแบบนั้นดูเหมือนตอนนี้แทบไม่ได้สอนกันแล้ว
โดยปกติอาจเสร็จแทบจะทันที แต่การมี loading spinner ไว้เผื่อกรณีใช้เวลานานก็สมเหตุสมผล
เรื่องที่แปลกที่สุดคือมีผู้ใช้คนหนึ่งบอกว่าข้อความที่ป้อนในฟอร์มบางอันเปลี่ยนไปเมื่อบันทึก
ตอนแรกคิดว่ามีคนอื่นแก้ไขฟอร์มเดียวกันพร้อมกัน แต่ดูจากล็อกแล้วไม่ใช่ และบนคอมพิวเตอร์ของผมก็เห็นข้อความถูกต้อง
ต่อมาสังเกตจากภาพหน้าจอว่าข้อความในเมนูบางส่วนก็แปลกไปด้วย สาเหตุคือเปิดตัวเลือก “แปลหน้านี้” ของ Chrome ไว้
พอบอกวิธีเปลี่ยนภาษาอย่างถูกต้องภายในแอป ปัญหาก็หายไป
ดูเหมือนว่านี่คือคำสั่งใหม่ที่ใช้กับแอปหรือ element ได้ คงไม่ใช่ CSS เพราะไม่อยากรองรับการเปลี่ยนแบบไดนามิก และหน้าตาก็น่าเกลียด: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_att...
บางครั้งพอไปดู meta tag ของแอป single-page ขนาดใหญ่ แล้วพยายามหาว่าแท็กนั้นจำเป็นไปทำไม ก็ได้เจอความสยองใหม่ ๆ อยู่เรื่อย
เวลาอ่านเว็บไซต์ภาษาญี่ปุ่น ผมพึ่ง Google Translate บ่อยมาก แต่ทุกเว็บไซต์ที่ใช้ React จะพัง
เพราะ React กับ Google Translate ต่างก็พยายามอัปเดต DOM node โดยไม่รู้กันและกัน
ภายหลังผมถึงขั้นไปดู implementation ของ Google Translate อย่างจริงจัง เพื่อดูว่าจะสร้างเว็บวิดเจ็ตที่ไม่มีปัญหานี้ขึ้นมาใหม่ได้ไหม
[1] https://bugs.chromium.org/p/chromium/issues/detail?id=872770
เป็นปัญหาที่คุ้นเคยเกินไป
เมื่อก่อนเคยเห็น เครื่องมือการเข้าถึง ของ Chrome ทำให้เกิดปัญหาแบบนี้กับเมนู dropdown และถึงขั้นทำซ้ำได้ด้วย HTML ขนาดเล็กมาก ๆ
bug เฉพาะที่ผมเจอเมื่อ 2 ปีก่อนอยู่ใน Chromium-Edge แต่อาการและสาเหตุคล้ายกันมาก
Grammarly แทบจะแน่นอนว่าพึ่งพาบางส่วนของเครื่องมือการเข้าถึงของ Chrome อยู่
เครื่องมือแบบนี้แตกต่างกันเล็กน้อยในแต่ละสาย Chromium อย่าง Edge, Brave, Chrome
ถ้าเกิดเรื่องแบบนี้อีกครั้ง แนะนำให้ให้ใช้เบราว์เซอร์อื่นไปเลย
โดยเฉพาะ Firefox ที่ตอนนี้ฟีเจอร์นำเข้า bookmark, password ฯลฯ จาก Chrome ดีขึ้นมาก
จักรวาลกำลังส่ง สัญญาณ ว่าถึงเวลาเปลี่ยนแล้ว และเราคงปฏิเสธสัญญาณไม่ได้
อนึ่ง ผมเป็นวิศวกร Firefox แต่ไม่เกี่ยวอะไรกับคำแนะนำนี้นะ
แต่ในมุม PM คือใช้เวลา 4 เดือนเพื่อทำให้ onboarding ง่ายขึ้น แล้วตอนนี้จะให้ไปบอกคนให้ติดตั้งเบราว์เซอร์ใหม่งั้นหรือ
ผลิตภัณฑ์บนเบราว์เซอร์ที่ทำงานไม่ถูกต้องบนเบราว์เซอร์ที่มีคนใช้มากที่สุดในโลก ไม่ใช่สัญญาณที่ดี
ชอบนโยบายความปลอดภัยขององค์กรแบบนี้จริง ๆ ที่บล็อกรายงานการแครชของ Chrome ด้วยเหตุผลด้านความปลอดภัย แต่กลับอนุญาตให้พนักงาน ติดตั้ง Grammarly ได้