Tento článek odpovídá na nejčastější dotazy týkající se shromažďování výpisů paměti v .NET.
Proč dochází k selhání shromažďování výpisů paměti v Linuxu?
Aby bylo možné implementovat kolekci výpisů paměti, vytvoří procesy .NET podřízený proces s názvem createdump. Tento podřízený proces používá ptrace() rozhraní Linux API a také čte ze systému souborů /proc pro přístup k datům vlákna a paměti, která jsou zapsána do souboru s výpisem paměti. I když je využití rozhraní API povolené ve výchozím nastavení zabezpečení v mnoha distribucích Linuxu, někdy méně běžná konfigurace zabezpečení přístup odepře. Může se zobrazit výstup z vytvořeného procesu napsaného v konzole aplikace, která se vypíše, například:
[createdump] The process or container does not have permissions or access: open(/proc/1234/mem) FAILED Permission denied (13)
Jedním z důvodů, proč je možné přístup zamítnout, je to, že sandbox zabezpečení zachytí volání pomocí filtru BPF seccomp. U aplikací spuštěných v kontejneru pomocí technologie seccomp Open Container Initiative musí profil umožňovat volání ptrace. Například Docker používá kontejnery pod kapotou jako modul runtime kontejneru. Při inicializaci určuje výchozí profil seccomp , který umožňuje ptrace pouze v případě, že hostitel kontejneru má verzi jádra vyšší než 4.8 nebo pokud CAP_SYS_PTRACE byla v kontejneru zadána schopnost.
Pokud se volání nezachytí, jádro provede řadu integrovaných kontrol přístupu. Dokumentace pro ptrace() obsahuje podrobný popis na konci s názvem "Kontrola režimu přístupu Ptrace", který popisuje, jak se to dělá. Přístup k systému souborů /proc používá také variantu stejné kontroly režimu přístupu ptrace. Následuje zkrácený souhrn provedených kontrol zabezpečení a míst, kde může být přístup odepřen:
- Volající proces musí mít stejné ID uživatele jako cílový proces, nebo volající proces musí mít CAP_SYS_PTRACE. Pokud žádná z těchto hodnot není pravdivá, přístup se odepře. Vzhledem k tomu, že modul runtime .NET nedělá nic ke změně uživatelského účtu při spuštění nástroje Createdump, id uživatelů by se měla shodovat a tento krok by měl proběhnout úspěšně.
- Pokud createdump nemá CAP_SYS_PTRACE (ve výchozím nastavení to není), musí být cílový proces výpisu označený jako "dumpable". Ve výchozím nastavení je většina procesů v Linuxu k výpisu paměti, ale toto nastavení můžete změnit voláním prctl() s možností PR_SET_DUMPABLE. Pokud do procesu přidáte funkce pomocí nástroje setcap, může to také způsobit, že proces přestane být výpis paměti. Podrobnější popis nastavení výpisu paměti a jeho příčiny, které ho způsobí zakázání, najdete v dokumentaci k Linuxu.
- Všechny povolené moduly zabezpečení Linuxu (LSM) jsou vyčísleno a každý z nich musí schválit přístup. Pokud LSM přístup bohužel odmítne, neexistuje žádný jednotný mechanismus generování sestav Linuxu, který by věděl, který z nich je zodpovědný. Místo toho je potřeba určit, které jsou ve vašem systému povolené, a pak je prověřit jednotlivě. Spuštěním příkazu můžete určit, které moduly LSM jsou aktivní:
cat /sys/kernel/security/lsm. I když jakýkoli LSM může být zodpovědný, Yama, SELinux a AppArmor jsou často relevantní.
AppArmor i SELinux mají bohaté mechanismy konfigurace a vytváření sestav, takže pokud se potřebujete naučit pracovat s nimi, je nejlepší zobrazit si vlastní dokumentaci jednotlivých projektů. Yama má jenom jedno nastavení konfigurace, které se dá zobrazit spuštěním příkazu:
cat /proc/sys/kernel/yama/ptrace_scope
Tento příkaz vypíše číslo označující aktuální zásady zabezpečení Yama ptrace:
- 0: Klasická oprávnění ke trasování.
- 1: Omezený ptrace.
- 2: Připojení pouze správce.
- 3: Žádné připojení.
Yama by měl udělit přístup pro vytvoření v rámci zásad 0 a 1, ale očekává se, že přístup bude odepřen v rámci zásad 2 a 3. Zásada 3 vždy odepře přístup a zásada 2 ve výchozím nastavení nefunguje, protože vytvoření obvykle nemá schopnost CAP_SYS_PTRACE.
Proč se v Linuxu zobrazují výpisy paměti jenom v případě, že je spuštěný proces dotnet-dump nebo proces chybového ukončení?
Některé systémy založené na Linuxu jsou nakonfigurované se zásadami zabezpečení, které vyžadují, aby všechny procesy, které shromažďují výpis paměti, měly CAP_SYS_PTRACE schopností. Obvykle procesy tuto funkci nemají, ale spuštění se zvýšenými oprávněními je jedním ze způsobů, jak ji povolit. Úplný popis toho, jak zásady zabezpečení Linuxu ovlivňují shromažďování výpisů paměti, najdete v tématu "Proč dochází k selhání shromažďování výpisů paměti v Linuxu?".
Proč při spuštění v kontejneru nemůžu shromažďovat výpisy paměti?
U aplikací spuštěných v libovolné technologii seccomp Open Container Initiative musí profil umožňovat volání ptrace(). Například Docker používá kontejnery pod kapotou jako modul runtime kontejneru. Při inicializaci modulu runtime určuje výchozí profil seccomp , který umožňuje ptrace pouze v případě, že hostitel kontejneru má verzi jádra vyšší než 4.8 nebo pokud CAP_SYS_PTRACE byla zadána schopnost.
Úplný popis toho, jak zásady zabezpečení Linuxu ovlivňují shromažďování výpisů paměti, najdete v tématu "Proč dochází k selhání shromažďování výpisů paměti v Linuxu?".
Proč nemůžu shromažďovat výpisy paměti v systému macOS?
Použití systému macOS ptrace vyžaduje, aby byl hostitel cílového procesu správně oprávněn. Informace o minimálních požadovaných nárocích najdete v tématu Výchozí oprávnění.
Kde najdu další informace o tom, jak můžu využít výpisy paměti k diagnostice problémů v aplikaci .NET?
Tady jsou některé další zdroje informací:
Jak můžu vyřešit "Nebylo možné najít žádnou kompatibilní verzi architektury"
V Linuxu DOTNET_ROOT musí proměnná prostředí při nastavení odkazovat na správnou složku. Když odkazuje na jinou verzi .NET, dotnet-dump vždy dojde k této chybě.
DOTNET_ROOT Pokud proměnná prostředí není nastavená, vytvoří se jiná chyba (Abyste mohli tuto aplikaci spustit, musíte nainstalovat .NET).