Ghostty Terminal Emulator เขียนแอปพลิเคชัน GTK ใหม่ หันมาใช้ระบบ GObject หลังประสบปัญหาการจัดการหน่วยความจำ

ทีมชุมชน BigGo
Ghostty Terminal Emulator เขียนแอปพลิเคชัน GTK ใหม่ หันมาใช้ระบบ GObject หลังประสบปัญหาการจัดการหน่วยความจำ

ทีมพัฒนา Ghostty terminal emulator ได้เสร็จสิ้นการเขียนแอปพลิเคชัน GTK ใหม่ทั้งหมดสำหรับระบบ Linux และ BSD โดยหันมาใช้ระบบ GObject type system อย่างเต็มรูปแบบ หลังจากประสบปัญหาการจัดการหน่วยความจำในการพัฒนาครั้งก่อน นี่เป็นครั้งที่ห้าที่ส่วน GUI ถูกเขียนใหม่ตั้งแต่เริ่มต้น ซึ่งแสดงให้เห็นถึงความท้าทายในการสร้างแอปพลิเคชันที่เป็น platform-native อย่างแท้จริง

ประวัติการเขียน GUI ใหม่:

  1. การใช้งาน GLFW
  2. macOS กับ SwiftUI
  3. macOS กับ AppKit + SwiftUI
  4. Linux กับ GTK (แนวทางแบบ procedural)
  5. Linux กับ GTK + ระบบ GObject แบบเต็มรูปแบบ (ปัจจุบัน)

ปัญหาการจัดการหน่วยความจำผลักดันให้เขียนใหม่ทั้งหมด

การพัฒนา GTK ครั้งแรกหลีกเลี่ยงการใช้ระบบ GObject type system ส่งผลให้เกิดบั๊กที่เกิดขึ้นอย่างต่อเนื่อง โดยหน่วยความจำที่จัดการโดย Zig หรือหน่วยความจำที่จัดการโดย GTK จะถูกปลดปล่อยอย่างไม่ถูกต้อง ปัญหา lifetime mismatches เหล่านี้สร้างปัญหาการ crash ทั้งหมดที่รบกวนแอปพลิเคชัน ทีมพัฒนาค้นพบว่าการต่อสู้กับระบบ reference-counting ของ GTK แทนที่จะยอมรับมันนั้นไม่เกิดประโยชน์

การพัฒนาใหม่ได้ห่อหุ้ม Zig structures เช่นระบบ configuration ด้วย reference-counted GObjects ซึ่งช่วยให้ระบบแจ้งเตือนการเปลี่ยนแปลง property ของ GTK สามารถจัดการการอัปเดตทั่วทั้งแอปพลิเคชันได้อย่างเป็นธรรมชาติ ขจัดการจัดการหน่วยความจำด้วยตนเองที่ซับซ้อนซึ่งเคยทำให้เกิดการ crash การโหลด configuration ใหม่ซึ่งเคยเป็นกระบวนการที่ใช้ CPU มากและเสี่ยงต่อข้อผิดพลาด ตอนนี้ทำงานได้อย่างราบรื่นผ่านกลไกในตัวของ GTK

การทดสอบ Valgrind เผยผลลัพธ์ที่น่าประหลาดใจ

ตลอดกระบวนการเขียนใหม่ ทีมได้ทดสอบทุกฟีเจอร์ผ่านเครื่องมือวิเคราะห์หน่วยความจำ Valgrind ผลลัพธ์ที่ได้ท้าทายสมมติฐานทั่วไปเกี่ยวกับความปลอดภัยของหน่วยความจำในภาษาโปรแกรมมิ่งต่างๆ โค้ดเบส Zig แสดงความเสถียรที่น่าทึ่งโดยมีเพียง memory leak หนึ่งครั้งและปัญหา undefined memory access หนึ่งครั้งในโค้ดเบสที่มีขนาดใหญ่ ซับซ้อน และมีหลาย thread

โค้ดเบส Zig ของเรามี leak หนึ่งครั้งและ undefined memory access หนึ่งครั้ง นั่นทำให้ฉันประหลาดใจมาก (ในทางที่ดี)

ปัญหาหน่วยความจำอื่นๆ ที่ค้นพบระหว่างการทดสอบเกิดขึ้นที่ขอบเขต C API โดยเฉพาะในการจัดการ lifetime ที่ซับซ้อนของระบบ GObject สิ่งนี้เสริมความจริงที่ว่าการรับประกันความปลอดภัยของหน่วยความจำมักจะพังทลายเมื่อข้ามขอบเขตภาษา โดยไม่คำนึงถึงคุณสมบัติความปลอดภัยของภาษาต้นทาง

ผลการวิเคราะห์หน่วยความจำ:

  • โค้ดเบส Zig : พบการรั่วไหลของหน่วยความจำ 1 จุด และการเข้าถึงหน่วยความจำที่ไม่ได้กำหนดค่า 1 จุด
  • ขอบเขต C API : พบและแก้ไขปัญหาหลายสิบจุด
  • ระบบ GTK/GObject : แก้ไขบั๊กการจัดการอายุการใช้งานหลายจุดเรียบร้อยแล้ว
  • วิธีการทดสอบ: การวิเคราะห์ด้วย Valgrind ในทุกฟีเจอร์และ PR

ชุมชนถกเถียงเกี่ยวกับแนวทาง Platform-Native

การเขียนใหม่ได้จุดประกายการอ้าเถียงเกี่ยวกับบทบาทของ GTK ในระบบนิเวศ Linux และว่าความซับซ้อนนั้นคุ้มค่าหรือไม่ นักพัฒนาบางคนตั้งคำถามว่างานการรวมระบบที่กว้างขวางนั้นคุ้มค่าหรือไม่สำหรับสิ่งที่เป็นเพียงแท็บและเมนูบริบท คนอื่นๆ โต้แย้งว่าการครอบงำของ GTK และสัญญาของคุณสมบัติการเข้าถึงทำให้มันเป็นตัวเลือกที่เหมาะสมสำหรับแอปพลิเคชัน Linux

การถกเถียงขยายไปเกินกว่าการพิจารณาทางเทคนิคไปสู่การพิจารณาเชิงปรัชญาเกี่ยวกับการออกแบบส่วนติดต่อผู้ใช้ ในขณะที่บางคนชอบแนวทางที่เรียบง่ายเช่นการเรนเดอร์ OpenGL แบบกำหนดเองของ Kitty ภารกิจของ Ghostty มุ่งเน้นที่การรวมระบบ platform-native ที่รู้สึกคุ้นเคยกับผู้ใช้ภายในสภาพแวดล้อมเดสก์ท็อปที่พวกเขาเลือก

การรองรับแพลตฟอร์มของ Ghostty :

  • macOS: แอปพลิเคชัน Swift พร้อม Xcode
  • Linux/BSD: แอปพลิเคชัน GTK พร้อมการผสานรวม X11/Wayland โดยตรง
  • Core: ไลบรารี Zig ที่ใช้ร่วมกันพร้อมความเข้ากันได้กับ C ABI
  • Frontend ของบุคคลที่สาม: รองรับผ่าน libghostty (เช่น Wraith สำหรับ Wayland )

มองไปข้างหน้า

แอปพลิเคชัน GTK ที่เขียนใหม่จะจัดส่งเป็นค่าเริ่มต้นใน Ghostty เวอร์ชัน 1.2 ซึ่งจะมาถึงในสัปดาห์ที่จะมาถึง ทีมวางแผนที่จะใช้ประโยชน์จากการรวมระบบ GTK ใหม่สำหรับฟังก์ชัน GUI ที่ขยายออกไป รวมถึงไดอะล็อกการตั้งค่าแบบ native และคุณสมบัติการรวมระบบแพลตฟอร์มที่ลึกขึ้นเช่นการซิงค์การกำหนดค่าอัตโนมัติบน macOS

สำหรับผู้ใช้ที่ชอบทางเลือกอื่นแทน GTK แกนกลาง libghostty แบบโมดูลาร์ช่วยให้ frontend ของบุคคลที่สามทำงานได้ โปรเจ็กต์เช่น Wraith แสดงให้เห็นแล้วถึงการพัฒนาแบบ Wayland-native ที่ข้าม GTK ทั้งหมด แสดงให้เห็นว่าสถาปัตยกรรมรองรับแนวทางที่แตกต่างกันในการออกแบบส่วนติดต่อผู้ใช้

อ้างอิง: We Rewrote the Ghostty GTK Application