Manuel bellek yönetimi veya çalışma zamanı çöp toplama olmadan tip tabanlı bellek güvenliği?


13

Diyelim ki, Haskell veya Idris gibi, çöp toplama olmadan programlamayı hedefleyen ve çalışma zamanı olmayan (veya en azından C ve Rust "çalışma zamanlarından" daha fazla olmayan), saf ve işlevsel bir programlama dili istedik. Çıplak metal üzerinde az çok koşabilen bir şey.

El ile bellek yönetimi veya çalışma zamanı çöp toplama gerektirmeyen statik bellek güvenliği için bazı seçenekler nelerdir ve Haskell veya Idris'e benzer saf bir işlevin tür sistemi kullanılarak sorun nasıl çözülebilir?


Dildeki türlerin çöp toplamadan kaçınmanın bir yolu olarak hizmet etmesini istediğinizi mi söylüyorsunuz? Temel problem fonksiyonların değerlendirilmesinde ortaya çıkar. Bir işlev, geçerli çalışma zamanı ortamını kapsayan bir kapanış olarak değerlendirilir. Çöp toplama yapmak zorunda kalmanın ana kaynağı budur. İşlevler için yazma kuralını değiştirmediğiniz sürece, türlerin bu konuda nasıl yardımcı olacağını görmüyorum. Java ve kırık soyutlamaları olan diğer diller , kapanışların oluşumunu bozarak bunu uyandırırlar: gabrage toplanmasını gerektiren referanslara izin vermezler. λ
Andrej Bauer

Elbette Rust, sahiplik modeli ve borç alma denetleyicisi ile aynı fonksiyon değerlendirme ve kapanış sorununu ele almak zorundaydı? Bellek yönetimi sadece değerlerin ne kadar süredir canlı olduğunu bilmek, başka hangi değerlerin bunlara bağlı olduğunu ve kullanılmadığında ölülen değerleri yok etmek anlamına gelir, değil mi? Bu yüzden, sanırım bellek yönetiminin, yeni bir sahiplik sistemi ve "ödünç alarak" dil veya derleyicinin temel makinelerini genişletmeden, doğruluk açısından kontrol edilebilen bir dizi türde kapsüllenip eklenemeyeceğini soruyorum. checker "(Rust'un yolu).
Chase,

Martin Hofmann'ın LFPL'si ne olacak ? Özel bir taban tipi olan "elmas", doğrusal tip disiplinin uygulandığı ve türlerin temel bellek kullanımını (tahsis / ayrılma) hesaba katmasına izin verir. Bu, bahsettiğiniz yöne gider mi?
Damiano Mazza

Yanıtlar:


18

Kabaca söylemek gerekirse, güvenli manuel bellek yönetimi için iki ana strateji vardır.

  1. İlk yaklaşım, kaynak kullanımını kontrol etmek için doğrusal mantık gibi bazı yapısal mantığı kullanmaktır. Bu fikir temelde lineer mantığın başlangıcından beri etrafta dolaşmıştır ve temel olarak daralmanın yapısal kuralını yasaklayarak, her değişkenin en fazla bir kez kullanıldığı ve böylece hiçbir örtüşme olmadığı gözlemi üzerinde çalışır. Sonuç olarak, yerinde güncelleme ve yeniden ayırma arasındaki fark program tarafından görülmez ve böylece dilinizi manuel bellek yönetimi ile uygulayabilirsiniz.

    Rust'in yaptığı budur (afin tipi bir sistem kullanır). Rust tarzı diller teorisiyle ilgileniyorsanız, okunacak en iyi belgelerden biri Ahmed ve arkadaşlarının L3: Yerlerle Doğrusal Bir Dil'dir . Bir yana, bahsedilen LFPL hesabı Damiano Mazza da doğrusaldır, RAML dilinde ondan türetilen tam bir dile sahiptir .

    Idris tarzı doğrulama ile ilgileniyorsanız, Xi et al'ın Haskell tarzı dizin türlerine dayalı doğrulama desteği ile Rust / L3 tarzı bir dil olan ATS diline bakmalısınız , sadece daha fazla vermek için kanıtla alakasız ve doğrusal hale getirin performans kontrolü.

    Daha agresif bir şekilde bağımlı bir yaklaşım, tam bağımlı bir tür teorisi olan Microsoft Research'te geliştirilen F-yıldız dilidir . Bu dil, Nanevski ve arkadaşlarının Hoare Tip Teorisi (veya hatta kendi Entegre Doğrusal ve Bağımlı Tiplerim) ruhunda ön ve son koşullarla monadik bir arayüze sahiptir ve düşük seviyeli C koduna derlenebilen tanımlanmış bir alt kümeye sahiptir. - Aslında, zaten Firefox'un bir parçası olarak doğrulanmış kripto kodu gönderiyorlar!

    Açık olmak gerekirse, ne F-star ne de HTT doğrusal olarak yazılan diller değildir, ancak monadları için endeks dili genellikle Reynold ve O'Hearn'ün , büyük başarı gösteren doğrusal mantıkla ilgili alt yapı mantığı olan ayırma mantığına dayanır. işaretçi programları için Hoare mantıklarının onay dili.

  2. İkinci yaklaşım, hangi montajın (veya istediğiniz düşük seviyeli IR'nin) ne yapacağını belirtmek ve daha sonra bir prova asistanındaki davranışı hakkında mantık yürütmek için bir tür doğrusal veya ayırma mantığı kullanmaktır. Temel olarak, prova asistanını veya bağımlı olarak yazılan dili, yalnızca doğru programları üreten çok süslü bir makro birleştirici olarak kullanabilirsiniz.

    Jensen ve arkadaşlarının düşük seviye kodu için yüksek seviye ayırma mantığı bunun en saf örneğidir - x86 montajı için ayırma mantığı oluşturur! Ancak, bu bağlamda Princeton'daki Doğrulanmış Yazılım Araç Zinciri ve Yale'deki CertiKOS projesi gibi birçok proje var .

Değişkenlerin kullanımını kısıtlayarak mülkiyeti izlemek hepsinin anahtarı olduğu için, tüm bu yaklaşımlar Rust gibi biraz "hissedilecek".


3

Doğrusal tiplerin ve ayırma mantığının her ikisi de mükemmeldir, ancak biraz programcı çabası gerektirebilir. Örneğin, Rust'ta güvenli bir bağlantı listesi yazmak oldukça zor olabilir.

Ancak, daha az sıkı garantiler olsa da, daha az programcı çabası gerektiren bir alternatif var. (Oldukça eski) bir çalışma akışı (genellikle bir yığın) kullanarak bellek güvenliğini garanti etmektir. Bölge çıkarımı kullanarak, bir derleyici, tahsis edilen bir veri parçasının hangi bölgeye girmesi gerektiğine statik olarak karar verebilir ve kapsam dışında kaldığında bölgeyi yeniden konumlandırabilir.

Bölge çıkarımı güvenilirdir (ulaşılabilir belleği yeniden konumlandıramaz) ve minimum programlayıcı müdahalesini gerektirir, ancak "toplam" değildir (yani, "hiçbir şey yapma" dan kesinlikle çok daha iyi olmasına rağmen bellek sızdırabilir), bu nedenle genellikle Uygulamada GC. MLtonML Kit derleyicisi çoğu GC çağrısını ortadan kaldırmak için bölgeleri kullanır, ancak yine de bir GC'ye sahiptir, çünkü aksi halde hala bellek sızdırır. Bölgelerdeki ilk öncülerin bazılarına göre, bölge çıkarımı aslında bu amaç için icat edilmemiştir (sanırım otomatik paralelleştirme içindi); ancak bellek yönetimi için de kullanılabileceği ortaya çıktı.

Bir başlangıç ​​noktası için, Mads Tofte ve Jean-Pierre Talpin'in "Bir Bölgeler Yığını Kullanarak Tipik Değerle Arama λ-kalkülüsünün Uygulanması" makalesine gidelim. Bölge çıkarımı hakkında daha fazla makale için M. Tofte ve J.-P. Talpin, Pierre Jouvelot'un çalışmalarının yanı sıra Greg Morrisett, Mike Hicks ve Dan Grossman'ın Cyclone üzerine bir dizi makalesi.


-2

"Çıplak metal" sistemler için önemsiz bir şema, tüm çalışma zamanı bellek ayırmalarına izin vermemektir. Unutmayın, C malloc/freeçifti bile bir çalışma zamanı kütüphanesi gerektirir. Ancak tüm nesneler derleme zamanında tanımlansa bile, bunlar güvenli bir şekilde tanımlanabilir.

Buradaki en önemli sorun, program çalışırken oluşturulan saf işlevsel dillerdeki değişmez değerlerin kurgusu. Gerçek donanım (ve kesinlikle çıplak metal sistemler) sınırlı tedarikte bulunan değiştirilebilir RAM'e güvenir. Pratikte bir işlevsel dil uygulamasının çalışma zamanı, yeni "değişmez" değerler oluşturuldukça RAM'i dinamik olarak tahsis eder ve "değişmez" değere artık gerek kalmadığında çöpleri toplar.

Ve en ilginç problemler için, en azından bazı değerlerin ömrü çalışma zamanı (kullanıcı) girdisine bağlıdır, bu nedenle yaşam süreleri statik olarak belirlenemez. Ancak yaşam süresi girdiye bağlı olmasa bile, önemsiz olabilir. Basit bir programı, her sayıyı sırayla kontrol ederek, tüm primerlere karşı kontrol ederek tekrarlayan primleri bulmaya devam edin sqrt(N). Açıkçası bu ihtiyaç primerleri korur ve primer olmayanlar için kullanılan belleği geri dönüştürebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.