Mám moderní linuxový desktop se spoustou procesů běžících souběžně. Jeden z těchto procesů, a já nevím který, volá funkci some_func
z oblíbené dynamické knihovny some_lib
(přemýšlejte o libc
nebo libx11
, takže hodně procesů to používá) a chci vědět, jaký proces to dělá (a v ideálním případě mít trasování zásobníku každého vyvolání).
Jak zjistím, který proces volá some_lib
?
Možnosti, které jsem zatím zvažoval:
- Použijte
ltrace
nebolatrace
:Sltrace
-style podrobný seznam
procesu nazvaného funkce, která mě zajímá, s jakými
argumenty by byly perfektní, aleltrace
funguje pouze s
jednotlivými procesy nebo skupinami procesů. Nemohu jen napsatltrace -e
a zobrazit všechna použití v celém systému.
[email protected]_lib -fp 1 - Zjistit, které procesy používají moji knihovnu, pomocí
lsof
a poté pokračujte krokem 1:To by bylo velmi těžkopádné, protože existuje příliš mnoho procesů, které používají stejnou knihovnu, ale nevolají uvedenou funkci. grep -r some_func /usr
, pak zjistěte, zda existuje pouze několik binárních souborů schopných volat funkci, a postupujte odtamtud. I když to mohlo fungovat v nějakém omezeném množství případů, to v žádném případě není obecné řešení a nefungovalo by, kdyby např.some_func
je všudypřítomný v různých dvojhvězdách, ale jen zřídka se nazývá.- Používejte systém auditu jádra. Pokud bych sledoval systémové volání, mohl bych napsat
auditctl -S some_syscall ...
a to by stačilo k protokolování celosystémových vyvolání. Nicméněauditctl
nezdá se, že by byl schopen udělat stejnou úroveň granularity s knihovními funkcemi . - Konečně jsem mohl přestavit knihovnu, přidáním nového řádku do funkce, která mě zajímá, která by zaprotokolovala všechna její vyvolání. I když by to zaručeně vyřešilo můj problém, toto řešení by bylo těžkopádné a vyžadovalo by úpravu/překompilování knihovny a alespoň 2 restarty, aby se instrumentovaná knihovna spustila a po nalezení viníka se vrátila zpět.
Existuje jednodušší způsob?
(Chci zdůraznit, že toto je myšleno jako obecná otázka a většinou mě zajímají obecná řešení, která by prostě fungovala.)
Našel jsem pěkný srovnávací článek zmiňující několik dalších sledovacích zařízení, o kterých jsem nevěděl a které možná stojí za to prozkoumat.
Přijatá odpověď:
SystemTap s debuginfo může sledovat volání funkcí v knihovnách; na systému Centos 7:
$ sudo stap -L 'process("/lib64/libglib*").function("*strndup*")'
process("/usr/lib64/libglib-2.0.so.0.5000.3").function("g_strndup")
$
A to lze použít jako probe
bod, který vytiskne zpětné stopy nebo cokoli chcete, co lze zapsat pomocí SystemTap:
probe begin {
printf("okn")
}
probe process("/usr/lib64/libglib-2.0.so.0.5000.3").function("g_strndup") {
/* printf("%s[%d]n", execname(), pid()) */
print_usyms(ubacktrace())
}
uložen jako probelibraryfunc.stp
to lze spustit přes
$ sudo stap probelibraryfunc.stp
ačkoli může produkovat šílené množství výstupu, pokud je volání běžné…
Související:Je možné napájet Open Office přes STDIN?