STAPPROBES(3stap) STAPPROBES(3stap) JMENO stapprobes - prehled sondaznich bodu systemtapu POPIS Nasledujici text prinasi prehled zakladnich druhu sondaznich bodu (probe points) podporovanych prekladacem systemtapu. Zmineny jsou take nektere prezdivky (aliases) definovane v tapset skriptech. Podrobnejsi individualni informace k mnohym z nich prinaseji man stranky s prefixem probe:: sdruzene v man sekci 3stap. SYNTAXE probe PROBEPOINT [, PROBEPOINT] { [STMT ...] } Deklarace sondy (probe) muze obsahovat seznam carkou oddelenych sondaznich bodu. Sonda pak bude svazana se vsemi takto zminenymi sondaznimi body, potazmo udalostmi v systemu. Jednotlivy sondazni bod se zapise jako posloupnost teckou oddelenych komponent, napriklad 'syscall.read', kde 'syscall' a 'read' jsou komponenty. Komponenty odpovidaji urcitym tridam deleni jmenneho prostoru udalosti. Pripomina to zapis domenoveho jmena pocitace na internetu. Kazda komponenta muze byt presneji specifikovana ciselnym, nebo retezcovym parametrem uvedenym v zavorkach, podobne jako pri volani funkce. V ramci deklarace sondy lze pouzit zastupny symbol hvezda "*", ktery bude expandovan v ramci jedne z teckou oddelenych komponent, nebo symbol "**", ktery bude expandovan pres vice nez jednu komponentu (v extremnim pripade pres vsechny). Prezdivka sondy se syntakticky chova podobne jako sonda samotna. Lze tez pracovat s prezdivkami prezdivek. Prezdivku sondy lze volat samostatne, nebo s priponou. Pripona se pri prekladu pripoji k sonde nad kterou je prezdivka definovana. Priklad: syscall.read.return.maxactive(10) se expanduje na kernel.function("sys_read").return.maxactive(10) kde maxactive(10) se chape jako pripona. Kazdy sondazni bod se po expanzi zastupnych symbolu a prezdivek mapuje na nejaky nizkourovnovy prvek systemu, jako napriklad na 'kprobe' adresu, na znacku (marker), na udalost casovace a podobne. Pokud takove mapovani selze (napriklad snazime-li se odkazat na jaderny modul ktery neni zaveden), preklad skriptu selze. Sondazni bod muze byt nasledovan znakem "?", a pak je povazovan za volitelny. V tom pripade nedojde k chybe prekladu, pokud se mapovani nezdari. Tento priznak volitelnosti se pri prekladu predava nize pres prezdivky a expanze az k elementarnim sondaznim bodum prekladace. Sondazni bod muze byt tez nasledovan znakem "!". V tom pripade je povazovan za volitelny a dostatecny. Volne to pripomina 'cut' operator znamy z prologu. Pokud se takovy "dostatecny" sondazni bod podari uspesne namapovat, pak se uz prekladac nepokousi o mapovani dalsich (carkou oddelenych) sondaznich bodu definujicich danou sondu. Oznacit sondazni bod za dostatecny tedy dava smysl jen je-li v definici sondy nasledovan dalsim sondaznim bodem. Dale muze byt sondazni bod nasledovan vyrazem podminky "if (expr)". Tim lze sondazni bod za behu aktivovat, ci deaktivovat. Pokud 'expr' je nepravda, sondazni bod je neaktivni. Podminka se pri prekladu predava nize pres prezdivky a expanze az k elementarnim sondaznim bodum prekladace, takze na nejnizsi urovni predstavuje podminka logicky soucin prislusnych podminek na elementarnich sondaznich bodech. Podminka 'expr' muze zakonite byt zalozena jen na globalnich promennych a pri tom nesmi menit jejich hodnotu (napr. i++ neni povoleno). Nasledujici sondazni body jsou syntakticky korektni. (Jejich semantika zavisi na obsahu tapsetu, verzi jadra analyzovaneho systemu atd. Pro Vas system jsou pravdepodobne semanticky nevalidni.) 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 obecne klasifikovat na "synchronni" a "asynchronni". Za synchronni povazujeme sondu (resp. udalost), kdy napr. nektery z procesoru vykonal danou instrukci. Tim je dan referencni bod na zaklade ktereho muze sonda ziskat dalsi kontextove informace. Za asynchronni povazujeme napr. udalost casovace. Asynchronni sonda nema k dispozici kontextove informace. Kazda sonda muze byt definovana na zaklade mnozstvi sondaznich bodu napriklad prostrednictvim zastupnych symbolu, prezdivek, nebo dalsich carkou oddelenych sondaznich bodu. Jakmile kterykoliv z nich detekuje udalost, sonda se aktivuje (probe point is hit) a spusti obsluznou rutinu, coz je blok kodu (probe handler). Zavorkova expanze je usporny zpusob zapisu vetsiho mnozstvi sondaznich bodu, ktere dohromady tvori sondu. Do slozenych zavorek se uvede seznam carkou oddelenych subkomponent a/nebo pripadne dalsich (vnorenych) zavorkovych expanzi. Expanze sondehne v danem poradi. Otaznik (?), vykricnik (!) a podminky (if (expr)) musi byt uvedeny za posledni komponentou sondazniho bodu. Priklad zavorkove 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*")! LADICI INFORMACE FORMATU DWARF Vyhodnoceni nekterych sondaznich bodu vyzaduje relevantni ladici informace formatu (DWARF). Pro nektere sondazni body si umi systemtap zrekonstruovat potrebne ladici informace na zaklade hlavickovych souboru sam. Pro jine sondazni body nejsou ladici informace potreba. Vzhledem k tomu, ze systemtap skript muze obsahovat libovolny mix ruznych typu sond, vysledne pozadavky celeho skriptu na dostupnost ladicich informaci jsou sjednocenim odpovidajicich pozadavku pro jednotlive sondazni body. Ladici informace jsou potrebne v okamziku kdy dochazi k prekladu skriptu. K te nemusi nutne dojit na systemu, kde bude systemtap modul nakonec pouzit. Viz volba --use-server a termin stap-server v manualove strance stap(1)). Nasleduje seznam dostupnych rodin sondaznich bodu rozdeleny podle jejich naroku na dostupnost ladicich informaci: 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 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 oznacene hvezdou *, si dokaze systemtap za urcitych okolnosti vygenerovat cast ladicich informaci z hlavickovych souboru sam. Obecne plati, ze cim vice relevantnich ladicich informaci je k dispozici, tim vyssi bude kvalita analyzy. ODEMYKANI A ZAMYKANI SOND ZA BEHU Nasledujici typy sondaznich bodu lze podle potreby zamknout / odemknout za behu. Tim lze snizit zatizeni systemu. Odemcena sonda je neaktivni, zamcena je aktivni. Odemcena sonda nekonzumuje systemove prostredky. ODEMYKATELNE vyjimky kernel.function, kernel.statement module.function, module.statement process.*.function, process.*.statement process.*.plt, process.*.mark timer. timer.profile java Odemykani lze predepsat i jinym typum sond, ale v jejich pripade nedojde k usporam systemovych prostredku. TYPY SONDAZNICH BODU BEGIN/END/ERROR Sondazni body begin a end jsou definovany prekladacem a odkazuji k okamzikum startu, resp. ukonceni skriptu. Obsluzne rutiny svazane se vsemi 'begin' sondami se v urcitem poradi provedou behem startu systemtap sezeni. Pred tim se inicializuji vsechny globalni promenne. Obsluzne rutiny svazane s 'end' sondami se provedou v danem poradi behem normalniho ukonceni sezeni, jako napriklad po vykonani funkce exit () , nebo pokud sezeni ukonci uzivatel (Ctrl-C). V pripade, kdy sezeni skonci v dusledku chyby, nebudou 'end' sondy aktivni. V kontextu 'end' sond neexistuji zadne cilove promenne. Poradi vykonani jednotlivych "begin" a "end" sond, lze urcit poradovym cislem: begin(N) end(N) Cislo M muze byt kladne i zaporne. Sondy budou aktivni ve vzestupnem poradi svych poradovych cisel. Poradi vykonani sond se stejnym poradovym cislem je nedefinovane. Kde neni poradove cislo explicitne uvedeno, pracuje se efektivne s nulou. Sondazni bod error je podobny sondaznimu bodu end az na to, ze je aktivovan pri ukonceni sezeni v dusledku chyby. V takovych pripadech se 'end' sondy preskoci, ale dojde k pokusu vykonat vsechny 'error' sondy. Tento typ sond lze vyuzit k zaverecnemu uklidu. Take 'error' sondam lze nastavit poradi vykonani. NEVER Sondazni bod never je specialne definovany prekladacem a znamena "nikdy". Obsluzna rutina spojena s touto sondou se nikdy nevykona, nicmene jeji prikazy projdou analyzou prekladace. Tato sonda muze byt uzitecna v kombinaci s volitelnymi (optional) sondami. SYSCALL a ND_SYSCALL Prezdivky syscall.* a nd_syscall.* definuji nekolik set sond. Prilis mnoho pro detailni popis na tomto miste. Zde je obecna forma: syscall.NAME nd_syscall.NAME syscall.NAME.return nd_syscall.NAME.return Pro kazde bezne systemove volani (viz syscalls(2) ) je definovana dvojice sond: Jedna pro vstup a druha pro opusteni systemoveho volani. Systemova volani, ktera nikdy neskonci, nemaji odpovidajici .return sondu. Rodina 'nd_*' sond je velmi podobna s tim rozdilem, ze pouziva non-DWARF pristup, tedy nevyzaduje ke sve cinnosti ladici informace. Mohou byt uzitecne zejmena neni-li k dispozici RPM balicek kernel-debuginfo s ladicimi informacemi jadra. Prezdivky obvykle poskytuji radu promennych, se kterymi lze v ramci obsluzne rutiny sondy pracovat. Jejich kompletni seznam je obsazen v tapset skriptech. Tam je vhodne nahlednout. Napriklad syscall.open poskytuje nasledujici promenne: filename, flags, a mode. Krome nich jsou v kazdem 'syscall.*' sondaznim bodu dostupne standardni promenne jako: argstr Retezec obsahujici hodnoty vsech argumentu. name Jmeno systemoveho volani. retstr Retezec obsahujici navratovou hodnotu systemoveho volani (dostupny v sondach pro vystup ze systemoveho volani). Tyto promenne jsou inicializovany v urcitem okamziku pri vstupu / vystupu do / ze systemoveho volani na zaklade kontextovych promennych a tudiz nereflektuji eventualni pozdejsi zmeny techto kontextovych promennych. CASOVACE Existuji dva hlavni typy 'timer' sond: Jsou to sondy 'jiffies', a sondy pro casove intervaly. Casove intervaly jsou v terminologii linuxoveho jadra definovany v jednotkach "jiffies" (odpovidajici priblizne 1 az 60 ms). Casovac aktivuje asynchronni sondy 'timer'. Prekladac podporuje dve varianty techto sond: timer.jiffies(N) timer.jiffies(N).randomize(M) Sonda je aktivovana kazdych N jiffies. Pokud je dana komponenta 'randomize', je k hodnote N pricteno nahodne cislo v rozmezi -M .. +M. Pri tom N musi nabyvat rozumnych hodnot, tj. priblizne z intervalu 1 .. 1e+6, a soucasne M < N. Casovace neposkytuji zadne kontextove promenne. Na multiprocesorovych systemech mohou tyto sondy bezet soucasne. Casove intervaly mohou byt pripadne vyjadreny i v jinych jednotkach. Priklad: timer.ms(N) timer.ms(N).randomize(M) V tomto pripade jsou M a N vyjadreny v milisekundach. Analogicky je mozno cas vyjadrovat v sekundach (s/sec), milisekundach (ms/msec), mikrosekundach (us/usec), nanosekundach (ns/nsec), a v hertzich (Hz). Randomizace neni podporovana je-li cas vyjadren v jednotkach Hz. Skutecna presnost casovacu zavisi na konkretnim jadru. U jader starsich nez 2.6.17 byla nejmensi jednotka casu jiffie, takze zadane casove intervaly se zaokrouhlily na cely pocet jiffies. U novejsich jader jsou casovace zalozeny na tzv. 'hrtimers' pro vyssi presnost. Ovsem skutecna presnost zavisi na architekture. V kazdem pripade, pokud je dana komponenta 'randomize', pak nahodna slozka bude pridana pred pripadnym zaokrouhlovanim. Existuji take profilovaci casovace, ktere tikaji na vsech CPU frekvenci CONFIG_HZ. Na nekterych systemech muze tento casovac pouzivat jen jediny uzivatel, na jinych systemech muze byt tento casovac nedostupny (EBUSY behem registrace sondy). timer.profile.tick timer.profile.freq.hz(N) Pri pouziti tohoto casovace je k dispozici plny kontext preruseneho procesu, takze tento casovac je vhodny pro sbirani profilovacich vzorku. Doporucujeme pouzivat timer.profile namisto timer.profile.tick. Obe sondy se chovaji podobne, pokud je dostupna potrebna funkcionalita jadra. Ale timer.profile umi na novejsich jadrech transparentne vyuzit perf.sw.cpu_clock. Je tedy obecnejsi. Profilovaci casovace s urcenou frekvenci jsou presne jen priblizne do 100 Hz. Poznamenejme, ze pokud je frekvence 'timer' sondy prilis vysoke, a telo sondy prilis slozite, mohou byt nektere aktivace dane sondy preskoceny, nebot jejich cas jiz uplynul. Normalne systemtap hlasi preskocene sondy, ovsem takto preskocene 'timer' sondy hlaseny nebudou. LADICI INFORMACE (DWARF) Tato rodina sondaznich bodu pouziva symbolicke ladici informace k analyze jadra / modulu / programu. Ladici informace mohou byt budto primou soucasti zkoumaneho ELF objektu (unstripped), nebo samostatne stojici (stripped) napr. v ramci debuginfo RPM balicku. Umoznuji umistit sondy do exekucni cesty programu prostrednictvim symbolicke specifikace umisteni ve zdrojovem, nebo objektovem kodu. Jakmile se odpovidajici prikaz na nektere CPU vykona, spusti se obsluzny kod sondy v danem kontextu. Existuje nekolik druhu DWARF sond zalozenych na ladicich informacich. Mohou byt specificke pro jadro, jaderny modul, ci uzivatelsky proces. Mohou se odkazovat na zdrojovy soubor, na konkretni radku nebo funkci v nem, anebo na nejakou kombinaci uvedeneho. Zde je seznam konkretne podporovanych 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 ANALYZA UZIVATELSKYCH PROCESU nize) Ve vyse uvedenych sondach lze pouzivat nasledujici modifikatory / filtry, ktere prinaseji dodatecnou funkcionalitu: .function Umisti sondu pobliz zacatku uvedene funkce, takze funkcni parametry jsou dostupne jako kontextove promenne. .return Umisti sondu hned za bod navratu z dane funkce, takze navratova hodnota funkce je dostupna jako kontextova promenna "$return". .inline Filtr propoustejici jen 'inline' funkce. Poznamenejme, ze 'inline' funkce nemaji identifikovatelny bod navratu, takze .return na .inline funkcich nelze pouzit. .call Filtr propoustejici jen funkce, ktere nejsou 'inline' (opak .inline). .exported Filtr propoustejici jen exportovane funkce. .statement Vlozi sondu na konkretni misto a zpristupni lokalni promenne ktere jsou v danem kontextu viditelne. .statement.nearest Vlozi sondu na misto nejblizsi danemu cislu radku (pro kazde cislo radku predane jako parametr 'statement') .callee Vlozi sondu do volane funkce .callee, ktera je volana funkci .function. Oproti primemu umisteni sondy do funkce .callee ma tento zpusob vyhodu v tom, ze sonda bude aktivni jen kdyz volana funkce .callee bude volana z dane funkce .function. Toto chovani lze potlacit direktivou -DSTAP_CALLEE_MATCHALL, viz stap(1)). Poznamenejme, ze mechanizmus 'callee' lze pouzit jen na staticky dohledatelne funkce. Mechanizmus 'callee' nelze pouzit napriklad na funkce volane prostrednictvim ukazatele, nebo na funkce z DSO knihoven. Dalsi podminkou je, aby kod byl prekladan GCC 4.7+. .callees Zkratka pro .callee("*"). Vlozi sondu do vsech funkci volanych zadanou funkci. .callees(DEPTH) Rekurzivne umisti sondy do volanych funkci az do hloubky DEPTH. Napriklad .callees(2) vlozi sondu nejen do volanych funkci, ale i do jimi volanych funkci. Sonda v hloubce N bude aktivni jen kdyz vsechny volajici funkce budou staticky dohledatelne. Toto chovani lze potlacit direktivou -DSTAP_CALLEE_MATCHALL, viz stap(1)). Ve vyse uvedenem seznamu sondaznich bodu zastupuje MPATTERN retezcovy literal, ktery urcuje zkoumany jaderny modul. Pokud se modul nachazi v obvyklem umisteni (in-tree), staci jej urcit jmenem (napr. "btrfs"). Jmeno muze obsahovat zastupne symboly, jako napr. "*", "[]", a "?". Pokud se modul nachazi v neobvyklem umisteni (out-of-tree), je potreba pouzit absolutni cestu. V tomto pripade nejsou zastupne symboly pripustne. Jmeno souboru musi vyhovovat konvencnimu schematu .ko (znaky ',' a '-' se nahradi '_'). LPATTERN je retezcovy literal, ktery odkazuje k umisteni ve zdrojovem kodu. Muze obsahovat zastupne symboly "*", "[]" a "?". Sklada se ze tri casti: o Prvni cast je jmeno funkce, tak, jak je zobrazi program nm . V teto casti lze pouzit zastupne symboly "*" a "?" k zadani vice jmen. o Druha cast je volitelna a zacina znakem "@". Nasleduje cesta ke zdrojovemu souboru, ktery danou funkci obsahuje. Cesta muze obsahovat zastupne znaky jako napr 'mm/slab*'. Pokud zadanemu zastupnemu symbolu nic nevyhovuje, prida prekladac implicitne "*/" pred dany zastupny symbol, takze v praxi staci vyjmenovat nekolik poslednich komponent cesty ke zdrojovemu souboru. o Nakonec treti cast je volitelna a urcuje cislo radku ve zdrojovem kodu. Cislu radku predchazi jeden ze znaku ":", nebo "+". Predpoklada se, ze cislo radku je absolutni pokud mu predchazi ":", nebo relativni vzhledem k deklaraci funkce, pokud mu predchazi "+". Vsechny radky funkce lze vyjadrit jako ":*", rozsah radku od x do y pouzitim ":x-y". Rozsahy a konkretni radky lze kombinovat, napr. ":x,y-z". Jako PATTERN lze zadat pametovou adresu. Je to ciselna konstanta odpovidajici adrese v tabulce symbolu objektoveho souboru jadra, nebo jaderneho modulu. Takova adresa bude overena proti znamym limitum a za behu relokovana. V guru rezimu lze zadat absolutni adresu jadra pomoci ".absolute". Takova adresa se povazuje za jiz relokovanou jako jsou adresy v /proc/kallsyms, a nelze ji validovat. KONTEXTOVE PROMENNE Mnohe z kontextovych promennych, jako jsou parametry funkci, lokalni promenne, globalni promenne viditelne v kompilacni jednotce, muzou byt viditelne v obsluznych rutinach sond. Jejich jmena maji prefix "$". Pomoci specialni syntaxe je mozne do jiste miry dereferencovat ukazatele a prochazet tak strukturami struktur a poli. Pekny formatovany vypis (pretty-printing) promennych a jejich skupin je take mozny. Viz @cast. Poznamenejme, ze promenne mohou byt nedostupne kvuli strankovani pameti, nebo i z jinych duvodu. Viz tez manualovou stranku error::fault(7stap). $var se odkazuje k promenne "var". Pokud jde o nejaky celociselny typ, bude pretypovan na typ 64-bit int pro pouziti v systemtap skriptech. Ukazatele na retezce (char *), mohou byt zkopirovany do retezcovych promennych pomoci funkci kernel_string nebo user_string. @var("varname") je alternativni syntaxe pro $varname. @var("varname@src/file.c") se odkazuje ke globalni (jak 'file local', tak 'external') promenne varname definovane v souboru src/file.c. Za relevantni kompilacni jednotku se povazuje ta, ktera ma odpovidajici jmeno souboru a pri tom nejkratsi cestu. Napr. mame-li @var("foo@bar/baz.c") a kompilacni jednotky src/sub/module/bar/baz.c a src/bar/baz.c, pak druha z kompilacnich jednotek bude povazovana za relevantni pro promennou foo. Syntaxe $var->field slouzi k prochazeni strukturou ukazatelu. Tento obecny dereferencni operator lze opakovat a prochazet tak vice urovnemi zanoreni. Poznamenejme, ze operator . se nepouziva pro odkaz na clena struktury. Jak pro odkaz na clena struktury, tak pro dereferenci ukazatele se pouziva symbol -> nebot operator "." je vyhrazen pro spojeni retezcu. Poznamenejme, ze pro prime dereferencovani ukazatele se doporucuje pouzit funkci {kernel,user}_{char,int,...}($p). Vice v sekci stapfuncs(5). $return je pristupny jen v .return sondach funkci, ktere maji deklarovanou navratovou hodnotu. To lze detekovat pomoci @defined($return). $var[N] slouzi k odkazu do pole podle daneho indexu (ciselny literal, nebo ciselny vyraz). Pro kontextove promenne existuje rada operatoru: $$vars se expanduje na znakovy retezec nasledujiciho formatu: sprintf("parm1=%x ... parmN=%x var1=%x ... varN=%x", parm1, ..., parmN, var1, ..., varN) pro kazdou promennou v rozsahu (scope) sondazniho bodu. Nektere promenne mohou mit hodnotu oznacenou jako =? v pripade, ze nebyly uspesne lokalizovany v pametovem prostoru. $$locals se expanduje na podmnozinu $$vars pouze pro lokalni promenne. $$parms se expanduje na podmnozinu $$vars pouze pro funkcni parametry. $$return je dostupny jen v .return sondach. Expanduje se na retezec, ktery je ekvivalentni sprintf("return=%x", $return) pokud zkoumana funkce ma navratovou hodnotu (jinak bude roven prazdnemu retezci) & $EXPR expanduje se na adresu dane kontextove promenne (pokud je adresovatelna). @defined($EXPR) Expanduje se na 1 nebo 0, pokud je dana kontextova promenna nalezitelna. Pouzit lze v podminkach jako napr.: @defined($foo->bar) ? $foo->bar : 0 $EXPR$ Se expanduje na retezec se vsemi cleny $EXPR. Format: sprintf("{.a=%i, .b=%u, .c={...}, .d=[...]}", $EXPR->a, $EXPR->b) $EXPR$$ Se expanduje na retezec se vsemi cleny $EXPR vcetne vnorenych clenu. Format: 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]) NAVRATOVE SONDY (RETURN PROBES) V jadernych 'return' sondach muze byt zpracovan jen relativne maly pocet navratu ".return" z funkce. Vychozi pocet je male cislo, priblizne jen nekolikanasobek poctu fyzickych CPU. Pokud danou funkci vola soucasne vice vlaken (jako napr. futex(), nebo read()), muze byt tento limit snadno prekrocen. V tom pripade bude "stap -t" hlasit preskocene sondy 'kretprobe'. Obejit tento problem je mozno pouzitim pripony probe FOO.return.maxactive(NNN) s dostatecne velkym NNN. Pripadne lze na prikazove radce zadat stap -DKRETACTIVE=NNNN cimz se tento problem obejde pro vsechny ".return" sondy ve skriptu. Pro pohodli uzivatele jsou v ".return" sondach pristupne i jine kontextove promenne, nez jen $return. Jde zejmena o parametry volani funkce. V tomto pripade ale jde o kopie (snapshot) vytvorene v momente vstupu do funkce. (Lokalni promenne funkce obecne nejsou dostupne, nebot ty v dobe vytvareni "snapshotu" neexistovaly.) Vhodnym zpusobem pristupu k temto promennym je @entry($var). Pri vstupu do funkce je mozno ulozit pomocne hodnoty pro pozdejsi vyuziti v @entry(expr). Napriklad tak lze zmerit dobu behu funkce: probe kernel.function("do_filp_open").return { println( get_timeofday_us() - @entry(get_timeofday_us()) ) } Nasledujici tabulka ukazuje, jak lze pristoupit ke kontextovym promennym funkcnich hodnot. Ukazatel s nazvem addr je pouzitelny v .return sonde. vstupni hodnota hodnota po vystupu z funkce $addr not available $addr->x->y @cast(@entry($addr),"struct zz")->x->y $addr[0] {kernel,user}_{char,int,...}(& $addr[0]) SONDY NEZAVISLE NA LADICICH INFORMACICH (DWARFLESS PROBES) V pripadech, kdy ladici informace nejsou k dispozici, lze do mist volani a vystupu do/z funkci vkladat sondy z rodiny 'kprobe'. Ty ovsem neumoznuji vyhledavani lokalnich promennych a/nebo parametru funkci. Podporovany jsou nasledujici 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 jaderne funkce doporucujeme pouzit sondy typu function zatimco pro analyzu modulu jsou vhodne sondy module V pripadech, kdy je znama absolutni adresa v jadre, nebo v modulu, lze pouzit sondy typu statement. Poznamenejme, ze FUNCTION a MODULE nesmi obsahovat zastupne symboly, jinak sonda nebude zaregistrovana. Dale pozn., ze ".statement" funguje jen v guru rezimu. UZIVATELSKE PROCESY (USER-SPACE) Analyza uzivatelskych procesu je dostupna nad jadry, ktera jsou konfigurovana s 'utrace', nebo 'uprobes' (3.5+) rozsirenimi (jde o sirokou sadu konfiguracnich voleb, ktere musi byt zapnuty, systemtap bude jejich nedostupnost ohlasovat). Existuje nekolik syntaktickych podob sond pro uzivatelske procesy. Prvni forma: process(PID).statement(ADDRESS).absolute je analogicka kernel.statement(ADDRESS).absolute v tom, ze obe pouzivaji syrove (raw), tj. neverifikovane adresy a nezpristupnuji kontextove promenne. Musi byt zadan PID beziciho procesu a dana adresa ADDRESS by mela identifikovat validni adresu instrukce. Analyzovana budou vsechna vlakna. Druha forma slouzi k analyzovani nesymbolickych udalosti obsluhovanych 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 aktivovana pri vytvoreni noveho procesu daneho PID, nebo FULLPATH. Navic je tato sonda volana jedenkrat z kontextu kazdeho procesu, ktery za behu systemtap skriptu vznikne. To je uzitecne pro udrzovani seznamu bezicich procesu. process.thread.begin sonda je aktivovana pri vytvoreni noveho vlakna daneho PID, nebo FULLPATH. process.end sonda je aktivovana pri ukonceni procesu daneho PID, nebo FULLPATH. process.thread.end sonda je aktivovana pri ukonceni vlakna daneho PID, nebo FULLPATH. process.syscall sonda je aktivovana kdyz vlakno daneho PID nebo FULLPATH zavola systemove volani. Cislo systemoveho volani je pristupne v kontextove promenne $syscall a prvnich 6 funkcnich argumentu v kontextovych promennych $argN (ex. $arg1, $arg2, ...). Sonda process.syscall.return sonda je aktivovana kdyz se vlakno daneho PID nebo FULLPATH vraci ze systemoveho volani. Cislo systemoveho volani je pristupne v kontextove promenne $syscall a navratova hodnota systemoveho volani pak v ramci kontextove promenne $return. Sonda Pokud je sonda specifikovana bez PID, nebo FULLPATH, budou analyzovana vlakna vsech uzivatelskych procesu. Ovsem pokud byl stap volan s prepinacem -c nebo -x, pak bude bran v potaz pouze dany proces a jeho potomci. Pokud chybi jak specifikace PID, tak specifikace FULLPATH, ale je dan prepinac -c , bude cesta k programu doplnena na zaklade heuristiky. V tom pripade jsou v ramci argumentu -c pripustne jen prikazy (tj. pripustne nejsou zejmena napr. substituce a nesmi se ani vyskytnout znaky '|&;<>(){}').). Treti typ: Je zalozen na staticke instrumentaci, ktera je jiz zakompilovana do programu 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 aktivovana, jakmile vykonavani programu dosahne mista, kde je zaprekladana specialni znacka pomoci makra STAP_PROBE1(PROVIDER,LABEL,arg1). Toto makro je definovano v sys/sdt.h. PROVIDER je volitelny identifikator aplikace, LABEL identifikator znacky, a arg1 je celociselny argument. Pro sondy s jednim argumentem se pouzije makro STAP_PROBE1, pro sondy se dvema argumenty makro STAP_PROBE2 a tak dale. Promenne arg1, arg2, ... argN jsou pak dostupne v kontextu sondy. Alternativou k pouziti makra STAP_PROBE je pouzit dtrace skript k vytvoreni uzivatelskych maker. V kontextu sondy jsou tez dostupne promenne $$name a $$provider. V sys/sdt.h se definuje makro DTRACE_PROBE* jako prezdivka pro STAP_PROBE*. Posledni typ: V uzivatelskych programech jsou dostupne vsechny varianty DWARF sond. Jsou analogicke k jadernym DWARF sondam, nebo DWARF sondam pro jaderne moduly popsanym vyse. Poskytuji pristup ke kontextovym promennym pro parametry funkci, lokalni promenne 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, ze pro vsechny sondy pro uzivatelske procesy plati, ze PATH se odkazuje k spustitelnemu souboru, jehoz absolutni umisteni se dohledava podobne jako to delaji shelly, tj. relativne k aktualnimu adresari pokud obsahuji lomitko "/", jinak v $PATH. Pokud se PATH odkazuje na skript, bude predmetem analyzy prislusny interpreter tak, jak je definovan v prvnim radku skriptu za sekvenci #! (shebang). Pokud je PATH parametrem komponenty '.process' a odkazuje se na sdilenou DSO knihovnu, pak analyzovany budou vsechny procesy, ktere tuto knihovnu vyuzivaji. Pokud je PATH parametrem komponenty '.library', pak analyzovan bude pouze dany proces. Poznamenejme, ze PATH v ramci komponenty '.library' se vzdy vztahuje na knihovny, ktere lze z daneho spustitelneho souboru zjistit staticky. Nicmene vzdy je mozne uvest absolutni cestu k libovolne knihovne explicitne. Sonda .plt bude umistens do 'program linkage' tabulky odpovidajici zbytku definice sondazniho bodu. Pri tom .plt je zkratkou pro .plt("*"). Jmeno symbolu je dostupne v kontextove promenne $$name, parametry funkci dostupne nejsou, protoze PLT sondy se zpracovavaji bez ladicich informaci. Sonda funkce. Retezec PATH muze obsahovat zastupne symboly, jako tomu bylo v pripade MPATTERN. V tomto pripade nebude bran zretel na promennou $PATH. Pokud je systemtap vyvolan s jednim z prepinacu -c nebo -x pak bude analyza omezena na cilovy proces a jeho potomky. JAVA Podpora pro instrumentaci java metod je zalozena na nastroji Byteman, coz je software slouzici k instrumentaci javy vyvijeny v ramci JBoss projektu. Systemtap tak muze detekovat vykonani java metody, nebo vykonani daneho radku java programu. Instrumentace javy je zalozena na generovani byteman skriptu a naslednem volani bminstall. V soucasnosti je instrumentace javy prototypem s vyznamnymi omezenimi: Instrumentace javy nefunguje napric uzivateli. Systemtap skript musi byt spusten stejnym uzivatelem, jako instrumentovany proces. Tedy zejmena, a to je ne neobvykle, systemtap skript spusteny rootem nemuze analyzovat java program jineho uzivatele. Prvni typ java sond se odkazuje k java procesum jmenem: java("PNAME").class("CLASSNAME").method("PATTERN") java("PNAME").class("CLASSNAME").method("PATTERN").return Argument PNAME musi byt jiz existujici jvm PID a musi byt viditelny ve vypisu programu jps. Parametr PATTERN urcuje signaturu java metody, ktera se ma instrumentovat. Signatura musi sestavat z presneho jmena java metody nasledovaneho uzavorkovanym seznamem typu argumentu. Priklad: "myMethod(int,double,Foo)". Zastupne znaky se zde nepodporuji. Sondu lze vlozit na konkretni radek pripojenim dvojtecky a cisla radku jako obvykle. Priklad: "myMethod(int,double,Foo):245". Parametr CLASSNAME identifikuje Java tridu, ke ktere metoda nalezi, a to jak s, tak bez uvedeni nazvu balicku (package). Za normalnich okolnosti bude sonda aktivni take na potomcich dane tridy, kteri ponechavaji danou metodu nepredefinovanou. Nicmene, CLASSNAME prijima volitelny prefix "^" jako napr: ^org.my.MyClass, ktery znaci, ze sonda by mela byt tez aktivni na vsech potomcich dane tridy, vcetne tech, kteri danou metodu predefinovali. Napriklad vsechny metody foo(int) v programu org.my.MyApp mohou byt instrumentovany takto: java("org.my.MyApp").class("^java.lang.Object").method("foo(int)") Druhy typ sond funguje analogicky, ovsem odkazuje se k java procesu prostrednictvim PID: java(PID).class("CLASSNAME").method("PATTERN") java(PID).class("CLASSNAME").method("PATTERN").return (PID jiz beziciho procesu lze ziskat pomoci jps(1). ) Kontextove promenne definovane v java sondach zahrnuji $arg1 az $arg10 (pro az 10 prvnich parametru metody), jakozto ukazatele na retezce, ktere lze podle potreby predhodit ke zpracovani funkci toString(). Promenne arg1 az arg10 zpristupnuji zminene argumenty metody primo jakozto retezce ziskane prostrednictvim user_string_warn(). Ve starsich verzich systemtapu (3.1 a nize) obsahovaly $arg1 az $arg10 budto cela cisla, nebo ukazatele na retezce, v zavislosti na typu odpovidajicich objektu. Toto historicke chovani lze pouzit v rezimu stap --compatible=3.0 . PROCFS Nasledujici sondy umoznuji vytvaret / cist "soubory" v /proc/systemtap/MODNAME. Pri tom je mozne definovat umask. vychozi hodnoty jsou 0400 pro cteci sondy a 0200 pro zapisovaci sondy. Pokud jsou na jednom souboru pouzivany sondy jak pro cteni, tak pro zapis, pak vychozi opravneni bude 0600. Sonda procfs.umask(0040).read zpusobi nastaveni opravneni 0404 na souboru. (MODNAME je jmeno systemtap modulu). Souborovy (pseudo-) system proc se pouziva jako uzivatelske rozhrani pro datove struktury jadra. Prekladac podporuje nekolik 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 relativni vzhledem k /proc/systemtap/MODNAME Pokud neni PATH urceno (tak jako u poslednich dvou variant vyse), pak PATH nabyva vychozi hodnoty "command". Nazev souboru "__stdin" se vnitrne pouziva v "input" sondach a nemel by se pouzivat v roli PATH procfs sond; viz sekce INPUT nize. Kdyz uzivatel cte /proc/systemtap/MODNAME/PATH, aktivuje se procfs read proba. Retezcova data ke cteni se priradi promenne $value. Priklad: procfs("PATH").read { $value = "100\n" } Kdyz uzivatel zapisuje do /proc/systemtap/MODNAME/PATH, aktivuje se odpovidajici write sonda. Data zapsana uzivatelem jsou pak dostupna v promenne $value. Priklad: procfs("PATH").write { printf("user wrote: %s", $value) } MAXSIZE Maximalni velikost procfs cteciho bufferu a procfs vystupu. Pokud MAXSIZE neni nastavena, velikost cteciho bufferu se polozi rovna STP_PROCFS_BUFSIZE (s vychozi hodnotou MAXSTRINGLEN, tj. maximalni delka retezce). V pripade, kdy je treba nastavit velikost ctecich bufferu pro vice nez jeden procfs soubor, muze pomoci STP_PROCFS_BUFSIZE . Zde je priklad pouziti MAXSIZE: procfs.read.maxsize(1024) { $value = "dlouhy retezec..." $value .= "jiny dlouhy retezec..." $value .= "jiny dlouhy retezec..." $value .= "jiny dlouhy retezec..." } INPUT Tyto sondy zpristupnuji standardni vstup skriptu v dobe jeho behu. Prekladac podporuje dve varianty teto rodiny sond: input.char input.line input.char se aktivuje po kazdem precteni znaku ze standardniho vstupu. Dotycny znak je pak dostupny prostrednictvim promenne char. Nehraje zde roli zadna vyrovnavaci pamet. input.line Znaky nactene ze standardniho vstupu se ukladaji do vyrovnavaci pameti az do okamziku nacteni znaku noveho radku. Po nacteni celeho radku se tento vcetne ukoncovaciho znaku stane dostupnym prostrednictvim promenne line. Pri tom maximalni delka radku je MAXSTRINGLEN. Znaky presahujici MAXSTRINGLEN se do line nedostanou. Tyto input sondy jsou ve skutecnosti prezdivkami pro procfs("__stdin").write. Pokud uzivatelsky skript obsahuje procfs sondu, nemel by vyuzivat "__stdin" jako argument "procfs" sond. Sondy "input" nefunguji pri pouziti -F a --remote voleb. SONDY 'NETFILTER HOOKS' Sondy 'netfilter hooks', (dale jen netfilter sondy) umozni sledovani sitovych paketu pomoci jaderneho mechanizmu 'netfilter'. Netfilter sonda odpovida funkci 'netfilter hook' s vyuzitim originalniho API. Pravdepodobne pohodlnejsi, nez pouzivani "syrovych" sondaznich bodu prekladace, je pouzit prislusne tapset funkce tapset::netfilter(3stap), ktere poskytuji praktickou obalku. Prekladac podporuje nekolik 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 protokolu ktere maji byt vyuzity k poslouchani. V soucasnosti jsou k dispozici nasledujici moznosti: NFPROTO_IPV4, NFPROTO_IPV6, NFPROTO_ARP, nebo NFPROTO_BRIDGE. HOOKNAME je bod ('hook') v ramci daneho protokolu, ve kterem se zachyti paket. Seznam dostupnych typu prislusnych sondaznich bodu nalezne ctenar v hlavickovych souborech , , a . Napriklad pouzitelne sondazni 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 celociselna priorita urcujici poradi aktivace netfilter sond vzhledem k ostatnim 'netfilter hook' funkcim pro dany paket. Na danem paketu se nejdrive vykonaji 'hetfilter hook' funkce s nejnizsi prioritou, pote funkce s vyssi prioritou. Pokud PRIORITY neni specifikovana (jako je tomu v prvnich dvou prikladech vyse), bude efektivne PRIORITY rovna nule. Existuje rada pojmenovanych priorit tvaru NF_IP_PRI_* a NF_IP6_PRI_* , ktere jsou definovany v hlavickovych souborech jadra a . Tato makra mohou byt pouzita v systemtap skriptech. Vyjimkou jsou sondazni body pro NFPROTO_ARP a NFPROTO_BRIDGE pro ktere momentalne neexistuji pojmenovane priority. Prijatelne zpusoby nastaveni priorit: priority("255") priority("NF_IP_PRI_SELINUX_LAST") Skript v guru rezimu muze urcit libovolny identifikator nebo cislo jako parametr 'hook', 'pf' a 'priority', coz je vhodne pouzivat opatrne, nebot parametr se vklada do vygenerovaneho C kodu doslovne. V ramci netfilter sond existuji nasledujici kontextove promenne: $hooknum Cislo identifikujici 'netfilter hook'. $skb adresa struktury sk_buff, ktera reprezentuje paket. Viz hlavickovy soubor a manualovou stranku tapset::netfilter(3stap) pro podrobnejsi informace. $in Adresa struktury net_device, ktera reprezentuje sitove zarizeni ze ktereho paket prisel. Muze byt 0 pokud zarizeni neni znamo nebo definovano. $out Adresa struktury net_device reprezentujici sitove zarizeni na ktere ma byt paket odeslan. Muze byt 0 pokud zarizeni neni znamo nebo definovano. $verdict Je dostupny jen v guru rezimu. Nastavenim teto hodnoty (viz ) se rozhodne o dalsim zpusobu zpracovani paketu v paketovem filtru. Napriklad nasledujici guru skript zpusobi zahazovani vsech IPv6 paketu: probe netfilter.pf("NFPROTO_IPV6").hook("NF_IP6_PRE_ROUTING") { $verdict = 0 /* nf_drop */ } Pro pohodli uzivatele poskytuji netfilter sondy definovane v tapset::netfilter(3stap) hodnoty pro promennou 'verdict' jako lokalni promenne. Napriklad promenna 'nf_drop' obsahuje hodnotu NF_DROP. SONDAZNI BODY TYPU 'TRACEPOINT' Tato rodina sondaznich bodu je zalozena na staticky zakompilovanych znackach typu 'tracepoint' (dale jen tracepoint body) vlozenych do jadra, nebo jaderneho modulu. Systemtap umi tyto znacky detekovat pomoci sondaznich bodu typu 'tracepoint', dale jen 'tracepoint sondy'. Tracepoint sondy jsou spolehlivejsi, nez sondy zalozene na DWARF ladicich informacich. Pro funkcnost tracepoint sond neni nutna pritomnost ladicich informaci. Dalsi vyhodou tracepoint sond jsou silneji typovane parametry ve srovnani se znackami (markers). Priklady tracepoint sond: kernel.trace("name"). Retezcovy literal "name" muze obsahovat zastupne symboly. Pro omezeni sondy na konkretni subsystem (napr. sched, ext3, atd...), lze vyuzit nasledujici syntaxe: kernel.trace("subsystem:jmeno"). Obsluzny kod pro tracepoint sondy muze cist volitelne parametry, ktere autori tracepoint bodu pripravili. Napriklad sondazni bod kernel.trace("sched:sched_switch") poskytuje parametry $prev a $next. Pokud je parametrem ukazatel, lze jej dereferencovat pomoci stejne syntaxe jako je tomu u DWARF sond. Hodnoty parametru tracepoint sond nelze modifikovat. V guru rezimu lze ovsem modifikovat promenne dereferencovane pomoci parametru tracepoint sond. Jmeno subsystemu a jmeno tracepoint bodu je pristupne prostrednictvim promennych $$system resp. $$name a retezcova reprezentace paru jmeno=hodnota je pak dostupna prostrednictvim $$vars nebo $$parms. JADERNE ZNACKY (KERNEL MARKERS) (ZASTARALE) Tato rodina sondaznich bodu je postavena na ponekud zastaralem mechanizmu statickych znacek, ktere se vyskytuji ve starsich jadrech a jadernych modulech. Jde o makra STAP_MARK, ktere do jadra vlozili vyvojari aby usnadnili instrumentaci jadra a ucinili ji spolehlivou. Proto DWARF ladici informace nejsou pro tento typ instrumentace potreba. Sondazni bod pro jadernou znacku zacina kernel. dalsi casti je jmeno znacky samotne: mark("name"). Retezec vyjadrujici jmeno znacky muze obsahovat obvykle zastupne symboly a porovnava se proti vyvojarem zavedenemu jmenu znacky. Volitelne lze uvest format: format("format"), cimz se odlisi znacky se stejnym jmenem, ale odlisnym oznacenim pro format. Obsluzny kod pro tento typ sond muze cist parametry, ktere mohou byt v miste znacky dostupne jako: $arg1 az $argNN, Kde NN je pocet parametru podporovanych makrem. Parametry mohou byt retezcoveho a celociselneho typu. Hodnota atributu 'format' znacky je dostupna v promenne $format. Hodnota atributu 'name' v $name. HARDWAROVE BODY ZASTAVENI (HARDWARE BREAKPOINTS) Tato skupina sond slouzi k nastaveni hardwarovych bodu zastaveni pro dany globalni symbol jadra. Prislusne sondy sestavaji ze tri komponent: 1. virtualni adresa" / "jmeno zkoumaneho symbolu jadra se predava jako argument teto tride sond. Podporovany jsou pouze sondy pro promenne v datovem segmentu. Analyzu lokalnich promennych nelze provest. 2. Zpusob pristupu : a. sonda .write se aktivuje, jakmile dojde na zadane adrese / symbolu k zapisu. b. sonda rw se aktivuje, jakmile dojde na zadane adrese / symbolu ke cteni. 3. .length (volitelne) uzivatel ma moznost vymezit rozsah adres pro analyzu pomoci "length". Uzivatelem urcena hodnota se zaokrouhli na nejblizsi hardwarem podporovanou hodnotu. Pokud se hodnota 'length' nezada, polozi ji prekladac rovnu jedne. Pozn., ze 'length' nelze pouzit v kombinaci se symbolickymi jmeny. Podporovany jsou nasledujici syntakticke 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 vyuziva ladici registry procesoru, coz je vzacny zdroj. Architektura x86_64 nabizi ctyri ladici registry, powerpc jen jeden. Pokud se uzivatel pokusi vyuzit vice ladicich registru, nez kolik jich ma k dispozici, preklad skonci chybou ve fazi 2. PERF SONDY Tato skupina sond je rozhranim pro infrastrukturu jadra "perf event", ktera pracuje s hardwarovymi pocitadly (hardware performance counters). Udalost, se kterou se ma proba svazat, se specifikuje pomoci atributu "type" a "config" struktury perf_event_attr. Vzorkovaci frekvence se urci pomoci atributu "sample_period" nebo "sample_freq". Tento typ sond pouziva nasledujici 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") Obsluzna rutina sondy se pri pouziti '.sample' zavola jednou za XX inkrementu daneho pocitadla, nebo, pokud se pouzije .hz, po uplynuti periody dane frekvence. Bez specifikace polozi prekladac XX rovno 1000000. Platny rozsah je specifikovan v popisu systemoveho volani perf_event_open(2) a / nebo v hlavickovem souboru linux/perf_event.h. Neplatne nastaveni skonci chybou prekladu. Kontrola platnosti zadanych hodnot se provadi v ramci jadra. Za normalnich okolnosti je .perf sonda platna pro cely system. Pokud se urci .process, pak jen pro dany uzivatelsky proces. Pokud se vynecha jmeno procesu, pokusi se ho prekladac odvodit z -c. Udalost lze cist pouzitim '.counter'. Obsluzna rutina perf sondy se pro .counter nezavola, ale pocitadlo lze cist pomoci nasledujici syntaxe: process("PROC").statement("func@file") {stat <<< @perf("NAME")} PYTHON S pouzitim specialniho python modulu je mozne analyzovat python 2 a python 3 funkce. K tomu je potreba mit nainstalovane ladici informace pro prislusny python. Zmineny modul lze pouzit takto: stap foo.stp -c "python -m HelperSDT foo.py" Prislusne sondy potom vypadaji 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 Vyse zminena ukazka obsahuje nasledujici modifikatory: .function Umisti sondu na zacatek funkce urcene jmenem, pokud neni prostrednictvim PATTERN urceno jinak. Funkcni parametry jsou dostupne jako kontextove promenne. .call Umisti sondu na zacatek funkce urcene jmenem. Funkcni parametry jsou dostupne jako kontextove promenne. .return Umisti sondu tesne pred navrat z funkce urcene jmenem. Parametry funkce, jakoz i lokalni, ci globalni promenne jsou dostupne prostrednictvim kontextovych promennych. PATTERN predstavuje retezcovy literal, ktery urcuje pozici v python programu. Sklada se ze tri casti: o Prvni casti je jmeno funkce (napriklad "foo"), nebo metody (napriklad "bar.baz"). V teto casti lze pouzivat take zastupne symboly "*" a "?". o Druha cast je volitelna a zacina znakem "@". Za ni nasleduje cesta k souboru, ktery obsahuje danou funkci/metodu. Zde lze taktez pouzit zastupne symboly "*" a "?". Pro vyhledavani ze vezme v potaz "python path". o Posledni, treti volitelnou casti, je speecifikace cisla radku ve zdrojovem souboru. Cislo radku se zapisuje za dvojtecku ":", nebo plus "+". V pripade dvojtecky se cislo radku interpretuje jako absolutni cislo radku, v pripade plusu jako relativni vzhledem k deklaraci funkce. Vsechny radky dane funkce lze oznacit zapisem ":*". Rozsah radku se zapise jako ":x-y", ci ":x,y-z". MPATTERN zastupuje nazev python modulu, nebo skriptu, ktery se na python modul odkazuje. I zde lze pouzit zastupne znaky "*" a "?". Dany nazev souboru se hleda v ramci "python path". PRIKLADY Zde uvadime nekolik konkretnich prikladu sond. begin, end, end odkazuje se k zacatku a k normalnimu ukonceni sezeni. V tomto pripade se obsluzna rutina provede jednou pri zacatku sezeni, a dvakrat pri jeho normalnim ukonceni. timer.jiffies(1000).randomize(200) sonda se aktivuje periodicky kazdych 1000 +/- 200 jiffies. kernel.function("*init*"), kernel.function("*exit*") odkazuje se ke vsem jadernym funkcim, jejichz jmeno obsahuje podretezec "init", nebo "exit". kernel.function("*@kernel/time.c:240") odkazuje se k libovolne funkci z "kernel/time.c", kde cast jejiho tela lezi na radku 240. Poznamenejme, ze v tomto pripade nejde o sondu vlozenou na dany radek. Pro vlozeni sondy na dany radek pouzijte kernel.statement . kernel.trace("sched_*") odkazuje se ke vsem 'tracepoint' bodum s prefixem "sched_", tj. souvisejicim s casovacem. kernel.mark("getuid") odkazuje se k zastaralemu jadernemu makru STAP_MARK(getuid, ...). module("usb*").function("*sync*").return odkazuje se k bodu navratu ze vsech funkci, ktere obsahuji "sync" ve svem jmene a nachazi se v nekterem z USB modulu. kernel.statement(0xc0044852) odkazuje se k prvnimu bajtu prikazu, jehoz prelozene instrukce lezi na dane adrese v jadre. kernel.statement("*@kernel/time.c:296") odkazuje se k prikazu na radku 290 v souboru "kernel/time.c". kernel.statement("bio_init@fs/bio.c+3") odkazuje se k prikazu na radku bio_init+3 v souboru "fs/bio.c". kernel.data("pid_max").write odkazuje se k hardwarovemu breakpointu typu "write" nastavenemu na pid_max. syscall.*.return odkazuje se ke skupine prezdivek sond s libovolnym jmenem druhe komponenty. VIZ TEZ stap(1), probe::*(3stap), tapset::*(3stap) STAPPROBES(3stap)