14 คะแนน โดย GN⁺ 2024-08-27 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • มีส่วนร่วมกับโปรเจกต์โอเพนซอร์สขนาดใหญ่ด้วยการแก้บั๊กของเว็บเบราว์เซอร์ 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 ความคิดเห็น

 
huiya 2024-08-27

ยอดเยี่ยมมาก

 
GN⁺ 2024-08-27
ความคิดเห็นจาก Hacker News
  • ประสบการณ์การทำงานกับโค้ดเบส Chromium

    • ใช้ Sublime Text ในการทำงานกับโค้ดแบบ plain text
    • หากใช้ VS Code ก็สามารถใช้ฟีเจอร์อย่างการกระโดดไปยังนิยามหรือการประกาศของฟังก์ชันได้
    • แนะนำบทความของตนเองสำหรับผู้ที่อยากสร้างเบราว์เซอร์บนพื้นฐาน Chromium
  • ปัญหาของส่วนขยาย C++ ใน VS Code

    • ส่วนขยาย C++ ของ VS Code ทำงานได้ไม่ดีนักเพราะโค้ดเบสมีขนาดใหญ่มาก
    • มีปัญหาที่ CPU core ถูกใช้งานค้างที่ 100%
    • เครื่องมือ Chromium Code Search มีประโยชน์มาก
  • ประสบการณ์เกี่ยวกับบั๊กใน Chrome

    • พบบั๊กที่ทำให้พิมพ์ "±±±±±±+..." ในเบราว์เซอร์สาย Chromium บน Linux
    • ไม่เกิดปัญหานี้ในแอปพลิเคชันอื่น
    • อยากทำซ้ำบั๊กและแก้ไขมัน
  • ประสบการณ์ครั้งแรกกับโค้ดเบส Chromium

    • การสำรวจโค้ดเบส Chromium เป็นครั้งแรกไม่ได้ยากอย่างที่คิด
    • เคยอ้างอิงโค้ดของ Chrome เพื่อแก้บั๊กการวางรูปภาพบน Windows
  • ข้อกำหนดในการบิลด์ Chrome

    • ข้อกำหนดในการบิลด์ Chrome สูงมาก
    • จำเป็นต้องใช้เวิร์กสเตชันประสิทธิภาพสูง
    • Firefox ก็ใช้เวลาบิลด์นานเช่นกัน
  • การดีบักด้วย printf

    • ไม่จำเป็นต้องอายที่จะใช้การดีบักด้วย printf
    • การดีบักด้วย printf มีประสิทธิภาพมาก
  • แนะนำให้ใช้ตัวดูโค้ดออนไลน์

    • แนะนำให้สำรวจโค้ดผ่านตัวดูโค้ดออนไลน์
    • URL cs.chromium.org จำได้ง่าย
  • ความแตกต่างระหว่าง WorkletGlobalScope และ WorkerGlobalScope

    • ใช้เวลาพอสมควรกว่าจะเข้าใจความแตกต่างของสองคำนี้
    • กฎการตั้งชื่อไม่ค่อยดีนัก
  • ข้อเสนอให้ช่วยแก้บั๊ก Chromium

    • แนะนำให้ลองแก้บั๊กใน Chromium
    • Chrome อัปเดตเร็ว จึงอาจเห็นบั๊กถูกแก้ภายใน 4-6 สัปดาห์
    • อยากหาคนมาช่วยมีส่วนร่วมในการแก้บั๊ก
  • ประสบการณ์เกี่ยวกับบั๊กการคัดลอกรูปภาพ

    • เมื่อคัดลอกรูปภาพไปยังคลิปบอร์ดในเบราว์เซอร์สาย Chromium แล้ว UI จะค้าง
    • สาเหตุเกิดจากปัญหาในการเข้ารหัส PNG
    • แก้ปัญหาโดยเปลี่ยนระดับการบีบอัดเป็น 0
    • Firefox ไม่มีอาการหน่วงและใส่ไฟล์ภาพต้นฉบับลงในคลิปบอร์ด