- มีส่วนร่วมกับโปรเจกต์โอเพนซอร์สขนาดใหญ่ด้วยการแก้บั๊กของเว็บเบราว์เซอร์ Chromium/Google Chrome เป็นครั้งแรก
- เป็นประสบการณ์ที่มีเอกลักษณ์และแตกต่างจากงานโอเพนซอร์สที่เคยทำมาก่อนอย่างมาก
- จึงบันทึกกระบวนการทั้งหมดไว้เพื่อช่วยนักพัฒนาที่อยากลองทำงานลักษณะเดียวกัน
บั๊ก
- บั๊กที่แก้เกี่ยวข้องกับปัญหาการทำงานร่วมกันระหว่าง Chromium Devtools และคำขอเครือข่ายจาก worklet เช่น
AudioWorklet ที่ทำงานอยู่นอก main thread
- คำขอเครือข่ายที่สร้างโดย worklet ไม่แสดงในแท็บ Network ของ Devtools เลย
- ตัวเลือก "Disable Cache" ถูกเพิกเฉย ทำให้โค้ดเก่าไม่ถูกล้างออกจากแคชระหว่างการพัฒนา
- ปัญหานี้เกิดขึ้นอย่างต่อเนื่องในหลายโปรเจกต์ และตรงกับรายงานข้อผิดพลาดอย่างน้อยสามรายการ
- การทำชุดทดสอบเพื่อให้เกิดปัญหาซ้ำแบบขั้นต่ำทำได้ไม่ยาก โดยใช้สคริปต์ที่ตั้งค่า cache header เพื่อสร้าง
AudioWorkletProcessor แล้วรีโหลดหน้าเพื่อให้ปัญหาเกิดขึ้นอีกครั้ง
ดาวน์โหลดและบิลด์โค้ด Chromium
- ขั้นตอนแรกของการแก้บั๊กจริง ๆ คือการบิลด์ Chromium จากต้นทางทั้งหมด
- โชคดีที่มีเอกสารอธิบายวิธีบิลด์บนระบบปฏิบัติการหลักต่าง ๆ อย่างละเอียด
- แม้จะใช้คอมพิวเตอร์ประสิทธิภาพสูง การบิลด์ครั้งแรกก็ยังใช้เวลามากกว่า 45 นาที ใช้ RAM มากกว่า 50GB และต้องมีพื้นที่ดิสก์มากกว่า 100GB
- การบิลด์แบบ incremental เสร็จได้รวดเร็วภายใน 10 วินาที
- แม้การบิลด์จะใช้เวลา แต่เมื่อได้ติดตั้งข้อกำหนดเบื้องต้นทั้งหมดแล้ว กระบวนการก็ค่อนข้างสะดวกและทำงานอัตโนมัติ
ค้นหาและแก้ไขบั๊ก
- หลังจากสภาพแวดล้อมสำหรับบิลด์พร้อมใช้งานแล้ว ก็เริ่มสำรวจโค้ด
- โค้ดเบสของ Chromium มีขนาดใหญ่มาก และยากต่อการมองเห็นโครงสร้างภาพรวม
- การอ้างอิงทางอ้อมจำนวนมากและการแยกโมดูลภายในโค้ดทำให้การไล่ดูโค้ดยากขึ้น และมีการใช้ dynamic dispatch อย่างกว้างขวาง
- ใช้การดีบักแบบ
printf เพื่อติดตามตั้งแต่จุดที่เริ่มคำขอเครือข่ายไปจนถึงตอนที่คำขอถูกสร้างจริงหรือถูกดึงจากแคช
- สาเหตุของปัญหาคือไม่มีการสร้าง
InspectorNetworkAgent สำหรับเป้าหมายประเภท worklet
- เพื่อแก้ปัญหานี้ จึงเปลี่ยนให้
InspectorNetworkAgent รับ WorkerOrWorkletGlobalScope แทน WorkerGlobalScope
- อย่างไรก็ตาม การแก้ตรงนี้เพียงอย่างเดียวยังไม่พอ และหลังจากตรวจดูโค้ด TypeScript ของฝั่งฟรอนต์เอนด์ของ Devtools เพิ่มเติม ก็พบว่า
Capability.Networking หายไปสำหรับ Type.Worklet
- เมื่อเพิ่มส่วนนี้เข้าไปแล้ว ปัญหาก็ได้รับการแก้ไขอย่างสมบูรณ์
การทดสอบและโค้ดรีวิว
- หลังจากจัดระเบียบ debug log และตรวจ diff ขั้นสุดท้ายแล้ว ก็ไปสำรวจกระบวนการรีวิวและรวมโค้ด
- สร้างบัญชีบนเว็บไซต์รีวิวโค้ด
Chromium Gerrit และลงนาม CLA
- เลือกรีวิวเวอร์ ตรวจทานโค้ดที่เขียนไว้ และเพิ่มการทดสอบที่จำเป็น
- เขียนเทสต์ใหม่โดยอ้างอิงจาก JavaScript เทสต์หลายตัวที่ใช้ทดสอบความสามารถในการตรวจสอบเครือข่ายของ Devtools
- สุดท้ายได้รับการอนุมัติ "LGTM" ในโค้ดรีวิว และ PR ก็ถูกรวมเข้าไป
CL ที่สอง
- เขียน CL อีกหนึ่งรายการเพื่อเพิ่ม
Capability.Network ให้กับเป้าหมาย Devtools ของ worklet ในรีโพซิทอรี devtools_frontend
- ดำเนินการคล้ายกับ PR แรก และหลังจาก CI ผ่านก็ถูกรวมโดยอัตโนมัติ
การปล่อยเวอร์ชัน
- รอจนกว่าเวอร์ชันที่รวมการแก้ไขนี้จะออกใน Chrome Canary
- Chrome Canary อัปเดตวันละสองครั้ง และในที่สุดก็สามารถยืนยันได้ว่าการแก้ไขมีผลแล้ว
- ใช้เวลามากกว่าหนึ่งเดือนกว่าจะทำการแก้ไขเสร็จ และมีกำหนดจะรวมเข้าสู่ช่องทางเสถียรใน Chrome เวอร์ชัน 130
ผลลัพธ์และการทบทวน
- แม้การแก้บั๊กจะใช้เวลาและความพยายามมาก แต่ก็เป็นประสบการณ์ที่มีเอกลักษณ์มาก
- ได้สัมผัสว่าซอฟต์แวร์ถูกพัฒนาขึ้นอย่างไรในระดับสเกลแบบ Chromium
- สำหรับผู้เขียนเอง การที่โค้ดของตัวเองจะถูกใช้งานบนอุปกรณ์นับล้านหรืออาจถึงนับพันล้านเครื่องทั่วโลก เป็นแรงจูงใจอย่างมาก
- ประสบการณ์ครั้งนี้ทำให้ได้เรียนรู้วิธีมีส่วนร่วมกับ Chromium และตั้งใจว่าจะลองแก้บั๊กเพิ่มเติมอีกในอนาคต
2 ความคิดเห็น
ยอดเยี่ยมมาก
ความคิดเห็นจาก Hacker News
ประสบการณ์การทำงานกับโค้ดเบส Chromium
ปัญหาของส่วนขยาย C++ ใน VS Code
ประสบการณ์เกี่ยวกับบั๊กใน Chrome
ประสบการณ์ครั้งแรกกับโค้ดเบส Chromium
ข้อกำหนดในการบิลด์ Chrome
การดีบักด้วย printf
แนะนำให้ใช้ตัวดูโค้ดออนไลน์
cs.chromium.orgจำได้ง่ายความแตกต่างระหว่าง WorkletGlobalScope และ WorkerGlobalScope
ข้อเสนอให้ช่วยแก้บั๊ก Chromium
ประสบการณ์เกี่ยวกับบั๊กการคัดลอกรูปภาพ