3 คะแนน โดย GN⁺ 2024-07-31 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • TRACTOR ของ DARPA เป็นโครงการวิจัยที่มุ่งแปลงโค้ด C รุ่นเก่าเป็น Rust โดยอัตโนมัติ เพื่อกำจัดช่องโหว่ด้านความปลอดภัยของหน่วยความจำในโปรแกรม C ทั้งหมวดหมู่
  • ปัญหา ความปลอดภัยของหน่วยความจำ ใน C และ C++ ถูกพูดถึงมานานกว่า 20 ปี แต่เริ่มมีความเข้าใจร่วมกันว่าเครื่องมือตรวจจับบั๊กเพียงอย่างเดียวไม่เพียงพอ
  • ทางเลือกคือการย้ายโค้ดเดิมไปยัง ภาษาโปรแกรมที่ปลอดภัย ซึ่งสามารถปฏิเสธโปรแกรมที่ไม่ปลอดภัยได้ตั้งแต่ขั้นตอนคอมไพล์
  • ผลลัพธ์ของการแปลงตั้งเป้าให้มี คุณภาพและสไตล์ เทียบเท่าโค้ดที่เขียนโดยนักพัฒนา Rust ที่มีประสบการณ์ โดยผสานการวิเคราะห์แบบสถิตและไดนามิกเข้ากับแมชชีนเลิร์นนิงที่อิงโมเดลภาษาขนาดใหญ่
  • MIT Lincoln Laboratory รับหน้าที่ ทดสอบและประเมินผล ส่วน benchmark, milestone project และเครื่องมือเผยแพร่ไว้บนหน้าสาธารณะ

เป้าหมายของ TRACTOR

  • TRACTOR คือโปรแกรม “Translating All C to Rust” มีเป้าหมายเพื่อแปลงโค้ด C รุ่นเก่าเป็น Rust โดยอัตโนมัติ
  • ในด้านความปลอดภัย มุ่งกำจัด ช่องโหว่ด้านความปลอดภัยของหน่วยความจำ ทั้งหมวดหมู่ที่มีอยู่ในโปรแกรม C
  • โค้ดที่แปลงแล้วไม่ได้มุ่งแค่ให้ทำงานได้เท่านั้น แต่ยังตั้งเป้าให้มี คุณภาพและสไตล์ เทียบเท่าโค้ดที่สร้างโดยนักพัฒนา Rust ที่มีประสบการณ์

ทำไมจึงต้องแปลงเป็น Rust

  • ปัญหาความปลอดภัยของหน่วยความจำใน C และ C++ เป็นโจทย์ที่ชุมชนวิศวกรรมซอฟต์แวร์จัดการมานานกว่า 20 ปี
  • เกิดฉันทามติว่าการพึ่งพาเพียงเครื่องมือตรวจจับบั๊กนั้นยากที่จะจัดการปัญหาได้อย่างเพียงพอ
  • แนวทางที่เป็นที่ต้องการมากกว่าคือการใช้ ภาษาโปรแกรมที่ปลอดภัย ซึ่งสามารถปฏิเสธโปรแกรมที่ไม่ปลอดภัยได้ตั้งแต่ขั้นตอนคอมไพล์
  • TRACTOR ใช้ Rust เป็นภาษาเป้าหมาย

เทคโนโลยีที่ใช้ในการแปลงอัตโนมัติ

  • TRACTOR ผสานเทคนิคการวิเคราะห์ซอฟต์แวร์หลายแบบเข้ากับเทคนิคแมชชีนเลิร์นนิง เพื่อย้ายโค้ด C รุ่นเก่าไปเป็น Rust
  • เทคนิคการวิเคราะห์

    • ใช้ทั้ง การวิเคราะห์แบบสถิต และ การวิเคราะห์แบบไดนามิก ร่วมกัน
    • รวมถึงเทคนิคแมชชีนเลิร์นนิงที่มีโมเดลภาษาขนาดใหญ่อยู่ในองค์ประกอบด้วย
    • การผสานนี้เป็นแกนเทคโนโลยีสำคัญที่จำเป็นต่อการทำความเข้าใจโครงสร้างและพฤติกรรมของโค้ด C และแปลงเป็นโค้ด Rust โดยอัตโนมัติ

การทดสอบ·ประเมินผลและเอกสารสาธารณะ

1 ความคิดเห็น

 
GN⁺ 2024-07-31
ความคิดเห็นบน Hacker News
  • เผื่ออ้างอิง https://sam.gov/opp/1e45d648886b4e9ca91890285af77eb7/view ก็น่าดูเช่นกัน

    • ลิงก์ตรงไปยัง PDF ข้อมูลงานชี้แจงผู้เสนอข้อเสนอ: https://sam.gov/api/prod/opps/v3/opportunities/resources/fil...
      ระบุว่าวัตถุประสงค์ของงานนี้คือเพื่ออธิบาย เป้าหมายและความท้าทายทางเทคนิคของ TRACTOR ตอบคำถามจากผู้เสนอข้อเสนอที่อาจสนใจ และเปิดโอกาสให้พิจารณาว่างานวิจัยของแต่ละฝ่ายจะสอดคล้องกับเป้าหมายของโปรแกรม TRACTOR ได้อย่างไร
  • เรื่องนี้ดูยากจริง ๆ โดยเฉพาะ Rust แบบ idiomatic ที่ผู้เชี่ยวชาญเขียนนั้นแทบไม่เหมือน C เลย และโค้ดที่น่าสนใจส่วนใหญ่ก็เขียนด้วย C++
    สุดท้ายแล้วผมรู้สึกว่ามันก็เหมือนกับการต้องตัดสิน lifetime ของการจัดสรรทั้งหมดในโปรแกรม C แบบสแตติก ไม่เว้นแม้แต่การจัดสรรที่ข้ามไปยัง allocator ที่ผู้ใช้กำหนดเองหรือไลบรารีเฉพาะทาง งานวิจัยด้านนี้มีมานานแล้ว แต่ความสำเร็จใหญ่ ๆ มีไม่มาก และโปรแกรม C/C++ สามารถผูก lifetime ของการจัดสรรเข้ากับปุ่มที่ผู้ใช้กดได้ แม้จะไม่มีมาตรการป้องกันอย่าง reference counting ก็ตาม ไม่ใช่ความคิดที่ดี แต่ทำได้
    ปัญหาชัดเจนอีกอย่างคือ โปรแกรมที่นำมาวิเคราะห์นั้น โดยนิยามแล้วเป็นโค้ดที่มีบั๊กอยู่ ถ้า lifetime สมเหตุสมผล ก็คงไม่มีช่องโหว่ด้าน memory safety และไม่จำเป็นต้องแทนที่มัน งานวิจัยที่ตรวจจับแบบสแตติกว่า “lifetime ควรเป็นอย่างไร” ส่วนใหญ่มักสมมติว่าโค้ดที่วิเคราะห์นั้นถูกต้องตั้งแต่แรก อาจตั้งเป้าเป็นโปรแกรมที่หาจุดซึ่งตัดสิน lifetime ไม่ได้แล้วขอความช่วยเหลือจากนักพัฒนาได้

    • เป็นงานที่ยากมาก และ DARPA ก็ชอบให้ทุนกับงานยาก ๆ[1]
      อย่างไรก็ตาม นี่ไม่ใช่ครั้งแรกที่ DARPA พยายามทำ การแปลโปรแกรมอัตโนมัติ หรือการแปลอัตโนมัติไปเป็น Rust[2]
      [1]: https://www.urbandictionary.com/define.php?term=DARPA%20hard
      [2]: https://c2rust.com/
    • พูดถึงงานยากแล้ว DOE ก็ให้ทุนโครงการชื่อ ROSE มานานกว่า 20 ปีเช่นกัน ครอบคลุมทั้ง static analysis และการแปลอัตโนมัติระหว่าง C/C++/Cuda รวมถึงภาษาระดับสูงอย่าง Python และ C/C++ variant สำหรับ HPC
      โครงการนี้มี unified abstract syntax tree ที่รองรับภาษาเหล่านี้ด้วยชุดชนิดของโหนดที่แทบจะเหมือนกัน ถือว่าเจ๋งทีเดียว เคยมีโอกาสได้ทำงานกับมันตอนเป็นเด็กฝึกงานฤดูร้อนที่ Livermore เมื่อปี 2014
      และยังเป็นโอเพนซอร์สด้วย: http://rosecompiler.org/ROSE_HTML_Reference/index.html
    • ในกรณีทั่วไปน่าจะแปลเป็น unsafe Rust และบางครั้งเฉพาะโหนดปลายทางที่แยกตัวอยู่เท่านั้นถึงจะแปลเป็น Rust ที่ปลอดภัย
      ถ้าแค่สู้กับ borrow checker ก็รู้สึกว่ายากแล้ว การแปลอัตโนมัติให้เป็นโค้ดที่ borrow checker ยอมรับ โดยต้องคำนึงถึงพื้นที่ของโปรแกรม C ที่เป็นไปได้ทั้งหมด รวมถึง undefined behavior อันเลื่องชื่อ จะยิ่งยากกว่านั้นมาก หนึ่งในปัญหาคลาสสิกของการเขียนคอมไพเลอร์คือ พื้นที่ของโปรแกรมที่ถูกต้องนั้นใหญ่กว่าพื้นที่ของโปรแกรมที่คอมไพล์ได้มาก
      ลองค้นเร็ว ๆ ก็มีความพยายามอย่าง c2rust อยู่แล้ว[1] อยากรู้ว่า TRACTOR ต่างออกไปอย่างไร
      [1] https://github.com/immunant/c2rust
    • มีเหตุผลที่โจทย์ของ DARPA ถูกเรียกว่า DARPA-hard
    • แนวทางน่าจะประมาณว่า “ให้ AI สรุปฟังก์ชันของโปรแกรมเป็นภาษาบรรยายเชิงเทคนิคบางอย่าง แล้วสังเคราะห์โค้ด Rust ที่ครอบคลุมชุดฟังก์ชันเดียวกัน”
      ถ้าแทนที่จะใส่โปรแกรมต้นฉบับเข้าไป แต่ใส่คู่มือของโปรแกรมนั้นแทน ก็น่าจะน่าสนใจกว่า อย่างไรก็ตาม คู่มือแทบไม่ค่อยบันทึกพฤติกรรมละเอียดอ่อนทั้งหมดของโปรแกรม ดังนั้นอย่างน้อยเพื่อให้ได้ค่ามาตรฐานจริง ๆ ก็น่าจะยังต้องดูซอร์สโค้ดอยู่ดี
  • ผม/ฉันทราบถึงโครงการริเริ่มที่เสนอนี้มาระยะหนึ่งแล้ว และน่าสนใจที่ตอนนี้มันถูกเปิดเผยต่อสาธารณะ เป็นข้อเสนอที่ทะเยอทะยานมาก และผม/ฉันเห็นว่าความทะเยอทะยานระดับนี้เหมาะกับ ภารกิจของ DARPA จึงหวังว่าจะไปได้สวย
    ในฐานะคนที่สนับสนุน Rust ในด้านนี้ ผม/ฉันพยายามลดความคาดหวังของผู้ที่ผลักดันข้อเสนอนี้เกี่ยวกับความเป็นไปได้ของการแปล C เป็น Rust แบบอัตโนมัติ อุปสรรคพื้นฐานที่ผม/ฉันมองเห็นคือซอร์สโค้ด C มีข้อมูลน้อยกว่าซอร์สโค้ด Rust การแปลโค้ด C เป็นโค้ด Rust จำเป็นต้องมีใครบางคนหรืออะไรบางอย่างสร้างข้อมูลที่ขาดหายไปนั้นขึ้นมา สามารถพิสูจน์ได้ง่ายว่าการสร้างข้อมูลที่ขาดหายไปนี้ให้สมบูรณ์แบบนั้นเป็นไปไม่ได้ ด้วยเหตุผลเดียวกับที่การขยายภาพให้ใหญ่ขึ้นไม่สามารถสร้างบิตข้อมูลที่ไม่ได้ถูกบันทึกไว้ในภาพต้นฉบับได้โดยไม่มีข้อผิดพลาด สุดท้ายก็ต้อง extrapolate หรือพูดอีกอย่างคือต้องประดิษฐ์ข้อมูลที่ขาดหายไปจากซอร์สโค้ดเดิมขึ้นมา การ extrapolate ให้ถูกต้องต้องอาศัยวิจารณญาณ และโดยเฉพาะเมื่อโมเดลภาษาที่ไม่มีการกำกับดูแลทำในปริมาณมาก ก็เป็นกระบวนการที่หลีกเลี่ยงข้อผิดพลาดไม่ได้ ผม/ฉันเคยเสนอแนวทางที่คิดว่าสามารถบรรเทาปัญหานี้ได้ในระดับหนึ่ง แต่จะไม่ลงรายละเอียด
    ท้ายที่สุดผม/ฉันคิดว่าโปรเจกต์นี้อาจประสบความสำเร็จได้ในระดับหนึ่ง แต่ควรเดินหน้าด้วยความคาดหวังที่ระมัดระวังและพอเหมาะ ขณะเดียวกันก็มีความเป็นไปได้ที่จะไม่มีผลลัพธ์สาธารณะออกมาเลย ดังนั้นอยากบอกว่าอย่าตีความเกินไปในตอนนี้ โดยเฉพาะอย่างยิ่ง รัฐบาลไม่ใช่องค์กรเดียวเป็นเนื้อเดียวกัน จึงไม่ควรตีความโปรเจกต์นี้ว่าเป็นการปฏิเสธ C อย่างสิ้นเชิง หรือเป็นการรับรอง Rust อย่างเต็มรูปแบบ แต่ละหน่วยงานจะกำหนดทิศทางและตารางเวลาการนำเทคโนโลยีความปลอดภัยของหน่วยความจำมาใช้เอง ตัวอย่างเช่น NIST แนะนำไม่เพียง Rust แต่ยังรวมถึง Ada SPARK และ dialect ของ C/C++ ที่เสริมความแข็งแกร่งหลายแบบด้วย

    • มีความเกี่ยวข้องอย่างไรกับความพยายาม CRAM ของ Grammatech?
      https://cpp-rust-assisted-migration.gitlab.io/blog/
    • หากไม่พยายามรักษาความหมายเชิงรูปแบบของโค้ด C และมองว่าแค่หลังแปลแล้วยังผ่าน ชุดทดสอบ ก็พอ การแปลก็จะมีพื้นที่ให้ทำได้มากขึ้นมาก
      โปรเจกต์เปลี่ยนเป็น Rust จริง ๆ มักดำเนินไปแบบนี้อยู่บ่อย ๆ Fuzzer ก็สามารถช่วยสร้างข้อมูลทดสอบเพิ่มเติมเพื่อเพิ่ม branch coverage ได้ด้วย
  • โดยส่วนตัวไม่ชอบแนวคิดแบบ “เขียนทั้งโลกใหม่ด้วย Rust” ถึงอย่างนั้น หากจะพอร์ตโปรเจกต์ใดไปยังภาษาใหม่หรือแพลตฟอร์มใหม่ การแปลเชิงกลไก ก็เป็นวิธีที่ไม่ดี
    ควรใช้เวลาวางแผนสถาปัตยกรรมที่ดีกว่า ออกแบบระบบซอฟต์แวร์ที่ดีกว่า แล้วหาวิธีเปลี่ยนทีละส่วน หากสร้างวิมานไว้บนฟ้า มันจะไม่มีวันแตะพื้น หากตัดสินใจใช้ Rust กับระบบนี้ก็ไม่เป็นไร แต่ควรเขียนให้เป็นแบบ Rust ไม่ควรพยายามพอร์ต C ย้อนกลับมาเป็น Rust
    ผม/ฉันมองว่ากระบวนการที่ดีกว่าและสุกงอมกว่ามากคือการปรับ C ให้เป็น C สมัยใหม่ และตรวจสอบความปลอดภัยของหน่วยความจำ ทรัพยากร และการคำนวณจำนวนเต็มด้วย model checker อย่าง CBMC วิธีนี้จะได้ความปลอดภัยแบบเดียวกับการเขียนใหม่ด้วย Rust แบบค่อยเป็นค่อยไป ขณะเดียวกันยังคงรักษา codebase ฐานความรู้ และนักพัฒนาไว้ได้

    • เป็นไปไม่ได้ CBMC น่าทึ่งก็จริง แต่เคยทำ formal verification กับโปรแกรม “จริง” ไหม?
      เห็นด้วยว่าการแทนที่ด้วยเวอร์ชัน Rust ที่ออกแบบสถาปัตยกรรมด้วยมือเป็นทางออกที่ดีกว่าแน่นอน แต่ต้นทุนก็สูงกว่าด้วย ดูเหมือนว่าที่นี่กำลังมุ่งทำผลิตภัณฑ์แบบ RLBox ที่ “เพิ่มความปลอดภัยได้มากโดยแทบไม่ต้องลงแรง” ถ้ามีทรัพยากรก็ไม่ได้หมายความว่าไม่ควรเขียนใหม่ด้วยมือทั้งหมด แต่หมายความว่ามันดีกว่าไม่ทำอะไรเลย
    • C สมัยใหม่ก็มี ช่องโหว่ด้านความปลอดภัย ในอาร์เรย์และสตริงเหมือนกับ C แบบคลาสสิกทุกประการ และไม่มีอะไรเปลี่ยนไปตลอด 50 ปี
    • นี่เป็น โจทย์ท้าทายแบบ DARPA ที่ค่อนข้างขายฝัน ซึ่งแน่นอนว่าถ้ามีไว้ตอนหลุดพ้นจากระบบ legacy ก็คงดี แต่แม้จะเอาฟังก์ชันหรือเมธอดของภาษาหนึ่งใส่ ChatGPT แล้วขอให้แปลเป็นอีกภาษา โดยทั่วไปก็ยังทำได้ไม่ดี
      ถ้าถาม ChatGPT ให้แก้ปัญหาตั้งต้นที่ต้องการแก้ มักจะตอบถูกบ่อยกว่า แต่โดยรวมก็ยังทำได้ไม่ดีอยู่ดี ยังต้องอาศัยการปรับแต่งและการคิดอีกมากเพื่อให้แม้แต่ผลลัพธ์พื้นฐานที่ออกมาทำงานได้
    • สำหรับโค้ดที่หลับใหลซึ่งรันอยู่ทุกที่แต่ไม่มีใครแตะต้อง วิธี “แปลเป็น Rust ห่วย ๆ ก่อนค่อยกลับมาแตะ” ก็มีเสน่ห์อยู่บ้าง
      ไม่ใช่เสน่ห์ในแง่ที่ว่าเป็นไอเดียที่ดีอย่างชัดเจน “Rust ห่วย ๆ” ที่ได้จากการแปลมีแนวโน้มว่าจะทำงานด้วยยากกว่า C ที่มีสัญญาณรบกวนพื้นหลังเป็นบั๊กมาก และด้วยการแปลที่ซื่อตรง บั๊กเหล่านั้นก็จะยังอยู่ใน “Rust ห่วย ๆ” เช่นเดิม ใน C ผู้คนพอรู้วิธีจัดการกับปัญหาอยู่บ้าง แต่ “Rust ห่วย ๆ” นั้นห่วยจริง ๆ เพราะคนสาย Rust ไม่คุ้นกับสิ่งแบบนั้น
      ถึงอย่างนั้น ความเป็นไปได้ที่ใครบางคนจะพัฒนาเทคนิคในการค่อย ๆ ทำความสะอาดซ้ำ ๆ จนอยู่ในสภาพที่พอรับได้ก็ไม่ใช่ศูนย์ อีกทั้งในฐานะผลลัพธ์นอกเป้าหมายของโปรเจกต์ อาจได้ feedback จาก linter ในทำนองว่า “ไม่สามารถแปลเป็น Rust ที่พอรับได้เพราะ x, y, z” ก็ได้ นักพัฒนา C สามารถนำสิ่งนี้ไปดูได้ และหากโค้ดสามารถแปลเป็น Rust ที่ดีได้แล้ว เหตุผลที่จะต้องแปลจริง ๆ ก็ลดลงด้วย
      ถ้าได้ผลลัพธ์แบบนี้ สำหรับบางคน การอธิบายวิธีแก้ด้วย C ที่รันได้ แล้วให้ “ตัวแปล/linter” ชี้นำไปสู่แนวทางที่ไม่พัง อาจง่ายกว่า ผม/ฉันคิดว่าผลลัพธ์เชิงบวกเหล่านี้มีโอกาสค่อนข้างต่ำ แต่การ เดิมพันม้ามืด เป็นครั้งคราวก็ดูใกล้เคียงกับคำบรรยายงานของ DARPA ไม่ใช่หรือ
    • ไม่มีแนวคิดแบบ “เขียนทั้งโลกใหม่ด้วย Rust” อยู่ที่ไหนเลย มีซอฟต์แวร์จำนวนมหาศาลที่ปล่อยไว้ในภาษาไดนามิกหรือภาษา static typed ที่มี garbage collection อย่าง Go จะดีกว่ามาก วิศวกรที่ดีเข้าใจแนวคิดว่าควรใช้เครื่องมือให้เหมาะกับงาน
      ประเด็นหลักคือการเริ่มลด memory safety CVE ที่พิสูจน์แล้วว่าเป็นปัญหาจริงหลายครั้ง
      ผม/ฉันเห็นด้วยกับคำกล่าวที่ว่าหากสามารถแปลจาก C/C++ ไปเป็น Rust ได้โดยอัตโนมัติและเชื่อถือได้ มันก็คงเกิดขึ้นไปแล้ว แต่ในกระบวนการวางแผนสถาปัตยกรรมและระบบที่ดีกว่าแล้วค่อย ๆ เปลี่ยนทีละส่วนนั้น ผู้คนอาจมีความมั่นใจว่า “ตอนนี้เราเขียน C ได้ดีขึ้นมากแล้ว คงไม่สร้างบั๊ก memory safety อีกแล้ว หยุดตรงนี้ก็ได้ไม่ใช่หรือ?” และในความเป็นจริงพวกเขาก็จะทำเช่นนั้น แล้วอีก 6 เดือนต่อมาก็จะมี CVE buffer overflow ที่ทั้งขำทั้งเศร้าออกมาอีก
      การปรับ C ให้เป็น C สมัยใหม่และตรวจสอบด้วย CBMC ก็เป็นการลงทุนมหาศาลเช่นกัน ถ้าจะทำถึงระดับนั้น ย้ายไป Rust เลยจะดีกว่า คำกล่าวว่าจะได้ความปลอดภัยแบบเดียวกับการเขียนใหม่ด้วย Rust แบบค่อยเป็นค่อยไปนั้นอาจเป็นไปได้ แต่ดูค่อนข้างไม่แน่นอน หรือยังห่างไกลจากข้อสรุปที่ชัดเจน
  • หลายคนอ่านสิ่งนี้เหมือนเป็นข้อเรียกร้องหรือคำสั่งให้แปลโค้ด C และ C++ ทั้งหมดเป็น Rust แต่แม้ชื่อโปรเจกต์จะสะดุดตา บทคัดย่อไม่ได้อ่านได้แบบนั้น มีสองย่อหน้าที่เกี่ยวข้องกันแต่แยกกัน
    อย่างแรก C และ C++ ไม่ปลอดภัยเพียงพอในระดับขนาดใหญ่ ต่อให้เขียนโปรแกรมอย่างระมัดระวังและใช้เครื่องมือดี ๆ ก็ยังเกิดช่องโหว่มากเกินไป เพราะการออกแบบที่ไม่ปลอดภัยโดยพื้นฐาน ดังนั้นจึงควรแปลหรือเขียนโค้ดใหม่ให้มากที่สุดเท่าที่ทำได้ด้วยภาษา “ปลอดภัย” โดยเฉพาะภาษาที่รับประกันความปลอดภัยของหน่วยความจำ
    อย่างที่สอง คือการให้ทุนและเปิดประกวดซอฟต์แวร์ที่แปลโค้ด C เดิมเป็น Rust
    นี่ไม่ใช่ฉันทามติว่าจะเขียนโลกใหม่ด้วย Rust แต่เป็นฉันทามติให้ ย้ายไปใช้ภาษาที่ปลอดภัย โดย Rust เป็นหนึ่งในตัวอย่าง และหมายความว่ามีโปรแกรมที่ตั้งเป้าไปที่ Rust ในการย้ายครั้งนี้

    • ถ้าภาษาเหล่านั้นมีไวยากรณ์ unsafe แล้วกฎในการใช้มันเป็นอย่างไร? ถ้าไม่มีชุดกฎที่นิยามไว้สำหรับเรื่องนี้ สุดท้ายก็แค่กลับไปยังจุดเริ่มต้น
      Rust มีโหมดปลอดภัย แต่ Rust ไม่ใช่ ภาษาปลอดภัย หากต้องการทำสิ่งที่น่าสนใจ ก็จำเป็นต้องใช้บล็อก unsafe สิ่งนี้ไม่ได้ให้อะไรมากนัก
      ในทางกลับกัน มีภาษาแบบ garbage collection มากมายที่ไม่ยอมให้โปรแกรมเมอร์แตะ pointer ด้วยซ้ำ ทำไมภาษาเหล่านั้นถึงไม่ถูกพิจารณา? เหตุผลคือประสิทธิภาพ เพราะโปรแกรมเมอร์ Rust “ให้ความสำคัญ” กับประสิทธิภาพมากขนาดนั้น ภาษานั้นจึงไม่มีวันแก้ปัญหารากฐานได้
      คุณต้องการประสิทธิภาพ หรือคุณต้องการความปลอดภัย? คุณมีทั้งสองอย่างพร้อมกันไม่ได้
  • น่าทึ่งจริง ๆ ที่สิ่งนี้อาจทำงานได้ด้วยวิธีอัตโนมัติแบบใดแบบหนึ่ง โปรแกรม C ทั่วไปไม่สามารถถอดเป็น Rust แบบบรรทัดต่อบรรทัดได้
    ในโปรแกรม C มี pointer และ aliasing อยู่ทุกที่ และ Rust ปิดกั้นแนวคิดแบบนั้นอย่างชัดเจน เว้นแต่จะครอบทั้งหมดด้วย unsafe การเขียนโปรแกรม C ใหม่เป็น Rust จำเป็นต้องคิดโครงสร้างแบบเดิมจำนวนมากใหม่ในระดับสูง

    • การแปลบรรทัดต่อบรรทัดเป็นไปไม่ได้ และเพราะอย่างนั้น หากต้องการทำ การอนุมานเชิงความหมาย ที่ใหญ่ขึ้น ก็ต้องใช้ AI
      ไม่จำเป็นต้องแปลทุกอย่างในคราวเดียวด้วย หนึ่งในคุณค่าของ Rust compiler คือมันให้ข้อมูลที่เป็นรูปธรรมจำนวนมาก ซึ่งสามารถป้อนกลับเข้า LLM เพื่อวนซ้ำได้
      ที่สตาร์ทอัพของผม grit.io เราได้ทำงานกับปัญหาคล้าย ๆ กัน และผมคิดว่า C -> Rust เป็นสิ่งที่รับมือได้เพียงพอในอนาคตอันใกล้ แน่นอนว่าไม่ง่าย แต่เป็นปัญหาที่แก้ได้
    • ถ้าไม่นับโปรแกรมแบบหลายเธรด aliasing ระยะยาวมีอยู่ทั่วทั้งโปรแกรม C จริง ๆ หรือ? ผมคาดว่าในหลายโปรแกรม ส่วนใหญ่จะเกิดภายในขอบเขตของฟังก์ชันเดียว หรือข้ามการเรียกฟังก์ชันภายในนั้น ในกรณีนั้นแก้ด้วย borrowing ไม่ได้หรือ?
      ถ้าอย่างนั้น ก็อาจมองเรื่องนั้นเป็นปัญหาย่อยหนึ่ง และมองการตรวจจับว่าข้อมูลถูกแชร์ระหว่างเธรดอย่างไรเป็นอีกปัญหาหนึ่ง ในกรณีหลัง หลายโปรแกรมน่าจะมีกฎ ownership โดยนัย เช่น “เธรด T1 ใส่ลงคิว Q แล้วเธรด T2 เอาไป” ซึ่งสามารถแปลเป็น “เมื่อใส่ลงคิว ownership จะถูกโอน” ได้
      การตรวจจับกฎแบบนี้คงไม่ง่าย แต่ก็ไม่ได้ดูเหมือนเป็นเรื่องที่เกินเอื้อมโดยสิ้นเชิง และอาจมีความหมายพอสำหรับโปรเจกต์วิจัย
    • ขอถามในฐานะมือใหม่แบบซื่อ ๆ ได้ไหมว่า ไล่ไปทีละบรรทัด ครอบทั้งหมดด้วย unsafe คอมไพล์ให้เป็นไบนารีเดียวกัน แล้วค่อย ๆ ถอด unsafe ออกไปช้า ๆ พร้อมตรวจสอบความเท่าเทียมไปเรื่อย ๆ ไม่ได้หรือ?
      ถ้าทำแบบนั้น อย่างน้อยก็น่าจะย้ายส่วนต่าง ๆ ไป Rust ได้มากที่สุดเท่าที่เป็นไปได้ แล้วแยกจัดการเฉพาะแนวคิดที่วิศวกรต้องคิดใหม่
    • การแปลบรรทัดต่อบรรทัดไม่ได้ต้องใช้ “AI” มากนักด้วยซ้ำ น่าจะสร้างงานแปลเป็น Rust แบบคร่าว ๆ ที่ส่วนใหญ่เป็น unsafe ได้
      ผมสมมติว่า AI จะต้องเข้าใจเรื่อง lifetime และอื่น ๆ เพื่อสร้างโปรแกรมที่มีประโยชน์และถูกต้องจริง ๆ ถ้าทำแบบนั้นได้จริงก็น่าประทับใจ
    • ผมสงสัยเป็นพิเศษว่าใน codebase ที่ใช้ macro หนัก ๆ เรื่องนี้จะออกมาอย่างไร
  • ถ้าปฏิบัติตามแนวทางการเขียนโค้ดที่เข้มงวดมาก และผสานเครื่องมือตรวจสอบแบบสถิตของบุคคลที่สามที่ต้องใส่ annotation แบบ proprietary เต็มไปหมดในโค้ด ก็อาจได้ผลลัพธ์คล้ายกันด้วย C/C++
    หรือไม่ก็แค่ใช้ Rust ก็จบ

    • ดูชุมชน C/C++ ต่อต้าน Rust แล้วค่อนข้างตลก ความพยายามและประสบการณ์หลายสิบปีที่อยู่กับภาษาเหล่านั้นคงเขียนทับวงจรการใช้เหตุผลไปแล้วแน่ ๆ
      ในเมื่อมีทางเลือกจริง ๆ อยู่ ใครที่สติปกติจะปกป้องภาษาที่มีข้อบกพร่องด้านการออกแบบใหญ่และชัดเจนขนาดนั้น
    • ที่ตั้งใจจะเขียนคือ annotation แบบ proprietary ไม่ใช่ “สถานการณ์ผูกขาด” เพราะระบบเติมคำอัตโนมัติในมือถือ
  • เรื่องนี้ดูไม่น่าจะไปได้สวย C มี abstraction ที่ไม่สามารถจำลองใน Rust ได้โดยไม่เปลี่ยนแปลงมาก
    ใน C เป็นเรื่องปกติที่โครงสร้างข้อมูลสองตัวที่ต่างกันซึ่งเก็บ pointer เดียวกันจะเขียนไปยัง pointer นั้น สิ่งนี้ไม่สามารถจำลองใน Rust ได้แบบง่าย ๆ และต้องการการแทรกแซงที่ค่อนข้างชาญฉลาด

    • น่าจะสร้างบางอย่างที่คอมไพล์ได้ และเป็นทั้ง “Rust” กับ “AI” ได้ คงดีต่อการ justify โปรเจกต์วิจัย เพราะตอบโจทย์ buzzword ได้สองเท่า
      แต่คงไม่ได้ output ที่มีบั๊กน้อยลง หรือกระบวนการสร้างโครงสร้างโปรแกรมที่ทำให้ Rust น่าเชื่อถือโดยอัตโนมัติ
  • สิ่งนี้จำเป็นต้องเป็นอัตโนมัติหรือ? ถ้าใช่ โปรแกรมที่สามารถ port C ไป Rust แบบอัตโนมัติ ก็ควรจะต้องมีฟังก์ชันทั้งหมดที่ทำให้โค้ด C เองปลอดภัยอยู่แล้วอย่างเลี่ยงไม่ได้ไม่ใช่หรือ?

    • ถ้าอ่านประโยคนั้นอย่างสมเหตุสมผล คงยากที่จะหมายถึง อัตโนมัติเต็มรูปแบบ และถ้าเป็นเช่นนั้น คำตอบของคำถามก็คือไม่
      โค้ด C บางส่วนไม่ใช่แค่ “ไม่สามารถตรวจสอบความถูกต้องได้” แต่ “ผิดจริงในแง่ความปลอดภัยของหน่วยความจำ” โค้ดแบบนั้นจะไม่ถูกแปลอัตโนมัติโดยไม่มีมนุษย์เข้ามาเกี่ยวข้อง มันจะเป็นไปได้อย่างไร ในเมื่อไม่มีโค้ดเทียบเท่าที่ถูกต้อง เครื่องมือต้องมีทางออกในการบอกว่า “ฉันไม่รู้ว่าโค้ดนี้ตั้งใจทำอะไร และสิ่งที่มันทำจริง ๆ คือการผิดสัญญากับ compiler ดังนั้นฉันก็รู้ด้วยว่านั่นไม่ใช่สิ่งที่ตั้งใจไว้ มนุษย์ ช่วยที”
      ในเชิงทฤษฎี เป็นไปไม่ได้ที่จะทำให้ทางออกนั้นถูกใช้เฉพาะเมื่อเกิด undefined behavior จริง ๆ เท่านั้น เพราะทฤษฎีบทของ Rice ในทางปฏิบัติก็ไม่ควรแปลโค้ดที่คลุมเครือเกินไปแบบสุ่มสี่สุ่มห้า ดังนั้นความพยายามที่จะทำแบบนั้นเองก็มีแนวโน้มว่าจะไม่พึงประสงค์
      สุดท้ายผมนึกภาพว่าเครื่องมือจะเป็นเหมือน เครื่องมือแบบโต้ตอบ ที่ทำงานส่วนใหญ่ให้ แต่ให้มนุษย์คอยชี้นำ และผลจากการชี้นำนั้นจะไม่ใช่โค้ดที่เทียบเท่ากันเป๊ะ ๆ แต่เป็นโค้ดที่ทำวัตถุประสงค์เดียวกัน
  • หาก 1) Rust ไม่มีบั๊กด้านหน่วยความจำ และ 2) สามารถแปล C เป็น Rust ได้โดยอัตโนมัติ ก็หมายความว่าสามารถแก้บั๊กด้านหน่วยความจำทั้งหมดได้โดยอัตโนมัติ
    เรื่องนี้แทบจะแน่นอนว่าไม่เป็นจริง งานนี้มีความเป็นไปได้สูงมากว่าในกรณีทั่วไปนั้น เป็นไปไม่ได้โดยสิ้นเชิง

    • เนื่องจากไม่ได้ระบุว่าต้องการรักษาพฤติกรรมทั้งหมดของโค้ด C ไว้ ปัญหานี้จึงมีวิธีแก้แบบง่าย ๆ
      เช่น เปลี่ยนการจัดสรรหน่วยความจำแบบไดนามิกทั้งหมดให้เป็นบัฟเฟอร์ขนาดคงที่ที่กำหนดไว้ ณ เวลาแปล แล้วปฏิเสธอินพุตทั้งหมดที่ไม่พอดีกับบัฟเฟอร์นั้นก็ได้