Nejčastější dotazy k výpisům dat

Tento článek odpovídá na nejčastější dotazy týkající se shromažďování výpisů v prostředí .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, procesy .NET spustí podřízený proces s názvem createdump. Tento podřízený proces používá Linux API ptrace() a také čte ze souborového systému /proc, aby získal přístup k datům vláken 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 procesu createdump zapsaný na konzoli aplikace, která je vykládána, 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 bezpečnostní sandbox zachytí volání pomocí seccomp BPF filtru. U aplikací spuštěných v kontejneru pomocí technologie seccomp Open Container Initiative musí profil umožňovat volání ptrace. Například Docker ve svém jádru používá containerd jako runtime kontejneru. Při inicializaci určuje výchozí profil seccomp, který to povolí pouze tehdy, pokud hostitel kontejneru má verzi jádra vyšší než 4.8 nebo pokud byla v kontejneru zadána odpovídající 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 (výchozí nastavení to nezahrnuje), musí být cílový proces, který se má vypsat, 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 uložitelný jako výpis. Podrobnější popis nastavení výpisu paměti a důvodů, proč je zakázáno, najdete v dokumentaci k Linuxu.
  • Všechny povolené moduly zabezpečení Linuxu (LSM) jsou vyjmenovány a každý z nich musí schválit přístup. Bohužel, pokud LSM přístup odmítne, neexistuje žádný jednotný mechanismus hlášení v Linuxu, který by určil, 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í ptrace.
  • 1: Omezený ptrace.
  • 2: Připojení pouze pro správce.
  • 3: Žádná příloha.

Yama by měl udělit přístup pro createdump podle zásad 0 a 1, ale očekává se, že přístup bude odepřen podle zásad 2 a 3. Pravidlo 3 vždy odepře přístup a pravidlo 2 ve výchozím nastavení nefunguje, protože createdump 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 jakýkoli proces, který shromažďuje výpis paměti, měl schopnost CAP_SYS_PTRACE. 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č nemohu shromažďovat dumpy při běhu v kontejneru?

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á pod pokličkou containerd 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 specifiková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í.

Proč nemůžu shromažďovat výpisy paměti v Androidu nebo iOSu?

Shromažďování výpisů paměti není podporováno na mobilních platformách (Android a iOS). Tyto platformy používají běhové prostředí Mono, které nepodporuje generování výpisu paměti.

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).