Provided by: systemtap-doc_5.1-5_amd64 bug

JMÉNO

       stapprobes - přehled sondážních bodů systemtapu

POPIS

       Následující   text  přináší  přehled  základních  druhů  sondážních  bodů  (probe  points)  podporovaných
       překladačem systemtapu. Zmíněny jsou také některé přezdívky  (aliases)  definované  v  tapset  skriptech.
       Podrobnější individuální informace k mnohým z nich přinášejí man stránky s prefixem

       probe:: sdružené v man sekci 3stap.

SYNTAXE

              probe PROBEPOINT [, PROBEPOINT] { [STMT ...] }

       Deklarace  sondy  (probe) může obsahovat seznam čárkou oddělených sondážních bodů. Sonda pak bude svázána
       se všemi takto zmíněnými sondážními body, potažmo událostmi v systému.

       Jednotlivý sondážní bod se zapíše jako posloupnost tečkou oddělených komponent, například 'syscall.read',
       kde 'syscall' a 'read' jsou komponenty. Komponenty odpovídají určitým  třídám  dělení  jmenného  prostoru
       událostí.  Připomíná  to zápis doménového jména počítače na internetu. Každá komponenta může být přesněji
       specifikována číselným, nebo řetězcovým parametrem uvedeným v závorkách, podobně jako při volání  funkce.
       V rámci deklarace sondy lze použít zástupný symbol hvězda "*", který bude expandován v rámci jedné z teč‐
       kou  oddělených  komponent, nebo symbol "**", který bude expandován přes více než jednu komponentu (v ex‐
       trémním případě přes všechny).

       Přezdívka sondy se syntakticky chová podobně jako sonda samotná. Lze též pracovat s  přezdívkami  přezdí‐
       vek.  Přezdívku  sondy lze volat samostatně, nebo s příponou. Přípona se při překladu připojí k sondě nad
       kterou je přezdívka definovaná. Příklad:

              syscall.read.return.maxactive(10)

       se expanduje na

              kernel.function("sys_read").return.maxactive(10)

       kde maxactive(10) se chápe jako přípona.

       Každý sondážní bod se po expanzi zástupných symbolů a přezdívek mapuje na nějaký nízkoúrovňový prvek sys‐
       tému, jako například na 'kprobe' adresu, na značku (marker), na událost časovače a podobně. Pokud  takové
       mapování  selže  (například  snažíme-li  se odkázat na jaderný modul který není zaveden), překlad skriptu
       selže.

       Sondážní bod může být následován znakem "?", a pak je považován za volitelný. V  tom  případě  nedojde  k
       chybě  překladu,  pokud se mapování nezdaří. Tento příznak volitelnosti se při překladu předává níže přes
       přezdívky a expanze až k elementárním sondážním bodům překladače. Sondážní bod může  být  též  následován
       znakem "!". V tom případě je považován za volitelný a dostatečný. Volně to připomíná 'cut' operátor známý
       z  prologu. Pokud se takový "dostatečný" sondážní bod podaří úspěšně namapovat, pak se už překladač nepo‐
       kouší o mapování dalších (čárkou oddělených) sondážních bodů definujících danou sondu.  Označit  sondážní
       bod za dostatečný tedy dává smysl jen je-li v definici sondy následován dalším sondážním bodem.

       Dále  může být sondážní bod následován výrazem podmínky "if (expr)". Tím lze sondážní bod za běhu aktivo‐
       vat, či deaktivovat. Pokud 'expr' je nepravda, sondážní bod je neaktivní. Podmínka se při překladu předá‐
       vá níže přes přezdívky a expanze až k elementárním sondážním bodům  překladače, takže na nejnižší  úrovni
       představuje  podmínka  logický  součin  příslušných podmínek na elementárních sondážních bodech. Podmínka
       'expr' může zákonitě být založena jen na globálních proměnných a  při  tom  nesmí  měnit  jejich  hodnotu
       (např. i++ není povoleno).

       Následující  sondážní  body  jsou syntakticky korektní. (Jejich sémantika závisí na obsahu tapsetu, verzi
       jádra analyzovaného systému atd. Pro Váš systém jsou pravděpodobně sémanticky nevalidní.)

              kernel.function("foo").return
              process("/bin/vi").statement(0x2222)
              end
              syscall.*
              syscall.*.return.maxactive(10)
              syscall.{open,close}
              sys**open
              kernel.function("no_such_function") ?
              module("awol").function("no_such_function") !
              signal.*? if (switch)
              kprobe.function("foo")

       Sondy lze obecně klasifikovat na "synchronní" a "asynchronní". Za synchronní považujeme sondu (resp. udá‐
       lost), kdy např. některý z procesorů vykonal danou instrukci. Tím je dán referenční bod na základě které‐
       ho může sonda získat další kontextové informace. Za asynchronní považujeme např. událost časovače.  Asyn‐
       chronní  sonda nemá k dispozici kontextové informace. Každá sonda může být definovaná na základě množství
       sondážních bodů například prostřednictvím zástupných symbolů, přezdívek, nebo dalších  čárkou  oddělených
       sondážních  bodů.  Jakmile  kterýkoliv  z nich detekuje událost, sonda se aktivuje (probe point is hit) a
       spustí obslužnou rutinu, což je blok kódu (probe handler).

       Závorková expanze je úsporný způsob zápisu většího množství sondážních bodů, které dohromady tvoří sondu.
       Do složených závorek se uvede seznam čárkou oddělených subkomponent a/nebo případně  dalších  (vnořených)
       závorkových expanzí. Expanze sonděhne v daném pořadí.

       Otazník (?), vykřičník (!) a podmínky (if (expr)) musí být uvedeny za poslední komponentou sondážního bo‐
       du.

       Příklad závorkové expanze:

              syscall.{write,read}
              # Se expanduje na
              syscall.write, syscall.read

              {kernel,module("nfs")}.function("nfs*")!
              # Se expanduje na
              kernel.function("nfs*")!, module("nfs").function("nfs*")!

LADICÍ INFORMACE FORMÁTU DWARF

       Vyhodnocení  některých  sondážních bodů vyžaduje relevantní ladicí informace formátu (DWARF). Pro některé
       sondážní body si umí systemtap zrekonstruovat potřebné ladicí informace na základě  hlavičkových  souborů
       sám.  Pro  jiné  sondážní body nejsou ladicí informace potřeba. Vzhledem k tomu, že systemtap skript může
       obsahovat libovolný mix různých typů sond, výsledné požadavky celého skriptu na dostupnost  ladicích  in‐
       formací jsou sjednocením odpovídajících požadavků pro jednotlivé sondážní body. Ladicí informace jsou po‐
       třebné  v okamžiku kdy dochází k překladu skriptu. K té nemusí nutně dojít na systému, kde bude systemtap
       modul nakonec použit. Viz volba --use-server a termín stap-server v manuálové stránce stap(1)).

       Následuje seznam dostupných rodin sondážních bodů rozdělený podle jejich nároků  na  dostupnost  ladicích
       informací:

       DWARF                          NON-DWARF                    SYMBOL-TABLE

       kernel.function, .statement    kernel.mark                  kernel.function*
       module.function, .statement    process.mark, process.plt    module.function*
       process.function, .statement   begin, end, error, never     process.function*
       process.mark*                  timer
       .function.callee               perf
       python2, python3               procfs
                                      kernel.statement.absolute
       AUTO-GENERATED-DWARF           kernel.data
                                      kprobe.function
       kernel.trace                   process.statement.absolute
                                      process.begin, .end
                                      netfilter
                                      java

       Pro  rodiny  sond označené hvězdou *, si dokáže systemtap za určitých okolností vygenerovat část ladicích
       informací z hlavičkových souborů sám. Obecně platí, že čím více relevantních ladicích informací je k dis‐
       pozici, tím vyšší bude kvalita analýzy.

ODEMYKÁNÍ A ZAMYKÁNÍ SOND ZA BĚHU

       Následující typy sondážních bodů lze podle potřeby zamknout / odemknout za běhu. Tím lze snížit  zatížení
       systému.  Odemčená sonda je neaktivní, zamčená je aktivní. Odemčená sonda nekonzumuje systémové prostřed‐
       ky.

       ODEMYKATELNÉ                              výjimky
       kernel.function, kernel.statement
       module.function, module.statement
       process.*.function, process.*.statement
       process.*.plt, process.*.mark
       timer.                                    timer.profile
       java

       Odemykání lze předepsat i jiným typům sond, ale v jejich případě nedojde k úsporám systémových  prostřed‐
       ků.

TYPY SONDÁŽNÍCH BODŮ

   BEGIN/END/ERROR
       Sondážní  body  begin  a  end  jsou  definovány překladačem a odkazují k okamžikům startu, resp. ukončení
       skriptu. Obslužné rutiny svázané se všemi 'begin' sondami se v určitém pořadí provedou během startu  sys‐
       temtap sezení. Před tím se inicializují všechny globální proměnné. Obslužné rutiny svázané s 'end' sonda‐
       mi se provedou v daném pořadí během normálního ukončení sezení, jako například po vykonání funkce exit ()
       ,  nebo  pokud  sezení  ukončí  uživatel (Ctrl-C). V případě, kdy sezení skončí v důsledku chyby, nebudou
       'end' sondy aktivní. V kontextu 'end' sond neexistují žádné cílové proměnné.

       Pořadí vykonání jednotlivých "begin" a "end" sond, lze určit pořadovým číslem:

              begin(N)
              end(N)

       Číslo M může být kladné i záporné. Sondy budou aktivní ve vzestupném pořadí svých pořadových čísel. Pořa‐
       dí vykonání sond se stejným pořadovým číslem je nedefinované. Kde není pořadové číslo explicitně uvedeno,
       pracuje se efektivně s nulou.

       Sondážní bod error je podobný sondážnímu bodu end až na to, že je aktivován při ukončení sezení v důsled‐
       ku chyby. V takových případech se 'end' sondy přeskočí, ale dojde k pokusu vykonat všechny 'error' sondy.
       Tento typ sond lze využít k závěrečnému úklidu. Také 'error' sondám lze nastavit pořadí vykonání.

   NEVER
       Sondážní bod never je speciálně definovaný překladačem a znamená "nikdy". Obslužná rutina spojená s touto
       sondou se nikdy nevykoná, nicméně její příkazy projdou analýzou překladače. Tato sonda může být  užitečná
       v kombinaci s volitelnými (optional) sondami.

   SYSCALL a ND_SYSCALL
       Přezdívky  syscall.*  a  nd_syscall.* definují několik set sond. Příliš mnoho pro detailní popis na tomto
       místě. Zde je obecná forma:

              syscall.NAME
              nd_syscall.NAME
              syscall.NAME.return
              nd_syscall.NAME.return

       Pro každé běžné systémové volání (viz syscalls(2) ) je definována dvojice sond: Jedna pro vstup  a  druhá
       pro opuštění systémového volání. Systémová volání, která nikdy neskončí, nemají odpovídající .return son‐
       du.  Rodina 'nd_*' sond je velmi podobná s tím rozdílem, že používá non-DWARF přístup, tedy nevyžaduje ke
       své činnosti ladicí informace. Mohou být užitečné zejména není-li k dispozici RPM balíček kernel-debugin‐
       fo s ladicími informacemi jádra.

       Přezdívky obvykle poskytují řadu proměnných, se kterými lze v rámci obslužné rutiny sondy  pracovat.  Je‐
       jich kompletní seznam je obsažen v tapset skriptech. Tam je vhodné nahlédnout. Například syscall.open po‐
       skytuje následující proměnné: filename, flags, a mode. Kromě nich jsou v každém 'syscall.*' sondážním bo‐
       du dostupné standardní proměnné jako:

       argstr Řetězec obsahující hodnoty všech argumentů.

       name   Jméno systémového volání.

       retstr Řetězec  obsahující návratovou hodnotu systémového volání (dostupný v sondách pro výstup ze systé‐
              mového volání).

       Tyto proměnné jsou inicializovány v určitém okamžiku při vstupu / výstupu do / ze systémového  volání  na
       základě  kontextových  proměnných a tudíž nereflektují eventuální pozdější změny těchto kontextových pro‐
       měnných.

   ČASOVAČE
       Existují dva hlavní typy 'timer' sond:  Jsou to sondy 'jiffies', a sondy pro časové intervaly.

       Časové intervaly jsou v terminologii linuxového jádra definovány  v  jednotkách  "jiffies"  (odpovídající
       přibližně 1 až 60 ms). Časovač aktivuje asynchronní sondy 'timer'. Překladač podporuje dvě varianty těch‐
       to sond:

              timer.jiffies(N)
              timer.jiffies(N).randomize(M)

       Sonda  je aktivována každých N jiffies. Pokud je dána komponenta 'randomize', je k hodnotě N přičteno ná‐
       hodné číslo v rozmezí -M .. +M. Při tom N musí nabývat rozumných hodnot, tj. přibližně z intervalu  1  ..
       1e+6,  a  současně M < N. Časovače neposkytují žádné kontextové proměnné. Na multiprocesorových systémech
       mohou tyto sondy běžet současně.

       Časové intervaly mohou být případně vyjádřeny i v jiných jednotkách. Příklad:

              timer.ms(N)
              timer.ms(N).randomize(M)

       V tomto případě jsou M a N vyjádřeny v milisekundách. Analogicky je  možno  čas  vyjadřovat  v  sekundách
       (s/sec),  milisekundách  (ms/msec), mikrosekundách (us/usec), nanosekundách (ns/nsec), a v hertzích (Hz).
       Randomizace není podporována je-li čas vyjádřen v jednotkách Hz.

       Skutečná přesnost časovačů závisí na konkrétním jádru. U jader starších než 2.6.17 byla nejmenší jednotka
       času jiffie, takže zadané časové intervaly se zaokrouhlily na celý počet jiffies. U novějších jader  jsou
       časovače  založeny na tzv. 'hrtimers' pro vyšší přesnost. Ovšem skutečná přesnost závisí na architektuře.
       V každém případě, pokud je dána komponenta 'randomize', pak náhodná složka bude  přidána  před  případným
       zaokrouhlováním.

       Existují také profilovací časovače, které tikají na všech CPU frekvencí CONFIG_HZ. Na některých systémech
       může  tento  časovač  používat jen jediný uživatel, na jiných systémech může být tento časovač nedostupný
       (EBUSY během registrace sondy).

              timer.profile.tick
              timer.profile.freq.hz(N)

       Při použití tohoto časovače je k dispozici plný kontext přerušeného procesu, takže tento časovač je vhod‐
       ný pro sbírání profilovacích vzorků.

       Doporučujeme používat timer.profile namísto timer.profile.tick. Obě sondy se chovají  podobně,  pokud  je
       dostupná  potřebná  funkcionalita  jádra. Ale timer.profile umí na novějších jádrech transparentně využít
       perf.sw.cpu_clock. Je tedy obecnější.

       Profilovací časovače s určenou frekvencí jsou přesné jen přibližně do 100 Hz.

       Poznamenejme, že pokud je frekvence 'timer' sondy příliš vysoké, a tělo sondy příliš složité,  mohou  být
       některé aktivace dané sondy přeskočeny, neboť jejich čas již uplynul. Normálně systemtap hlásí přeskočené
       sondy, ovšem takto přeskočené 'timer' sondy hlášeny nebudou.

   LADICÍ INFORMACE (DWARF)
       Tato  rodina sondážních bodů používá symbolické ladicí informace k analýze jádra / modulu / programu. La‐
       dicí informace mohou být buďto přímou součástí zkoumaného ELF objektu (unstripped), nebo samostatně  sto‐
       jící  (stripped)  např.  v rámci debuginfo RPM balíčků. Umožňují umístit sondy do exekuční cesty programu
       prostřednictvím symbolické specifikace umístění ve zdrojovém, nebo objektovém kódu. Jakmile se  odpovída‐
       jící příkaz na některé CPU vykoná, spustí se obslužný kód sondy v daném kontextu.

       Existuje několik druhů DWARF sond založených na ladicích informacích. Mohou být specifické pro jádro, ja‐
       derný modul, či uživatelský proces. Mohou se odkazovat na zdrojový soubor, na konkrétní řádku nebo funkci
       v něm, anebo na nějakou kombinaci uvedeného.

       Zde je seznam konkrétně podporovaných DWARF sond:

              kernel.function(PATTERN)
              kernel.function(PATTERN).call
              kernel.function(PATTERN).callee(PATTERN)
              kernel.function(PATTERN).callee(PATTERN).return
              kernel.function(PATTERN).callee(PATTERN).call
              kernel.function(PATTERN).callees(DEPTH)
              kernel.function(PATTERN).return
              kernel.function(PATTERN).inline
              kernel.function(PATTERN).label(LPATTERN)
              module(MPATTERN).function(PATTERN)
              module(MPATTERN).function(PATTERN).call
              module(MPATTERN).function(PATTERN).callee(PATTERN)
              module(MPATTERN).function(PATTERN).callee(PATTERN).return
              module(MPATTERN).function(PATTERN).callee(PATTERN).call
              module(MPATTERN).function(PATTERN).callees(DEPTH)
              module(MPATTERN).function(PATTERN).return
              module(MPATTERN).function(PATTERN).inline
              module(MPATTERN).function(PATTERN).label(LPATTERN)
              kernel.statement(PATTERN)
              kernel.statement(PATTERN).nearest
              kernel.statement(ADDRESS).absolute
              module(MPATTERN).statement(PATTERN)
              process("PATH").function("NAME")
              process("PATH").statement("*@FILE.c:123")
              process("PATH").library("PATH").function("NAME")
              process("PATH").library("PATH").statement("*@FILE.c:123")
              process("PATH").library("PATH").statement("*@FILE.c:123").nearest
              process("PATH").function("*").return
              process("PATH").function("myfun").label("foo")
              process("PATH").function("foo").callee("bar")
              process("PATH").function("foo").callee("bar").return
              process("PATH").function("foo").callee("bar").call
              process("PATH").function("foo").callees(DEPTH)
              process(PID).function("NAME")
              process(PID).function("myfun").label("foo")
              process(PID).plt("NAME")
              process(PID).plt("NAME").return
              process(PID).statement("*@FILE.c:123")
              process(PID).statement("*@FILE.c:123").nearest
              process(PID).statement(ADDRESS).absolute

       (Viz sekce ANALÝZA UŽIVATELSKÝCH PROCESŮ níže)

       Ve  výše  uvedených  sondách  lze  používat následující modifikátory / filtry, které přinášejí dodatečnou
       funkcionalitu:

              .function
                     Umístí sondu poblíž začátku uvedené funkce, takže funkční parametry jsou dostupné jako kon‐
                     textové proměnné.

              .return
                     Umístí sondu hned za bod návratu z dané funkce, takže návratová hodnota funkce je  dostupná
                     jako kontextová proměnná "$return".

              .inline
                     Filtr  propouštějící jen 'inline' funkce. Poznamenejme, že 'inline' funkce nemají identifi‐
                     kovatelný bod návratu, takže .return na .inline funkcích nelze použít.

              .call  Filtr propouštějící jen funkce, které nejsou 'inline' (opak .inline).

              .exported
                     Filtr propouštějící jen exportované funkce.

              .statement
                     Vloží sondu na konkrétní místo a zpřístupní lokální proměnné které jsou  v  daném  kontextu
                     viditelné.

              .statement.nearest
                     Vloží sondu na místo nejbližší danému číslu řádku (pro každé číslo řádku předané jako para‐
                     metr 'statement')

              .callee Vloží sondu do volané funkce .callee, která je volána funkcí
                     .function. Oproti přímému umístění sondy do funkce .callee má tento způsob výhodu v tom, že
                     sonda bude aktivní jen když volaná funkce .callee bude volána z dané funkce .function. Toto
                     chování lze potlačit direktivou -DSTAP_CALLEE_MATCHALL, viz stap(1)).

                     Poznamenejme,  že  mechanizmus 'callee' lze použít jen na staticky dohledatelné funkce. Me‐
                     chanizmus 'callee' nelze použít například na funkce volané prostřednictvím ukazatele,  nebo
                     na funkce z DSO knihoven. Další podmínkou je, aby kód byl překládán GCC 4.7+.

              .callees
                     Zkratka pro .callee("*"). Vloží sondu do všech funkcí volaných zadanou funkcí.

              .callees(DEPTH)
                     Rekurzivně umístí sondy do volaných funkcí až do hloubky DEPTH. Například .callees(2) vloží
                     sondu  nejen  do volaných funkcí, ale i do jimi volaných funkcí. Sonda v hloubce N bude ak‐
                     tivní jen když všechny volající funkce budou staticky dohledatelné. Toto chování lze potla‐
                     čit direktivou -DSTAP_CALLEE_MATCHALL, viz stap(1)).

       Ve výše uvedeném seznamu sondážních bodů zastupuje MPATTERN řetězcový literál, který určuje zkoumaný  ja‐
       derný  modul.  Pokud  se  modul  nachází  v  obvyklém  umístění  (in-tree), stačí jej určit jménem (např.
       "btrfs"). Jméno může obsahovat zástupné symboly, jako např. "*", "[]", a "?". Pokud se  modul  nachází  v
       neobvyklém  umístění  (out-of-tree),  je  potřeba použít absolutní cestu. V tomto případě nejsou zástupné
       symboly přípustné. Jméno souboru musí vyhovovat konvenčnímu schématu <module_name>.ko (znaky ',' a '-' se
       nahradí '_').

       LPATTERN je řetězcový literál, který odkazuje k umístění ve zdrojovém kódu. Může obsahovat zástupné  sym‐
       boly "*", "[]" a "?". Skládá se ze tří částí:

       •   První část je jméno funkce, tak, jak je zobrazí program nm . V této části lze použít zástupné symboly
           "*" a "?" k zadání více jmen.

       •   Druhá část je volitelná a začíná znakem "@". Následuje cesta ke zdrojovému souboru, který danou funk‐
           ci obsahuje. Cesta může obsahovat zástupné znaky jako např 'mm/slab*'. Pokud zadanému zástupnému sym‐
           bolu  nic  nevyhovuje, přidá překladač implicitně "*/" před daný zástupný symbol, takže v praxi stačí
           vyjmenovat několik posledních komponent cesty ke zdrojovému souboru.

       •   Nakonec třetí část je volitelná a určuje číslo řádku ve zdrojovém kódu. Číslu řádku  předchází  jeden
           ze  znaků ":", nebo "+". Předpokládá se, že číslo řádku je absolutní pokud mu předchází ":", nebo re‐
           lativní vzhledem k deklaraci funkce, pokud mu předchází "+". Všechny řádky funkce lze  vyjádřit  jako
           ":*",  rozsah  řádků  od  x  do  y  použitím  ":x-y". Rozsahy a konkrétní řádky lze kombinovat, např.
           ":x,y-z".

       Jako PATTERN lze zadat paměťovou adresu. Je to číselná konstanta odpovídající adrese  v  tabulce  symbolů
       objektového  souboru  jádra,  nebo jaderného modulu. Taková adresa bude ověřena proti známým limitům a za
       běhu relokována.

       V guru režimu lze zadat absolutní adresu jádra pomocí ".absolute". Taková adresa se považuje za již relo‐
       kovanou jako jsou adresy v /proc/kallsyms, a nelze ji validovat.

   KONTEXTOVÉ PROMĚNNÉ
       Mnohé z kontextových proměnných, jako jsou parametry funkcí, lokální proměnné, globální proměnné viditel‐
       né v kompilační jednotce, můžou být viditelné v obslužných rutinách sond. Jejich jména mají  prefix  "$".
       Pomocí  speciální  syntaxe  je  možné  do jisté míry dereferencovat ukazatele a procházet tak strukturami
       struktur a polí. Pěkný formátovaný výpis (pretty-printing) proměnných a jejich skupin je také možný.  Viz
       @cast.  Poznamenejme,  že proměnné mohou být nedostupné kvůli stránkování paměti, nebo i z jiných důvodů.
       Viz též manuálovou stránku error::fault(7stap).

       $var   se odkazuje k proměnné "var". Pokud jde o nějaký celočíselný typ, bude přetypován  na  typ  64-bit
              int pro použití v systemtap skriptech. Ukazatele na řetězce (char *), mohou být zkopírovány do ře‐
              tězcových proměnných pomocí funkcí kernel_string nebo user_string.

       @var("varname")
              je alternativní syntaxe pro $varname.

       @var("varname@src/file.c")
              se  odkazuje  ke globální (jak 'file local', tak 'external') proměnné varname definované v souboru
              src/file.c. Za relevantní kompilační jednotku se považuje ta, která má odpovídající jméno  souboru
              a při tom nejkratší cestu. Např. máme-li @var("foo@bar/baz.c") a kompilační jednotky src/sub/modu‐
              le/bar/baz.c  a src/bar/baz.c, pak druhá z kompilačních jednotek bude považovaná za relevantní pro
              proměnnou foo.

       Syntaxe $var->field slouží k procházení strukturou ukazatelů. Tento obecný
              dereferenční operátor lze opakovat a procházet tak více úrovněmi zanoření. Poznamenejme, že operá‐
              tor . se nepoužívá pro odkaz na člena struktury. Jak pro odkaz na člena struktury, tak pro derefe‐
              renci ukazatele se používá symbol -> neboť operátor "." je vyhrazen pro spojení řetězců.  Pozname‐
              nejme,   že   pro   přímé   dereferencování   ukazatele   se   doporučuje   použít   funkcí  {ker‐
              nel,user}_{char,int,...}($p). Více v sekci stapfuncs(5).

       $return
              je přístupný jen v .return sondách funkcí, které mají deklarovanou návratovou hodnotu. To lze  de‐
              tekovat pomocí @defined($return).

       $var[N]
              slouží k odkazu do pole podle daného indexu (číselný literál, nebo číselný výraz).

       Pro kontextové proměnné existuje řada operátorů:

       $$vars se expanduje na znakový řetězec následujícího formátu:

              sprintf("parm1=%x ... parmN=%x var1=%x ... varN=%x",
                      parm1, ..., parmN, var1, ..., varN)

              pro každou proměnnou v rozsahu (scope) sondážního bodu. Některé proměnné mohou mít hodnotu označe‐
              nou jako =? v případě, že nebyly úspěšně lokalizovány v paměťovém prostoru.

       $$locals
              se expanduje na podmnožinu $$vars pouze pro lokální proměnné.

       $$parms
              se expanduje na podmnožinu $$vars pouze pro funkční parametry.

       $$return
              je  dostupný  jen  v  .return sondách. Expanduje se na řetězec, který je ekvivalentní sprintf("re‐
              turn=%x", $return) pokud zkoumaná funkce má návratovou hodnotu (jinak bude roven prázdnému  řetěz‐
              ci)

       & $EXPR
              expanduje se na adresu dané kontextové proměnné (pokud je adresovatelná).

       @defined($EXPR)
              Expanduje  se  na 1 nebo 0, pokud je daná kontextová proměnná nalezitelná. Použít lze v podmínkách
              jako např.:

              @defined($foo->bar) ? $foo->bar : 0

       $EXPR$ Se expanduje na řetězec se všemi členy $EXPR. Formát:

              sprintf("{.a=%i, .b=%u, .c={...}, .d=[...]}",
                       $EXPR->a, $EXPR->b)

       $EXPR$$
              Se expanduje na řetězec se všemi členy $EXPR včetně vnořených členů. Formát:

              sprintf("{.a=%i, .b=%u, .c={.x=%p, .y=%c}, .d=[%i, ...]}",
                      $EXPR->a, $EXPR->b, $EXPR->c->x, $EXPR->c->y, $EXPR->d[0])

   NÁVRATOVÉ SONDY (RETURN PROBES)
       V jaderných 'return' sondách může být zpracován jen relativně malý počet návratů ".return" z funkce.  Vý‐
       chozí  počet  je  malé  číslo, přibližně jen několikanásobek počtu fyzických CPU. Pokud danou funkci volá
       současně více vláken (jako např. futex(), nebo read()), může být tento limit snadno překročen. V tom pří‐
       padě bude "stap -t" hlásit přeskočené sondy 'kretprobe'. Obejít tento problém je možno použitím přípony

              probe FOO.return.maxactive(NNN)

       s dostatečně velkým NNN. Případně lze na příkazové řádce zadat

              stap -DKRETACTIVE=NNNN

       čímž se tento problém obejde pro všechny ".return" sondy ve skriptu.

       Pro pohodlí uživatele jsou v ".return" sondách přístupné i jiné kontextové proměnné, než jen $return. Jde
       zejména o parametry volání funkce. V tomto případě ale jde o kopie (snapshot) vytvořené v momentě  vstupu
       do funkce. (Lokální proměnné funkce obecně nejsou dostupné, neboť ty v době vytváření "snapshotu" neexis‐
       tovaly.) Vhodným způsobem přístupu k těmto proměnným je @entry($var).

       Při vstupu do funkce je možno uložit pomocné hodnoty pro pozdější využití v ondách pomocí operátoru @ent‐
       ry(expr). Například tak lze změřit dobu běhu funkce:

              probe kernel.function("do_filp_open").return {
                  println( get_timeofday_us() - @entry(get_timeofday_us()) )
              }

       Následující tabulka ukazuje, jak lze přistoupit ke kontextovým proměnným funkčních hodnot. Ukazatel s ná‐
       zvem addr je použitelný v .return sondě.
       vstupní hodnota   hodnota po výstupu z funkce

       $addr             not available
       $addr->x->y       @cast(@entry($addr),"struct zz")->x->y
       $addr[0]          {kernel,user}_{char,int,...}(& $addr[0])

   SONDY NEZÁVISLÉ NA LADICÍCH INFORMACÍCH (DWARFLESS PROBES)
       V  případech,  kdy  ladicí informace nejsou k dispozici, lze do míst volání a výstupu do/z funkcí vkládat
       sondy z rodiny 'kprobe'. Ty ovšem neumožňují vyhledávání lokálních proměnných  a/nebo  parametrů  funkcí.
       Podporovány jsou následující konstrukce:

              kprobe.function(FUNCTION)
              kprobe.function(FUNCTION).call
              kprobe.function(FUNCTION).return
              kprobe.module(NAME).function(FUNCTION)
              kprobe.module(NAME).function(FUNCTION).call
              kprobe.module(NAME).function(FUNCTION).return
              kprobe.statement(ADDRESS).absolute

       Pro  jaderné  funkce doporučujeme použít sondy typu function zatímco pro analýzu modulů jsou vhodné sondy
       module V případech, kdy je známa absolutní adresa v jádře, nebo v modulu, lze použít  sondy  typu  state‐
       ment.

       Poznamenejme,  že  FUNCTION a MODULE nesmí obsahovat zástupné symboly, jinak sonda nebude zaregistrována.
       Dále pozn., že ".statement" funguje jen v guru režimu.

   UŽIVATELSKÉ PROCESY (USER-SPACE)
       Analýza uživatelských procesů je dostupná nad jádry, která jsou konfigurována s 'utrace', nebo  'uprobes'
       (3.5+)  rozšířeními  (jde o širokou sadu konfiguračních voleb, které musí být zapnuty, systemtap bude je‐
       jich nedostupnost ohlašovat).

       Existuje několik syntaktických podob sond pro uživatelské procesy. První forma:

              process(PID).statement(ADDRESS).absolute

       je analogická kernel.statement(ADDRESS).absolute v tom, že obě používají syrové (raw), tj. neverifikované
       adresy a nezpřístupňují kontextové proměnné. Musí být zadán PID běžícího procesu a daná adresa ADDRESS by
       měla identifikovat validní adresu instrukce. Analyzována budou všechna vlákna.

       Druhá forma slouží k analyzování nesymbolických událostí obsluhovaných mechanizmem 'utrace':

              process(PID).begin
              process("FULLPATH").begin
              process.begin
              process(PID).thread.begin
              process("FULLPATH").thread.begin
              process.thread.begin
              process(PID).end
              process("FULLPATH").end
              process.end
              process(PID).thread.end
              process("FULLPATH").thread.end
              process.thread.end
              process(PID).syscall
              process("FULLPATH").syscall
              process.syscall
              process(PID).syscall.return
              process("FULLPATH").syscall.return
              process.syscall.return

       process.begin sonda je aktivována při vytvoření nového procesu daného PID, nebo FULLPATH. Navíc  je  tato
       sonda volána jedenkrát z kontextu každého procesu, který za běhu systemtap skriptu vznikne. To je užiteč‐
       né pro udržování seznamu běžících procesů.

       process.thread.begin sonda je aktivována při vytvoření nového vlákna daného PID, nebo FULLPATH.

       process.end sonda je aktivována při ukončení procesu daného PID, nebo FULLPATH.

       process.thread.end sonda je aktivována při ukončení vlákna daného PID, nebo FULLPATH.

       process.syscall  sonda  je aktivována když vlákno daného PID nebo FULLPATH zavolá systémové volání. Číslo
       systémového volání je přístupné v kontextové proměnné $syscall a prvních 6 funkčních argumentů v  kontex‐
       tových proměnných $argN (ex. $arg1, $arg2, ...). Sonda process.syscall.return sonda je aktivována když se
       vlákno daného PID nebo FULLPATH vrací ze systémového volání. Číslo systémového volání je přístupné v kon‐
       textové proměnné $syscall a návratová hodnota systémového volání pak v rámci kontextové proměnné $return.
       Sonda

       Pokud  je sonda specifikována bez PID, nebo FULLPATH, budou analyzována vlákna všech uživatelských proce‐
       sů. Ovšem pokud byl stap volán s přepínačem -c nebo -x, pak bude brán v potaz pouze daný  proces  a  jeho
       potomci. Pokud chybí jak specifikace PID, tak specifikace FULLPATH, ale je dán přepínač -c , bude cesta k
       programu  doplněna  na  základě heuristiky. V tom případě jsou v rámci argumentu -c přípustné jen příkazy
       (tj. přípustné nejsou zejména např. substituce a nesmí se ani vyskytnout znaky '|&;<>(){}').).

       Třetí typ: Je založen na statické instrumentaci, která je již zakompilovaná do programů a DSO knihoven.

              process("PATH").mark("LABEL")
              process("PATH").provider("PROVIDER").mark("LABEL")
              process(PID).mark("LABEL")
              process(PID).provider("PROVIDER").mark("LABEL")

       Sonda .mark bude aktivována, jakmile vykonávání programu dosáhne místa,  kde  je  zapřekládána  speciální
       značka  pomocí  makra STAP_PROBE1(PROVIDER,LABEL,arg1). Toto makro je definováno v sys/sdt.h. PROVIDER je
       volitelný identifikátor aplikace, LABEL identifikátor značky, a arg1 je celočíselný argument. Pro sondy s
       jedním argumentem se použije makro STAP_PROBE1, pro sondy se dvěma argumenty makro STAP_PROBE2 a tak  dá‐
       le. Proměnné arg1, arg2, ... argN jsou pak dostupné v kontextu sondy.

       Alternativou  k  použití makra STAP_PROBE je použít dtrace skript k vytvoření uživatelských maker. V kon‐
       textu sondy jsou též dostupné proměnné $$name a $$provider. V sys/sdt.h se definuje  makro  DTRACE_PROBE*
       jako přezdívka pro STAP_PROBE*.

       Poslední typ: V uživatelských programech jsou dostupné všechny varianty DWARF sond. Jsou analogické k ja‐
       derným DWARF sondám, nebo DWARF sondám pro jaderné moduly popsaným výše. Poskytují přístup ke kontextovým
       proměnným pro parametry funkcí, lokální proměnné atd:

              process("PATH").function("NAME")
              process("PATH").statement("*@FILE.c:123")
              process("PATH").plt("NAME")
              process("PATH").library("PATH").plt("NAME")
              process("PATH").library("PATH").function("NAME")
              process("PATH").library("PATH").statement("*@FILE.c:123")
              process("PATH").function("*").return
              process("PATH").function("myfun").label("foo")
              process("PATH").function("foo").callee("bar")
              process("PATH").plt("NAME").return
              process(PID).function("NAME")
              process(PID).statement("*@FILE.c:123")
              process(PID).plt("NAME")

       Poznamenejme,  že  pro  všechny  sondy pro uživatelské procesy platí, že PATH se odkazuje k spustitelnému
       souboru, jehož absolutní umístění se dohledává podobně jako to dělají shelly, tj. relativně k  aktuálnímu
       adresáři pokud obsahují lomítko "/", jinak v $PATH. Pokud se PATH odkazuje na skript, bude předmětem ana‐
       lýzy příslušný interpreter tak, jak je definován v prvním řádku skriptu za sekvencí #! (shebang).

       Pokud  je  PATH  parametrem komponenty '.process' a odkazuje se na sdílenou DSO knihovnu, pak analyzovány
       budou všechny procesy, které tuto knihovnu využívají. Pokud je PATH parametrem komponenty '.library', pak
       analyzován bude pouze daný proces. Poznamenejme, že PATH v rámci komponenty '.library' se  vždy  vztahuje
       na knihovny, které lze z daného spustitelného souboru zjistit staticky. Nicméně vždy je možné uvést abso‐
       lutní cestu k libovolné knihovně explicitně.

       Sonda  .plt  bude umístěns do 'program linkage' tabulky odpovídající zbytku definice sondážního bodu. Při
       tom .plt je zkratkou pro .plt("*"). Jméno symbolu je dostupné v  kontextové  proměnné  $$name,  parametry
       funkcí dostupné nejsou, protože PLT sondy se zpracovávají bez ladicích informací. Sonda funkce.

       Řetězec  PATH  může obsahovat zástupné symboly, jako tomu bylo v případě MPATTERN. V tomto případě nebude
       brán zřetel na proměnnou $PATH.

       Pokud je systemtap vyvolán s jedním z přepínačů -c nebo -x pak bude analýza omezena na  cílový  proces  a
       jeho potomky.

   JAVA
       Podpora  pro instrumentaci java metod je založena na nástroji Byteman, což je software sloužící k instru‐
       mentaci javy vyvíjený v rámci JBoss projektu. Systemtap tak může detekovat vykonání java metody, nebo vy‐
       konání daného řádku java programu.

       Instrumentace javy je založená na generování byteman skriptu a následném volání bminstall.

       V současnosti je instrumentace javy prototypem s významnými omezeními: Instrumentace javy  nefunguje  na‐
       příč  uživateli.  Systemtap skript musí být spuštěn stejným uživatelem, jako instrumentovaný proces. Tedy
       zejména, a to je ne neobvyklé, systemtap skript spuštěný rootem nemůže  analyzovat  java  program  jiného
       uživatele.

       První typ java sond se odkazuje k java procesům jménem:

              java("PNAME").class("CLASSNAME").method("PATTERN")
              java("PNAME").class("CLASSNAME").method("PATTERN").return

       Argument PNAME musí být již existující jvm PID a musí být viditelný ve výpisu programu jps.

       Parametr  PATTERN  určuje  signaturu  java  metody, která se má instrumentovat. Signatura musí sestávat z
       přesného  jména  java  metody  následovaného  uzávorkovaným  seznamem  typů  argumentů.  Příklad:  "myMe‐
       thod(int,double,Foo)". Zástupné znaky se zde nepodporují.

       Sondu  lze  vložit  na  konkrétní  řádek připojením dvojtečky a čísla řádku jako obvykle. Příklad: "myMe‐
       thod(int,double,Foo):245".

       Parametr CLASSNAME identifikuje Java třídu, ke které metoda náleží, a to jak s, tak bez uvedení názvu ba‐
       líčku (package). Za normálních okolností bude sonda aktivní také na potomcích dané třídy, kteří  ponechá‐
       vají  danou  metodu  nepředefinovanou.  Nicméně,  CLASSNAME  přijímá  volitelný  prefix  "^"  jako  např:
       ^org.my.MyClass, který značí, že sonda by měla být též aktivní na  všech  potomcích  dané  třídy,  včetně
       těch,  kteří  danou metodu předefinovali. Například všechny metody foo(int) v programu org.my.MyApp mohou
       být instrumentovány takto:

              java("org.my.MyApp").class("^java.lang.Object").method("foo(int)")

       Druhý typ sond funguje analogicky, ovšem odkazuje se k java procesu prostřednictvím PID:

              java(PID).class("CLASSNAME").method("PATTERN")
              java(PID).class("CLASSNAME").method("PATTERN").return

       (PID již běžícího procesu lze získat pomocí jps(1). )

       Kontextové proměnné definované v java sondách zahrnují $arg1$arg10 (pro až 10 prvních parametrů meto‐
       dy), jakožto ukazatele na řetězce, které lze podle potřeby předhodit ke zpracování funkci toString().

       Proměnné arg1arg10 zpřístupňují zmíněné argumenty metody přímo jakožto řetězce  získané  prostřednic‐
       tvím user_string_warn().

       Ve  starších  verzích systemtapu (3.1 a níže) obsahovaly $arg1$arg10 buďto celá čísla, nebo ukazatele
       na řetězce, v závislosti na typu odpovídajících objektů. Toto historické chování lze použít v režimu stap
       --compatible=3.0 .

   PROCFS
       Následující sondy umožňují vytvářet / číst "soubory" v /proc/systemtap/MODNAME. Při tom je možné  defino‐
       vat  umask.  výchozí  hodnoty jsou 0400 pro čtecí sondy a 0200 pro zapisovací sondy. Pokud jsou na jednom
       souboru používány sondy jak pro čtení, tak pro zápis, pak výchozí oprávnění bude 0600.

       Sonda procfs.umask(0040).read způsobí nastavení oprávnění 0404 na souboru. (MODNAME  je  jméno  systemtap
       modulu). Souborový (pseudo-) systém proc se používá jako uživatelské rozhraní pro datové struktury jádra.
       Překladač podporuje několik variant procfs sond:

              procfs("PATH").read
              procfs("PATH").umask(UMASK).read
              procfs("PATH").read.maxsize(MAXSIZE)
              procfs("PATH").umask(UMASK).maxsize(MAXSIZE)
              procfs("PATH").write
              procfs("PATH").umask(UMASK).write
              procfs.read
              procfs.umask(UMASK).read
              procfs.read.maxsize(MAXSIZE)
              procfs.umask(UMASK).read.maxsize(MAXSIZE)
              procfs.write
              procfs.umask(UMASK).write

       PATH  je cesta relativní vzhledem k /proc/systemtap/MODNAME Pokud není PATH určeno (tak jako u posledních
       dvou variant výše), pak PATH nabývá výchozí hodnoty "command". Název souboru "__stdin" se vnitřně používá
       v "input" sondách a neměl by se používat v roli PATH procfs sond; viz sekce INPUT níže.

       Když uživatel čte /proc/systemtap/MODNAME/PATH, aktivuje se procfs read proba. Řetězcová data ke čtení se
       přiřadí proměnné $value. Příklad:

              procfs("PATH").read { $value = "100\n" }

       Když uživatel zapisuje do /proc/systemtap/MODNAME/PATH, aktivuje se odpovídající write sonda. Data zapsa‐
       ná uživatelem jsou pak dostupná v proměnné $value. Příklad:

              procfs("PATH").write { printf("user wrote: %s", $value) }

       MAXSIZE Maximální velikost procfs čtecího bufferu a procfs výstupu. Pokud MAXSIZE není  nastavena,  veli‐
       kost  čtecího  bufferu se položí rovna STP_PROCFS_BUFSIZE (s výchozí hodnotou MAXSTRINGLEN, tj. maximální
       délka řetězce). V případě, kdy je třeba nastavit velikost čtecích bufferů pro více než jeden procfs  sou‐
       bor, může pomoci STP_PROCFS_BUFSIZE .

       Zde je příklad použití MAXSIZE:

              procfs.read.maxsize(1024) {
                  $value = "dlouhý řetězec..."
                  $value .= "jiný dlouhý řetězec..."
                  $value .= "jiný dlouhý řetězec..."
                  $value .= "jiný dlouhý řetězec..."
              }

   INPUT
       Tyto  sondy zpřístupňují standardní vstup skriptu v době jeho běhu. Překladač podporuje dvě varianty této
       rodiny sond:

              input.char
              input.line

       input.char se aktivuje po každém přečtení znaku ze standardního vstupu. Dotyčný znak je pak dostupný pro‐
       střednictvím proměnné char. Nehraje zde roli žádná vyrovnávací paměť.

       input.line Znaky načtené ze standardního vstupu se ukládají do vyrovnávací paměti až do okamžiku  načtení
       znaku  nového řádku. Po načtení celého řádku se tento včetně ukončovacího znaku stane dostupným prostřed‐
       nictvím proměnné line. Při tom maximální délka řádku je MAXSTRINGLEN. Znaky přesahující  MAXSTRINGLEN  se
       do line nedostanou.

       Tyto  input  sondy  jsou ve skutečnosti přezdívkami pro procfs("__stdin").write. Pokud uživatelský skript
       obsahuje procfs sondu, neměl by využívat "__stdin" jako argument "procfs" sond. Sondy  "input"  nefungují
       při použití -F a --remote voleb.

   SONDY 'NETFILTER HOOKS'
       Sondy 'netfilter hooks', (dále jen netfilter sondy) umožní sledování síťových paketů pomocí jaderného me‐
       chanizmu 'netfilter'. Netfilter sonda odpovídá funkci 'netfilter hook' s využitím originálního API. Prav‐
       děpodobně  pohodlnější,  než  používání "syrových" sondážních bodů překladače, je použít příslušné tapset
       funkce tapset::netfilter(3stap), které poskytují praktickou obálku.

       Překladač podporuje několik variant netfilter sond:

              netfilter.hook("HOOKNAME").pf("PROTOCOL_F")
              netfilter.pf("PROTOCOL_F").hook("HOOKNAME")
              netfilter.hook("HOOKNAME").pf("PROTOCOL_F").priority("PRIORITY")
              netfilter.pf("PROTOCOL_F").hook("HOOKNAME").priority("PRIORITY")

       PROTOCOL_F je rodina protokolů které mají být využity k poslouchání. V současností jsou k  dispozici  ná‐
       sledující možnosti:

       NFPROTO_IPV4, NFPROTO_IPV6, NFPROTO_ARP, nebo NFPROTO_BRIDGE.

       HOOKNAME  je  bod  ('hook')  v rámci daného protokolu, ve kterém se zachytí paket. Seznam dostupných typů
       příslušných sondážních bodů nalezne čtenář v hlavičkových souborech <linux/netfilter_ipv4.h>, <linux/net‐
       filter_ipv6.h>, <linux/netfilter_arp.h> a <linux/netfilter_bridge.h>. Například použitelné sondážní  body
       pro  NFPROTO_IPV4  jsou  NF_INET_PRE_ROUTING,  NF_INET_LOCAL_IN,  NF_INET_FORWARD,  NF_INET_LOCAL_OUT,  a
       NF_INET_POST_ROUTING.

       PRIORITY Je celočíselná priorita určující pořadí aktivace netfilter sond vzhledem k  ostatním  'netfilter
       hook'  funkcím  pro  daný  paket. Na daném paketu se nejdříve vykonají 'hetfilter hook' funkce s nejnižší
       prioritou, poté funkce s vyšší prioritou. Pokud PRIORITY není specifikovaná (jako je tomu v prvních  dvou
       příkladech výše), bude efektivně PRIORITY rovna nule.

       Existuje  řada pojmenovaných priorit tvaru NF_IP_PRI_* a NF_IP6_PRI_* , které jsou definovány v hlavičko‐
       vých souborech jádra <linux/netfilter_ipv4.h> a <linux/netfilter_ipv6.h>. Tato makra mohou být použita  v
       systemtap  skriptech.  Výjimkou  jsou sondážní body pro NFPROTO_ARP a NFPROTO_BRIDGE pro které momentálně
       neexistují pojmenované priority. Přijatelné způsoby nastavení priorit:

              priority("255")
              priority("NF_IP_PRI_SELINUX_LAST")

       Skript v guru režimu může určit libovolný identifikátor nebo číslo jako parametr 'hook', 'pf' a  'priori‐
       ty', což je vhodné používat opatrně, neboť parametr se vkládá do vygenerovaného C kódu doslovně.

       V rámci netfilter sond existují následující kontextové proměnné:

       $hooknum
              Číslo identifikující 'netfilter hook'.

       $skb   adresa struktury sk_buff, která reprezentuje paket. Viz hlavičkový soubor <linux/skbuff.h> a manu‐
              álovou stránku tapset::netfilter(3stap) pro podrobnější informace.

       $in    Adresa  struktury net_device, která reprezentuje síťové zařízení ze kterého paket přišel. Může být
              0 pokud zařízení není známo nebo definováno.

       $out   Adresa struktury net_device reprezentující síťové zařízení na které má být paket odeslán. Může být
              0 pokud zařízení není známo nebo definováno.

       $verdict
              Je dostupný jen v guru režimu. Nastavením této hodnoty (viz  <linux/netfilter.h>)  se  rozhodne  o
              dalším způsobu zpracování paketu v paketovém filtru. Například následující guru skript způsobí za‐
              hazování všech IPv6 paketů:

              probe netfilter.pf("NFPROTO_IPV6").hook("NF_IP6_PRE_ROUTING") {
                $verdict = 0 /* nf_drop */
              }

              Pro  pohodlí uživatele poskytují netfilter sondy definované v tapset::netfilter(3stap) hodnoty pro
              proměnnou 'verdict' jako lokální proměnné. Například proměnná 'nf_drop' obsahuje hodnotu NF_DROP.

   SONDÁŽNÍ BODY TYPU 'TRACEPOINT'
       Tato rodina sondážních bodů je založena na staticky zakompilovaných značkách typu 'tracepoint' (dále  jen
       tracepoint  body)  vložených  do jádra, nebo jaderného modulu. Systemtap umí tyto značky detekovat pomocí
       sondážních bodů typu 'tracepoint', dále jen 'tracepoint sondy'. Tracepoint sondy jsou spolehlivější,  než
       sondy  založené  na DWARF ladicích informacích. Pro funkčnost tracepoint sond není nutná přítomnost ladi‐
       cích informací. Další výhodou tracepoint sond jsou silněji typované parametry  ve  srovnání  se  značkami
       (markers).

       Příklady tracepoint sond: kernel.trace("name"). Řetězcový literál "name" může obsahovat zástupné symboly.
       Pro  omezení  sondy  na  konkrétní subsystém (např. sched, ext3, atd...), lze využít následující syntaxe:
       kernel.trace("subsystém:jméno").

       Obslužný kód pro tracepoint sondy může číst volitelné parametry, které autoři tracepoint bodů připravili.
       Například sondážní bod kernel.trace("sched:sched_switch") poskytuje parametry $prev a $next. Pokud je pa‐
       rametrem ukazatel, lze jej dereferencovat pomocí stejné syntaxe jako je tomu u DWARF sond. Hodnoty  para‐
       metrů tracepoint sond nelze modifikovat. V guru režimu lze ovšem modifikovat proměnné dereferencované po‐
       mocí parametrů tracepoint sond.

       Jméno  subsystému a jméno tracepoint bodu je přístupné prostřednictvím proměnných $$system resp. $$name a
       řetězcová reprezentace párů jméno=hodnota je pak dostupná prostřednictvím $$vars nebo $$parms.

   JADERNÉ ZNAČKY (KERNEL MARKERS) (ZASTARALÉ)
       Tato rodina sondážních bodů je postavena na poněkud zastaralém mechanizmu statických značek, které se vy‐
       skytují ve starších jádrech a jaderných modulech. Jde o makra STAP_MARK, které do jádra vložili  vývojáři
       aby usnadnili instrumentaci jádra a učinili ji spolehlivou. Proto DWARF ladicí informace nejsou pro tento
       typ instrumentace potřeba.

       Sondážní  bod pro jadernou značku začíná kernel. další částí je jméno značky samotné: mark("name"). Řetě‐
       zec vyjadřující jméno značky může obsahovat obvyklé zástupné symboly a porovnává se proti vývojářem zave‐
       denému jménu značky. Volitelně lze uvést formát: format("format"), čímž se odliší značky se stejným  jmé‐
       nem, ale odlišným označením pro formát.

       Obslužný  kód pro tento typ sond může číst parametry, které mohou být v místě značky dostupné jako: $arg1$argNN, Kde NN je počet parametrů podporovaných makrem. Parametry mohou být řetězcového a celočíselné‐
       ho typu.

       Hodnota atributu 'format' značky je dostupná v proměnné $format. Hodnota atributu 'name' v $name.

   HARDWAROVÉ BODY ZASTAVENÍ (HARDWARE BREAKPOINTS)
       Tato skupina sond slouží k nastavení hardwarových bodů zastavení pro daný globální symbol jádra. Přísluš‐
       né sondy sestávají ze tří komponent:

       1. virtuální adresa" / "jméno zkoumaného symbolu jádra se předává jako argument této třídě sond. Podporo‐
       vány jsou pouze sondy pro proměnné v datovém segmentu. Analýzu lokálních proměnných nelze provést.

       2. Způsob přístupu : a. sonda .write se aktivuje, jakmile dojde na zadané adrese / symbolu k  zápisu.  b.
       sonda rw se aktivuje, jakmile dojde na zadané adrese / symbolu ke čtení.

       3.  .length  (volitelné) uživatel má možnost vymezit rozsah adres pro analýzu pomocí "length". Uživatelem
       určená hodnota se zaokrouhlí na nejbližší hardwarem podporovanou hodnotu. Pokud se hodnota 'length' neza‐
       dá, položí ji překladač rovnu jedné. Pozn., že 'length' nelze použít v kombinaci se symbolickými jmény.

       Podporovány jsou následující syntaktické konstrukce.

              probe kernel.data(ADDRESS).write
              probe kernel.data(ADDRESS).rw
              probe kernel.data(ADDRESS).length(LEN).write
              probe kernel.data(ADDRESS).length(LEN).rw
              probe kernel.data("SYMBOL_NAME").write
              probe kernel.data("SYMBOL_NAME").rw

       Tato skupina sond využívá ladicí registry procesoru, což je vzácný zdroj. Architektura x86_64 nabízí čty‐
       ři ladicí registry, powerpc jen jeden. Pokud se uživatel pokusí využít více ladicích registrů, než  kolik
       jich má k dispozici, překlad skončí chybou ve fázi 2.

   PERF SONDY
       Tato  skupina sond je rozhraním pro infrastrukturu jádra "perf event", která pracuje s hardwarovými poči‐
       tadly (hardware performance counters). Událost, se kterou se má proba svázat, se specifikuje pomocí atri‐
       butů "type" a "config" struktury perf_event_attr. Vzorkovací frekvence  se  určí  pomocí  atributů  "sam‐
       ple_period" nebo "sample_freq".

       Tento typ sond používá následující syntaxi:

              probe perf.type(NN).config(MM).sample(XX)
              probe perf.type(NN).config(MM).hz(XX)
              probe perf.type(NN).config(MM)
              probe perf.type(NN).config(MM).process("PROC")
              probe perf.type(NN).config(MM).counter("COUNTER")
              probe perf.type(NN).config(MM).process("PROC").counter("COUNTER")

       Obslužná rutina sondy se při použití '.sample' zavolá jednou za XX inkrementů daného počitadla, nebo, po‐
       kud  se  použije  .hz,  po  uplynutí  periody  dané  frekvence. Bez specifikace položí překladač XX rovno
       1000000. Platný rozsah je specifikován v popisu systémového volání perf_event_open(2) a / nebo v  hlavič‐
       kovém souboru linux/perf_event.h.

       Neplatné  nastavení  skončí chybou překladu. Kontrola platnosti zadaných hodnot se provádí v rámci jádra.
       Za normálních okolností je .perf sonda platná pro celý systém. Pokud se určí .process, pak jen  pro  daný
       uživatelský proces. Pokud se vynechá jméno procesu, pokusí se ho překladač odvodit z -c. Událost lze číst
       použitím  '.counter'.  Obslužná rutina perf sondy se pro .counter nezavolá, ale počitadlo lze číst pomocí
       následující syntaxe:

          process("PROC").statement("func@file") {stat <<< @perf("NAME")}

   PYTHON
       S použitím speciálního python modulu je možné analyzovat python 2 a python 3 funkce. K  tomu  je  potřeba
       mít nainstalované ladicí informace pro příslušný python. Zmíněný modul lze použít takto:

              stap foo.stp -c "python -m HelperSDT foo.py"

       Příslušné sondy potom vypadají takto:

              python2.module("MPATTERN").function("PATTERN")
              python2.module("MPATTERN").function("PATTERN").call
              python2.module("MPATTERN").function("PATTERN").return
              python3.module("MPATTERN").function("PATTERN")
              python3.module("MPATTERN").function("PATTERN").call
              python3.module("MPATTERN").function("PATTERN").return

       Výše zmíněná ukázka obsahuje následující modifikátory:

              .function
                     Umístí sondu na začátek funkce určené jménem, pokud není prostřednictvím PATTERN určeno ji‐
                     nak. Funkční parametry jsou dostupné jako kontextové proměnné.

              .call  Umístí  sondu na začátek funkce určené jménem. Funkční parametry jsou dostupné jako kontex‐
                     tové proměnné.

              .return
                     Umístí sondu těsně před návrat z funkce určené jménem. Parametry funkce, jakož  i  lokální,
                     či globální proměnné jsou dostupné prostřednictvím kontextových proměnných.

       PATTERN představuje řetězcový literál, který určuje pozici v python programu. Skládá se ze tří částí:

       •   První  částí  je  jméno funkce (například "foo"), nebo metody (například "bar.baz"). V této části lze
           používat také zástupné symboly "*" a "?".

       •   Druhá část je volitelná a začíná znakem "@". Za ní následuje cesta k souboru,  který  obsahuje  danou
           funkci/metodu.  Zde  lze  taktéž  použít zástupné symboly "*" a "?". Pro vyhledávání ze vezme v potaz
           "python path".

       •   Poslední, třetí volitelnou částí, je speecifikace čísla řádku ve zdrojovém souboru.  Číslo  řádku  se
           zapisuje  za dvojtečku ":", nebo plus "+". V případě dvojtečky se číslo řádku interpretuje jako abso‐
           lutní číslo řádku, v případě plusu jako relativní vzhledem k deklaraci  funkce.  Všechny  řádky  dané
           funkce lze označit zápisem ":*". Rozsah řádků se zapíše jako ":x-y", či ":x,y-z".

       MPATTERN zastupuje název python modulu, nebo skriptu, který se na python modul odkazuje. I zde lze použít
       zástupné znaky "*" a "?". Daný název souboru se hledá v rámci "python path".

PŘÍKLADY

       Zde uvádíme několik konkrétních příkladů sond.

       begin, end, end
              odkazuje  se  k začátku a k normálnímu ukončení sezení. V tomto případě se obslužná rutina provede
              jednou při začátku sezení, a dvakrát při jeho normálním ukončení.

       timer.jiffies(1000).randomize(200)
              sonda se aktivuje periodicky každých 1000 +/- 200 jiffies.

       kernel.function("*init*"), kernel.function("*exit*")
              odkazuje se ke všem jaderným funkcím, jejichž jméno obsahuje podřetězec "init", nebo "exit".

       kernel.function("*@kernel/time.c:240")
              odkazuje se k libovolné funkci z "kernel/time.c", kde část jejího těla leží na řádku 240. Pozname‐
              nejme, že v tomto případě nejde o sondu vloženou na daný řádek. Pro vložení sondy  na  daný  řádek
              použijte kernel.statement .

       kernel.trace("sched_*")
              odkazuje se ke všem 'tracepoint' bodům s prefixem "sched_", tj. souvisejícím s časovačem.

       kernel.mark("getuid")
              odkazuje se k zastaralému jadernému makru STAP_MARK(getuid, ...).

       module("usb*").function("*sync*").return
              odkazuje se k bodu návratu ze všech funkcí, které obsahují "sync" ve svém jméně a nachází se v ně‐
              kterém z USB modulů.

       kernel.statement(0xc0044852)
              odkazuje se k prvnímu bajtu příkazu, jehož přeložené instrukce leží na dané adrese v jádře.

       kernel.statement("*@kernel/time.c:296")
              odkazuje se k příkazu na řádku 290 v souboru "kernel/time.c".

       kernel.statement("bio_init@fs/bio.c+3")
              odkazuje se k příkazu na řádku bio_init+3 v souboru "fs/bio.c".

       kernel.data("pid_max").write
              odkazuje se k hardwarovému breakpointu typu "write" nastavenému na pid_max.

       syscall.*.return
              odkazuje se ke skupině přezdívek sond s libovolným jménem druhé komponenty.

VIZ TÉŽ

       stap(1),
       probe::*(3stap),
       tapset::*(3stap)

                                                                                               STAPPROBES(3stap)