Differences

This shows you the differences between two versions of the page.

Link to this comparison view

so2:laboratoare:lab02 [2016/03/02 18:41]
madalina.hristache [Logging]
so2:laboratoare:lab02 [2020/02/20 14:16] (current)
ionel.ghita
Line 15: Line 15:
   * printk, dyndbg   * printk, dyndbg
   * objdump, addr2line, netconsole   * objdump, addr2line, netconsole
-  * KDB, Kprobes, Jprobes, Kretprobes +  * KDB
 ===== Materiale ajutătoare ===== ===== Materiale ajutătoare =====
  
Line 97: Line 96:
 <note important>​ <note important>​
 Pentru laborator și în temele de casă vom configura diferit variabila internă ''​KDIR'',​ în conformitate cu specificațiile [[:​so2:​resurse:​masini-virtuale|mașinii virtuale]]:<​code>​ Pentru laborator și în temele de casă vom configura diferit variabila internă ''​KDIR'',​ în conformitate cu specificațiile [[:​so2:​resurse:​masini-virtuale|mașinii virtuale]]:<​code>​
-KDIR = /usr/src/linux-so2+KDIR = /home/student/so2/linux
 [...] [...]
 </​code>​ </​code>​
Line 120: Line 119:
 Sufixul țintelor din Kbuild determină modul în care sunt folosite, astfel: Sufixul țintelor din Kbuild determină modul în care sunt folosite, astfel:
   *m (module) reprezintă o țintă pentru module de kernel încărcabile   *m (module) reprezintă o țintă pentru module de kernel încărcabile
-  *y (yes) reprezintă o țintă pentru fișiere obiect ce vor fi compilate ca apoi să fie linkate în cadrul unui modul ($(nume_modul)-y) sau în cadrul kernel-ului (obj-y)+  *y (yes) reprezintă o țintă pentru fișiere obiect ce vor fi compilate ca apoi să fie linkate în cadrul unui modul ''​($(nume_modul)-y)'' ​sau în cadrul kernel-ului ​''​(obj-y)''​
   *orice alt sufix de țintă va fi ignorat de Kbuild și nu va fi compilat   *orice alt sufix de țintă va fi ignorat de Kbuild și nu va fi compilat
  
Line 439: Line 438:
 </​code>​ </​code>​
 unde ''​0x5''​ este valoarea contorului program (EIP = ''​c89d4005''​) la care s-a generat kernel oops, minus adresa de bază a modulului (''​0xc89c4000''​),​ conform ''/​proc/​modules''​. unde ''​0x5''​ este valoarea contorului program (EIP = ''​c89d4005''​) la care s-a generat kernel oops, minus adresa de bază a modulului (''​0xc89c4000''​),​ conform ''/​proc/​modules''​.
 +
 +=== minicom ===
 +
 +Minicom (sau alte utilitare echivalente,​ e.g. picocom, screen) este un utilitar ce poate fi folosit pentru a ne connecta și interacționa cu un port serial. Portul serial este metoda de bază pentru a analiza mesajele de kernel sau a interacționa cu un sistem (embedded) în faza de dezvoltare. Sunt două modalități mai comune de conectare: ​
 +* un port serial clasic caz în care device-ul pe care o să îl folosim este /dev/ttyS0
 +* un port USB serial (FDTI) caz în care device-ul pe care o sa îl folosim este /​dev/​ttyUSB)
 +
 +În cazul mașinii virtuale folosite în laborator, device-ul pe care trebuie să îl folosim este afișat după ce mașina virtuala pornește:
 +
 +<​code>​
 +char device redirected to /dev/pts/20 (label virtiocon0)
 +</​code>​
 +
 +Utilizare minicom:
 +
 +<​code>​
 +#pentru conectarea via COM1 și folosirea unei viteze de 115200 caractere pe secundă
 +minicom -b 115200 -D /dev/ttyS0
 +
 +#pentru conectare via port serial USB
 +minicom -D /​dev/​ttyUSB0
 +
 +#pentru conectarea la portul serial al mașinii virtuale
 +minicom -D /​dev/​pts/​20 ​ # numărul variază, inspectați output-ul qemu
 +</​code>​
 +
 +
  
 === netconsole === === netconsole ===
Line 452: Line 478:
 Un exemplu de configurare în momentul inserării este următorul: Un exemplu de configurare în momentul inserării este următorul:
 <​code>​ <​code>​
-alice:~# modprobe netconsole ​+alice:~# modprobe netconsole ​netconsole=6666@192.168.191.130/​eth0,​6000@192.168.191.1/​00:​50:​56:​c0:​00:​08
->  ​6666@192.168.191.130/​eth0,​6000@192.168.191.1/​00:​50:​56:​c0:​00:​08+
 </​code>​ </​code>​
-Astfel, mesajele de debug de pe stația ce are adresa 192.168.191.130 vor fi trimise pe interfața eth0, având ca port sursă 6666. Mesajele vor fi trimise către 192.168.191.1,​ ce are adresa MAC 00:​50:​56:​c0:​00:​08 , pe portul 6000.+Astfel, mesajele de debug de pe stația ce are adresa 192.168.191.130 vor fi trimise pe interfața eth0, având ca port sursă 6666. Mesajele vor fi trimise către 192.168.191.1,​ ce are adresa MAC 00:​50:​56:​c0:​00:​08,​ pe portul 6000.
  
 Mesajele pot fi ascultate pe stația destinație folosind ''​netcat'':​ Mesajele pot fi ascultate pe stația destinație folosind ''​netcat'':​
 <​code>​ <​code>​
-bob:~# nc -l -p 6666 -u+bob:~# nc -l -p 6000 -u
 </​code>​ </​code>​
-Alternativ, stația destinație poate configura ''​syslogd''​ pentru a intercepta aceste mesaje. Mai multe informații puteți găsi [[http://koala.cs.pub.ro/lxr/#linux26/​Documentation/​networking/​netconsole.txt | aici]].+Alternativ, stația destinație poate configura ''​syslogd''​ pentru a intercepta aceste mesaje. Mai multe informații puteți găsi [[https://www.kernel.org/doc/​Documentation/​networking/​netconsole.txt | aici]].
  
 ==== Logging ==== ==== Logging ====
Line 483: Line 508:
   *''​KERN_DEBUG''​ - n = 7   *''​KERN_DEBUG''​ - n = 7
  
-Definițiile tuturor loglevel-urilor se găsesc în [[http://www.cs.fsu.edu/​~baker/​devices/​lxr/​http/source/linux/​include/​linux/​kernel.h|linux/kernel.h]]. Practic, aceste loglevel-uri sunt utilizate de sistem pentru a ruta mesajele trimise către diverse output-uri: consolă, fișiere log din ''/​var/​log''​ etc.+Definițiile tuturor loglevel-urilor se găsesc în [[http://lxr.free-electrons.com/​source/​include/​linux/​kern_levels.h|linux/kern_levels.h]]. Practic, aceste loglevel-uri sunt utilizate de sistem pentru a ruta mesajele trimise către diverse output-uri: consolă, fișiere log din ''/​var/​log''​ etc.
  
 <note important>​ <note important>​
-Pentru a afișa mesajele trimise cu ''​printk''​ în user space, trebuie ca nivelul folosit la apelul ''​printk''​ să fie prioritar valorii variabilei [[http://lxr.free-electrons.com/​source/​include/​linux/​printk.h?v=3.13#L38|console_loglevel]] (( Nivelul implicit setat pe consolă se poate configura din [[http://​koala.cs.pub.ro/​lxr/#​linux26/​Documentation/​sysctl/​kernel.txt#​L261 | /​proc/​sys/​kernel/​printk]];​ spre exemplu, comanda ''​echo 8 > /​proc/​sys/​kernel/​printk''​ va face ca toate mesajele din kernel să fie afișate la consolă )). Adică nivelul de logging să fie mai mic strict decât nivelul variabilei [[http://lxr.free-electrons.com/​source/​include/​linux/​printk.h?v=3.13#L38|console_loglevel]]. De exemplu, dacă variabila ''​console_loglevel''​ are valoarea ''​5''​ (specifică valorii ''​KERN_NOTICE''​) doar mesajele cu loglevel-ul mai mic strict decât ''​5''​ (adică ''​0'',​ ''​1'',​ ''​2'',​ ''​3''​ și ''​4'',​ adică ''​KERN_EMERG'',​ ''​KERN_ALERT'',​ ''​KERN_CRIT'',​ ''​KERN_ERR'',​ ''​KERN_WARNING''​) vor fi afișate (( http://​elinux.org/​Debugging_by_printing )).+Pentru a afișa mesajele trimise cu ''​printk''​ în user space, trebuie ca nivelul folosit la apelul ''​printk''​ să fie prioritar valorii variabilei [[https://elixir.bootlin.com/​linux/​v4.15.7/​source/​include/​linux/​printk.h#​L65|console_loglevel]] (( Nivelul implicit setat pe consolă se poate configura din [[http://​koala.cs.pub.ro/​lxr/#​linux26/​Documentation/​sysctl/​kernel.txt#​L261 | /​proc/​sys/​kernel/​printk]];​ spre exemplu, comanda ''​echo 8 > /​proc/​sys/​kernel/​printk''​ va face ca toate mesajele din kernel să fie afișate la consolă )). Adică nivelul de logging să fie mai mic strict decât nivelul variabilei [[https://elixir.bootlin.com/​linux/​v4.15.7/​source/​include/​linux/​printk.h#​L65|console_loglevel]]. De exemplu, dacă variabila ''​console_loglevel''​ are valoarea ''​5''​ (specifică valorii ''​KERN_NOTICE''​) doar mesajele cu loglevel-ul mai mic strict decât ''​5''​ (adică ''​0'',​ ''​1'',​ ''​2'',​ ''​3''​ și ''​4'',​ adică ''​KERN_EMERG'',​ ''​KERN_ALERT'',​ ''​KERN_CRIT'',​ ''​KERN_ERR'',​ ''​KERN_WARNING''​) vor fi afișate (( http://​elinux.org/​Debugging_by_printing )).
 </​note>​ </​note>​
  
Line 527: Line 552:
 === Dynamic debugging === === Dynamic debugging ===
  
-Depanarea dinamică [[https://​www.kernel.org/​doc/​Documentation/​dynamic-debug-howto.txt | dyndbg]] permite activarea/​dezactivarea în mod dinamic a mesajelor de debug. Spre deosebire de ''​printk'',​ oferă opțiuni mai avansate de filtrare a mesajelor pe care dorim să le afișăm - foarte util în cazul unor module complexe sau pentru depanarea subsistemelor. Astfel, se reduce semnificativ cantitatea de mesaje afișate, rămânând doar cele relevante pentru contextul depanării. Pentru activarea dyndbg, kernelul trebuie compilat cu opțiunea ''​CONFIG_DYNAMIC_DEBUG''​. Odata configurat, apelurile ''​pr_debug()'',​ ''​dev_dbg()''​ și ''​print_hex_dump_debug()'',​ ''​print_hex_dump_bytes()''​ pot fi activate dinamic per callsite.+Depanarea dinamică [[https://​www.kernel.org/​doc/​html/​v4.15/​admin-guide/​dynamic-debug-howto.html | dyndbg]] permite activarea/​dezactivarea în mod dinamic a mesajelor de debug. Spre deosebire de ''​printk'',​ oferă opțiuni mai avansate de filtrare a mesajelor pe care dorim să le afișăm - foarte util în cazul unor module complexe sau pentru depanarea subsistemelor. Astfel, se reduce semnificativ cantitatea de mesaje afișate, rămânând doar cele relevante pentru contextul depanării. Pentru activarea dyndbg, kernelul trebuie compilat cu opțiunea ''​CONFIG_DYNAMIC_DEBUG''​. Odata configurat, apelurile ''​pr_debug()'',​ ''​dev_dbg()''​ și ''​print_hex_dump_debug()'',​ ''​print_hex_dump_bytes()''​ pot fi activate dinamic per callsite.
  
 Pentru filtrarea mesajelor sau vizualizarea filtrelor existente se va folosi fișierul ''/​sys/​kernel/​debug/​dynamic_debug/​control''​ din cadrul sistemului de fișiere ''​debugfs''​ (unde ''/​sys/​kernel/​debug''​ este calea la care a fost montat debugfs). Pentru filtrarea mesajelor sau vizualizarea filtrelor existente se va folosi fișierul ''/​sys/​kernel/​debug/​dynamic_debug/​control''​ din cadrul sistemului de fișiere ''​debugfs''​ (unde ''/​sys/​kernel/​debug''​ este calea la care a fost montat debugfs).
Line 593: Line 618:
  
 În laborator vom folosi o serială legată la gazdă. Comanda de mai jos va activa KDB prin serială: În laborator vom folosi o serială legată la gazdă. Comanda de mai jos va activa KDB prin serială:
-<​code>​ echo ttyS0 > /​sys/​module/​kgdboc/​parameters/​kgdboc </​code>​+<​code>​ echo hvc0 > /​sys/​module/​kgdboc/​parameters/​kgdboc </​code>​
  
 KDB este un "stop mode debugger"​. Astfel, când suntem în debug mode, toate celelalte procese sunt oprite. Pentru a "​forța"​ intrarea în KDB în timpul execuției se poate folosi următoarea comandă [[http://​en.wikipedia.org/​wiki/​Magic_SysRq_key |SysRq]] KDB este un "stop mode debugger"​. Astfel, când suntem în debug mode, toate celelalte procese sunt oprite. Pentru a "​forța"​ intrarea în KDB în timpul execuției se poate folosi următoarea comandă [[http://​en.wikipedia.org/​wiki/​Magic_SysRq_key |SysRq]]
-<​code>​ echo g > /​proc/​sysrq-trigger </​code>​+<​code>​ echo g > /​proc/​sysrq-trigger </​code> ​sau folosind secvența de taste ''​Ctrl+O g''​ dintr-un terminal conectat (de exemplu folosind minicom) la portul serial.
  
 KDB permite numeroase comenzi pentru a controla și defini în detaliu contextul sistemului depanat. KDB permite numeroase comenzi pentru a controla și defini în detaliu contextul sistemului depanat.
Line 607: Line 632:
 # trigger KDB # trigger KDB
 echo g > /​proc/​sysrq-trigger echo g > /​proc/​sysrq-trigger
 +# or if we are connected to the serial port issue 
 +Ctrl-O g
 # breakpoint la accesul de scriere al variabilei mVar # breakpoint la accesul de scriere al variabilei mVar
 kdb> bph mVar dataw kdb> bph mVar dataw
 # revenire din KDB # revenire din KDB
 kdb> go kdb> go
-</​code>​ 
- 
-==== Tracing ==== 
- 
-=== Kprobes === 
- 
-''​Kprobes''​ permite instrumentarea dinamică a oricărei funcții din kernel pentru a colecta informații de debug într-un mod cât mai puțin invaziv. Cu kprobe, putem seta breakpoints la aproape orice adresă din kernel și configura handlere ce vor fi invocate în aceste puncte. Pot fi folosite trei tipuri de probe: ''​Kprobes'',​ ''​Jprobes''​ și ''​Kretprobes''​ (sau probe de return). 
-  - O ''​Kprobe''​ poate fi inserată la orice adresă (instrucțiune) din kernel și putem specifica handlere ce vor fi apelate înainte sau după execuția instrucțiunii. 
-  - ''​Jprobe''​ va fi adăugată la entry-pointul unei funcții, utilă pentru a monitoriza argumentele funcțiilor. 
-  - O probă de return (''​Kretprobe''​) va fi apelată la întoarcerea dintr-o funcție, unde putem analiza rezultatul întors de aceasta. 
- 
-De cele mai multe ori se va realiza instrumentarea cu kprobe prin intermediul unui modul. Funcția module_init va instala una sau mai multe probe care vor fi dezactivate apoi în module_exit. Înregistrarea unei probe (e.x. ''​register_kprobe()''​) presupune specificarea adresei la care aceasta va fi inserată și a unui handler ce va fi apelat când se ajunge la adresa setată. Pentru mai multe detalii despre modul de funcționare ''​Kprobe'',​ ''​Jprobe''​ sau ''​Kretprobe'',​ expandați secțiunea de mai jos. 
- 
-<spoiler onHidden="​Afișați detalii implementare Kprobe"​ onVisible="​Ascundeți detalii implementare Kprobe"​ > 
- 
-**Kprobe** 
- 
-  - La înregistrarea unei probe, ''​Kprobes''​ face o copie a instrucțiunii de la adresa specificată (instrucțiunea pe care dorim să o instrumentăm) și înlocuiește primii bytes cu o instrucțiune de breakpoint (e.g. int3). 
-  - Când procesorul ajunge la instrucțiunea de breakpoint, se execută un trap și controlul revine la ''​Kprobes''​ (printr-un mecanism de tipul [[http://​lwn.net/​Articles/​160953/​ | notifier_call_chain]]). În acest punct, ''​Kprobes''​ va executa pre_handler-ul asociat probei. 
-  - După pre-handler,​ Kprobes execută instrucțiunea instrumentată,​ urmată post_handler-ul asociat. 
-  - Execuția continuă cu următoarea instrucțiune după cea instrumentată. 
- 
-**Jprobe** 
- 
-JProbe este implementat prin inserarea unei kprobe la entry-pointul funcției. Folosește un mecanism de mirroring pentru a permite accesul la argumentele funcției instrumentate. Se așteaptă ca handler-ul înregistrat:​ 
-  * să aibă aceeași semnătură (lista de argumente și return type) ca funcția instrumentată. 
-  * să se termine mereu cu apelarea funcției ''​jprobe_return()''​. 
- 
-Când se ajunge la un breakpoint, ''​Kprobes''​ face o copie a registrelor și a stivei, setând apoi instruction pointerul către handlerul înregistrat. Astfel, handlerul va fi apelat în aceeași stare (registre și stivă) ca funcția instrumentată. La ieșirea din handler, ''​jprobe_return()''​ restaurează conținutul inițial al stivei și al registrelor și continuă execuția cu funcția instrumentată. 
- 
-**Kretprobe** 
- 
-La înregistrarea unei probe de return, ''​Kprobes''​ instalează un kprobe la intrarea în funcția instrumentată. Acest kprobe are rolul de a salva o copie a adresei de return și de a înlocui adresa de return cu adresa unei porțiuni aleatoare de cod - o "​trambulină"​ (e.x. o instrucțiune nop). Astfel, funcția instrumentată se va întoarce în codul din "​trambulină"​. 
- 
-La inițializare,​ ''​Kprobes''​ setează un breakpoint la adresa acestei "​trambuline"​. La acest breakpoint se va apela handlerul asociat kretprobe, si se va reseta IP-ul la adresa de return salvată anterior (adresa de return inițială a funcției instrumentate). 
- 
-{{:​so2:​wiki:​kretprobe.png?​700X297}} 
- 
-</​spoiler>​ 
- 
-\\ 
- 
-** Înregistrare Kprobe ** 
- 
-Pentru înregistrarea unei ''​Kprobe''​ se va folosi o structură de tipul [[http://​lxr.free-electrons.com/​source/​include/​linux/​kprobes.h#​L73 | struct kprobe]]. Aici putem seta ''​addr''​ - adresa la care se va insera proba, ''​pre_handler''/''​post_handler'',​ metode ce vor fi apelate înainte/​după executarea instrucțiunii de la ''​addr''​ și ''​fault_handler''​ ce va fi apelat dacă apare un fault în handlerele pre/post sau la execuția instrucțiunii instrumentate. Adresa la care vrem să inserăm proba se poate specifica fie direct, fie folosind funcția [[http://​lxr.free-electrons.com/​source/​kernel/​kallsyms.c?​v=2.6.33#​L170 | kallsyms_lookup_name]] ce returnează adresa unui simbol primit ca parameru. 
- 
-<code c> 
-struct kprobe { 
-     /* location of the probe point */ 
-     ​kprobe_opcode_t *addr; 
-     /* Called before addr is executed. */ 
-     ​kprobe_pre_handler_t pre_handler;​ 
-     /* Called after addr is executed, unless... */ 
-     ​kprobe_post_handler_t post_handler;​ 
-     /* Called if executing addr or handlers causes a fault (eg. page fault). */ 
-     ​kprobe_fault_handler_t fault_handler;​ 
-     ... 
-} 
-</​code>​ 
- 
-Pentru înregistrarea/​deînregistrarea unei probe se vor apela funcțiile [[http://​lxr.free-electrons.com/​source/​kernel/​kprobes.c#​L1472 | register_kprobe]],​ respectiv [[http://​lxr.free-electrons.com/​source/​kernel/​kprobes.c#​L1577 | unregister_kprobe]]. Mai jos puteți urmări un exemplu în care este inițializată o probă de tipul ''​Kprobe''​. 
- 
-<code c> 
-static struct kprobe kp; 
-  
-/* kprobe pre_handler:​ called just before the probed instruction is executed */ 
-int handler_pre(struct kprobe *p, struct pt_regs *regs); 
-  
-/* kprobe post_handler:​ called after the probed instruction is executed */ 
-void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags); 
-  
-/* fault_handler:​ this is called if an exception is generated for any 
- * instruction within the pre- or post-handler,​ or when Kprobes 
- * single-steps the probed instruction. 
- */ 
-int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr); 
-  
-int init_module(void) 
-{ 
-         ​kp.pre_handler = handler_pre;​ 
-         ​kp.post_handler = handler_post;​ 
-         ​kp.fault_handler = handler_fault;​ 
-         ​kp.addr = (kprobe_opcode_t*) probe_addr; 
-  
-         if ((ret = register_kprobe(&​kp) < 0)) { 
-                 ​printk("​register_kprobe failed, returned %d\n", ret); 
-                 ​return -1; 
-         } 
-         ​printk("​kprobe registered\n"​);​ 
-         ​return 0; 
-} 
- 
-</​code>​ 
- 
-** Înregistrare Jprobe ** 
- 
-Pentru ''​Jprobe'',​ vom folosi o structură de tipul [[http://​lxr.free-electrons.com/​source/​include/​linux/​kprobes.h?​v=2.6.39#​L158 | struct jprobe]], al cărei câmp ''​entry''​ determină adresa handlerului ce va fi apelat la intrarea în funcția instrumentată. Pentru înregistrare/​deînregistrare se vor folosi [[http://​lxr.free-electrons.com/​source/​kernel/​kprobes.c#​L1703 | register_jprobe]]/​[[http://​lxr.free-electrons.com/​source/​kernel/​kprobes.c#​L1740 |unregister_jprobe]]. În exemplul de mai jos se folosește un modul pentru a monitoriza apelurile funcției ''​do_execve_common''​. 
- 
-<note important>​ 
-  * Semnătura handlerului trebuie să fie aceeași cu semnătura funcției instrumentate. 
-  * Nu uitați să apelați jprobe_return() la ieșirea din handler. 
-</​note>​ 
- 
-<file C kprobes.c>​ 
-#include <​linux/​module.h>​ 
-#include <​linux/​init.h>​ 
-#include <​linux/​kernel.h>​ 
-#include <​linux/​kprobes.h>​ 
-#include <​linux/​kallsyms.h>​ 
- 
-MODULE_DESCRIPTION("​Probes module"​);​ 
-MODULE_AUTHOR("​So2rul Esforever"​);​ 
-MODULE_LICENSE("​GPL"​);​ 
- 
-#define LOG_LEVEL KERN_WARNING 
- 
-/* 
- * Pre-entry point for do_execve. 
- */ 
-static int my_do_execve(char * filename, 
- char __user *__user *argv, 
- char __user *__user *envp) 
-{ 
- printk(LOG_LEVEL "​do_execve for %s %s \n", filename, current->​comm);​ 
- /* Always end with a call to jprobe_return(). */ 
- jprobe_return();​ 
- /​*NOTREACHED*/​ 
- return 0; 
-} 
- 
-static struct jprobe my_jprobe = { 
- .entry = (kprobe_opcode_t *) my_do_execve 
-}; 
- 
-static int my_probe_init(void) 
-{ 
- int ret; 
- 
- my_jprobe.kp.addr = 
- (kprobe_opcode_t *) kallsyms_lookup_name("​do_execve"​);​ 
- if (my_jprobe.kp.addr == NULL) { 
- printk(LOG_LEVEL "​Couldn'​t find %s to plant jprobe\n",​ "​do_execve"​);​ 
- return -1; 
- } 
- 
- ret = register_jprobe(&​my_jprobe);​ 
- if (ret < 0) { 
- printk(LOG_LEVEL "​register_jprobe failed, returned %d\n", ret); 
- return -1; 
- } 
- printk(LOG_LEVEL "​Planted jprobe at %p, handler addr %p\n", 
- my_jprobe.kp.addr,​ my_jprobe.entry);​ 
- 
- return 0; 
-} 
- 
-static void my_probe_exit(void) 
-{ 
- unregister_jprobe(&​my_jprobe);​ 
- printk(LOG_LEVEL "​jprobe unregistered\n"​);​ 
-} 
- 
-module_init(my_probe_init);​ 
-module_exit(my_probe_exit);​ 
-</​file>​ 
- 
-** Înregistrare Kretprobe ** 
- 
-''​Kretprobes''​ se vor insera într-un mod similar, folosind o structură de tipul [[http://​lxr.free-electrons.com/​source/​include/​linux/​kprobes.h#​L184 | struct kretprobe]] și funcțiile [[http://​lxr.free-electrons.com/​source/​kernel/​kprobes.c#​L1811 | register_kretprobe]],​ [[http://​lxr.free-electrons.com/​source/​kernel/​kprobes.c#​L1882 | unregister_kretprobe]]. 
- 
-<code c> 
- 
-static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs); 
-  
-static struct kretprobe my_kretprobe = { 
-         ​.handler = ret_handler,​ 
-}; 
- 
 </​code>​ </​code>​
  
so2/laboratoare/lab02.txt · Last modified: 2020/02/20 14:16 by ionel.ghita
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0