Bu makale, .NET'te dökmeleri toplama hakkında sıkça sorulan soruları yanıtlamaktadır.
Linux'ta döküm toplama neden başarısız oluyor?
Döküm toplama işlevini gerçekleştirmek için .NET işlemleri createdump adlı bir alt işlem oluşturur. Bu alt işlem Linux API ptrace() kullanır ve döküm dosyasına yazılan iş parçacığı ve bellek verilerine erişmek için /proc dosya sisteminden okur. API kullanımına birçok Linux dağıtımında varsayılan güvenlik ayarları tarafından izin verilse de, bazen daha az yaygın bir güvenlik yapılandırması erişimi reddeder. Uygulamanın konsolunda yazılan createdump işleminin çıkışını görebilirsiniz, örneğin:
[createdump] The process or container does not have permissions or access: open(/proc/1234/mem) FAILED Permission denied (13)
Erişimin reddedilmesinin bir nedeni, bir güvenlik korumalı alanın seccomp BPF filtresi kullanarak çağrıya müdahale etmesidir. Open Container Initiative teknolojisini kullanan bir kapsayıcıda çalışan uygulamalar için profilin seccomp çağrısına ptraceizin vermesi gerekir. Örneğin, Docker altyapıda containerd kullanarak bir container çalışma zamanı kullanır. Başlatıldığında, varsayılan bir seccomp profili belirtir; bu profil, yalnızca kapsayıcı konağı 4.8'den yüksek bir çekirdek sürümüne sahipse veya kapsayıcıda CAP_SYS_PTRACE yeteneği belirtilmişse ptrace izin verir.
Çağrılar kesilmezse çekirdek çeşitli yerleşik erişim denetimleri yapar. ptrace() belgeleri, bunların nasıl yapıldığını açıklayan "Ptrace erişim modu denetimi" başlıklı, sonuna yakın ayrıntılı bir açıklama içerir. /proc dosya sistemine erişirken aynı ptrace erişim modu denetiminin bir çeşitlemesi de kullanılır. Aşağıda, gerçekleştirilen güvenlik denetimlerinin kısaltılmış bir özeti ve erişimin reddedilebileceği yerler verilmiştir:
- Arama işleminin hedef işlemle aynı kullanıcı kimliğine sahip olması veya arama işleminin CAP_SYS_PTRACE olması gerekir. Bunların hiçbiri doğru değilse erişim reddedilir. .NET çalışma zamanı createdump başlatılırken kullanıcı hesabını değiştirmek için hiçbir şey yapmadığından, kullanıcı kimlikleri eşleşmelidir ve bu adım başarılı olmalıdır.
- createdump'un CAP_SYS_PTRACE yetkisi yoksa (varsayılan olarak yok), hedef işlem "döküm edilebilir" olarak işaretlenmelidir. Varsayılan olarak, Linux'ta çoğu işlem döküme alınır, ancak prctl() öğesini PR_SET_DUMPABLE seçeneğiyle çağırarak bu ayarı değiştirebilirsiniz. Setcap aracını kullanarak bir işleme özellikler eklerseniz, bu durum işlemin döküm alınamaz hale gelmesine de neden olabilir. Döküm atanabilirlik ayarının daha ayrıntılı bir açıklaması ve devre dışı bırakılmasına neyin sebep olduğu konusunda Linux belgelerine bakın.
- Etkinleştirilmiş tüm Linux güvenlik modülleri (LSM) numaralandırılır ve her birinin erişimi onaylaması gerekir. Ne yazık ki, bir LSM erişimi reddederse, hangisinin sorumlu olduğunu bilmek için tekdüzen linux raporlama mekanizması yoktur. Bunun yerine, sisteminizde hangilerinin etkinleştirildiğini belirlemeniz ve ardından her birini ayrı ayrı araştırmanız gerekir. Hangi LSM'lerin etkin olduğunu şu şekilde çalıştırarak belirleyebilirsiniz:
cat /sys/kernel/security/lsm. Tüm LSM'ler sorumlu olsa da Yama, SELinux ve AppArmor genellikle ilgili olanlardır.
AppArmor ve SELinux'un her ikisi de zengin yapılandırma ve raporlama mekanizmalarına sahiptir, bu nedenle onlarla nasıl çalışacağınızı öğrenmeniz gerekiyorsa, her projenin kendi belgelerini görüntülemek en iyisidir. Yama yalnızca tek bir yapılandırma ayarına sahiptir ve bu ayar şu şekilde çalıştırılarak görüntülenebilir:
cat /proc/sys/kernel/yama/ptrace_scope
Bu komut geçerli Yama ptrace güvenlik ilkesini gösteren bir sayı verir:
- 0: Klasik ptrace izinleri.
- 1: Kısıtlanmış ptrace.
- 2: Yalnızca yönetici ekleme.
- 3: Ekleme yok.
Yama'nın 0 ve 1 politikaları kapsamında createdump için erişim vermesi gerekir, ancak 2 ve 3 politikaları kapsamında erişimin reddedilmesi beklenmelidir. İlke 3 her zaman erişimi reddeder ve ilke 2 varsayılan olarak çalışmaz çünkü createdump normalde CAP_SYS_PTRACE özelliğine sahip değildir.
Linux'ta neden yalnızca dotnet-dump veya kilitlenme işlemim yükseltilmiş olarak çalışıyorsa dökümleri alıyorum?
Bazı Linux tabanlı sistemler, döküm toplayan herhangi bir sürecin CAP_SYS_PTRACE yeteneğine sahip olmasını gerektiren güvenlik politikalarıyla yapılandırılmıştır. Normalde işlemler bu özelliğe sahip değildir, ancak yükseltilmiş olarak çalıştırmak bunu etkinleştirmenin bir yoludur. Linux güvenlik ilkelerinin döküm toplamayı nasıl etkilediğinin daha ayrıntılı bir açıklaması için bkz. 'Linux'ta döküm toplama neden başarısız oluyor?'.
Kapsayıcı içinde çalışırken neden dökümleri toplayamıyorum?
Herhangi bir Open Container Initiative teknolojisi altında çalışan uygulamalar için profilin seccompptrace() çağrısına izin vermesi gerekir. Örneğin, Dockercontainerd arka planda bir kapsayıcı çalıştırma zamanı olarak kullanılır. Çalışma zamanını başlatırken, yalnızca kapsayıcı sunucunun çekirdek sürümü 4.8'den yüksekse veya ilgili yetenek belirtilmişse izin veren varsayılan bir seccomp profili belirtmektedir.
Linux güvenlik ilkelerinin döküm toplamayı nasıl etkilediğinin daha ayrıntılı bir açıklaması için 'Döküm toplama neden Linux'ta başarısız oluyor?' sorusuna bakın.
MacOS'ta dökümleri neden toplayamam?
macOS'ta ptrace kullanımı, hedef işlemin konağının uygun şekilde yetkilendirilmiş olmasını gerektirir. Gerekli en düşük yetkilendirmeler hakkında bilgi için bkz. Varsayılan yetkilendirmeler.
Android veya iOS'ta dökümleri neden toplayamıyorum?
Döküm koleksiyonu mobil platformlarda (Android ve iOS) desteklenmez. Bu platformlar bellek dökümü oluşturmayı desteklemeyen Mono çalışma zamanını kullanır.
.NET uygulamamdaki sorunları tanılamaya yardımcı olmak için dökümleri nasıl kullanabileceğim hakkında nereden daha fazla bilgi edinebilirim?
Bazı ek kaynaklar şunlardır:
"Uyumlu bir çerçeve sürümü bulmak mümkün değildi" sorununu nasıl çözebilirim?
Linux'ta ortam DOTNET_ROOT değişkeni ayarlandığında doğru klasöre işaret etmelidir. Başka bir .NET sürümünü gösterdiğinde, dotnet-dump her zaman bu hatayı üretir.
DOTNET_ROOT Ortam değişkeni ayarlı olmadığında farklı bir hata oluşturulur ("Bu uygulamayı çalıştırmak için .NET'i yüklemelisiniz").