linuks u ugrađenim sistemima i razvoj rukovalaca - debagovanje...kernel log ring buffer typically...
TRANSCRIPT
Univerzitet u Novom Sadu
Fakultet tehničkih nauka
Odsek za računarsku tehniku i računarske komunikacije
Linuks u ugrađenim sistemima i razvoj rukovalaca
Debagovanje
Sadržaj
Debagovanje
Uvod
Udaljeno debagovanje
2
DEBAGOVANJE
Uvod
3
Debagovanje porukama (1/2)
Univerzalna tehnika debagovanja sa ispisima printk()
Ispisi se pojavljuju u konzoli ili u /var/log/messages u zavisnosti od prioriteta
Kontrolisano pomoću kernel parametra loglevel ili kroz /proc/sys/kernel/printk
Dostupni prioriteti ( include/linux/kernel.h ) #define KERN_EMERG "<0>" /* system is unusable */
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant condition */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */
4
Debagovanje porukama (2/2)
printk() - zastarela familija funkcija, više nije preporučljiva
pr_* familija funckija: pr_emerg(), pr_alert(), pr_critic(), pr_err(), pr_warning(), pr_notice(), pr_info(), pr_cont() i specijalna pr_debug()
Argument je string
Definisane u zaglavlju include/linux/printk.h
dev_* familija funkcija: dev_emerg(), dev_alert(), dev_crit(), dev_err(), dev_warning(), dev_notice(), dev_info() i specijalna dev_dbg()
Prvi argument je pokazivač na struct device strukturu, a drugi je string
Definisane u zaglavlju include/linux/device.h
Koriste se u rukovaocima koji koiste Linuksov model rukavaoca 5
pr_debug() i dev_dbg() (1/2)
Kada se rukovalac prevede sa definisanim simbolom DEBUG, sve ove poruke se prevode i prikazuju se na debug nivou
DEBUG simbol se može definisati
Iskozom #define DEBUG na pocetku rukovaoca
Korišćenjem ccflags-$(CONFIG_DRIVER) += -DDEBUG u Makefile-u
6
pr_debug() i dev_debug() (2/2)
Kada se kernel prevede sa CONFIG_DYNAMIC_DEBUG uključenim, ove poruke se mogu dinamički uključivati na nivou datoteke, modula ili poruke
Više detalja u Documentation/dynamic-debug-howto.txt
Kada DEBUG simbol nije definisan i CONFIG_DYNAMIC_DEBUG nije uključen, ove poruke se ne prevode
7
Definisanje prioriteta
Each message is associated to a priority, ranging from 0 for emergency to 7 for debug. ▶ All the messages, regardless of their priority, are stored in the kernel log ring buffer ▶ Typically accessed using the dmesg command ▶ Some of the messages may appear on the console, depending on their priority and the configuration of ▶ The loglevel kernel parameter, which defines the priority above which messages are displayed on the console. See Documentation/kernel-parameters.txt for details. ▶ The value of /proc/sys/kernel/printk, which allows to
8
Debugfs
Virtuelni sistem datoteka za prikaz debag informacija u korisničkom prostoru
Konfiguracija kernela
Kernel hacking > Debug Filesystem (DEBUG_FS)
Jednostavnije za kodovanje od sprega u /proc ili /sys
Debag sprega nestaje kada se isključi u konfiguraciji
Primer mauntovanja
sudo mount -t debugfs none /mnt/debugfs
9
Debugfs API (1/2)
Pravljenje poddirektorijuma :
struct dentry *debugfs_create_dir(const char
*name, struct dentry *parent);
Prikaz celobrojne promenljive kao datoteke u DebugFS-u struct dentry *debugfs_create_{u,x}{8,16,32}
(const char *name, mode_t mode, struct dentry *parent,
u8 *value);
u je decimalni prikaz
x je heksadecimalni prikaz
10
Debugfs API (2/2)
Prikaz binarnog bloba u DebugFS-u
struct dentry *debugfs_create_blob(const char
*name, mode_t mode, struct dentry *parent,
struct debugfs_blob_wrapper *blob);
Moguće je koristiti i generičkiju funkciju debugfs_create_file() u razne svrhe
11
Jednostavan debugfs primer
12
Debagovanje sa /proc i /sys (1/2)
Umesto ispisivanja poruka u kernelski log informacije se mogu učiniti dostupnim korisničkom prostoru kroz datoteku u /proc ili /sys koja se registruje u rukovaocu
Može da prikaže bilo kakvu informaciju o uređaju ili rukovaocu
Može da se koristi i za slanje podataka i za kontrolu rukovaoca
Upozorenje: Dostupno svima
U fazi proizvodnje treba ukloniti sprege za debagovanje
Od pojave debugfs-a nije više preferirani način debagovanja (ne koristi se u novim rukovaocima)
13
Debagovanje sa /proc i /sys (2/2)
Primeri
cat /proc/acme/stats
Prikazuje statistiku o acme rukovaocu
cat /proc/acme/globals
Prikazuje vrednosti globalnih varijabli koje koristi rukovalac
echo 600000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
Podešava brzinu procesora
14
Debagovanje pomoću ioctl
ioctl() sistemski poziv se može koristiti za upit o informacijama ili za slanje komandi rukovaocu
Poziva ioctl operaciju nad datotekom koja se registruje u rukovaocu
Prednost - debag sprega nije javna (može se čak ostaviti u sistemu i kada dospe do korisnika)
Od pojave debugfs-a nije više preferirani način debagovanja (ne koristi se u novim rukovaocima)
15
Korišćenje Magic SysRq
Omogućava pokretanje više debug / rescue komandi čak i kada se čini da je kernel u velikom problemu
na PC: [Alt] + [SysRq] + <karakter>
na namenskim sistemima:
break karakter na serijskoj liniji + <karakter>
Primer komandi:
s: sinhronizuj sve mauntovane sisteme datoteka
b: ponovo pokreni sistem (reboot)
w: prikazuje kernel stek svih uspavanih procesa
t: prikazuje kernel stek svih pokrenutih procesa
Možete registrovati i svoju komandu!
Detalji u Documentation/sysrq.txt 16
Debagovanje GDB-om
Ukoliko se kernel pokrene iz debagera na istom računaru uticaće na ponašanje kernela na računaru
GDB može da pristupi trenutnom stanju kernela
gdb /usr/src/linux/vmlinux /proc/kcore
Može da se pristupi kernelskim strukturama, da se prate pokazivači (samo čitanje je dozvoljeno)
Kernel mora da bude preveden sa CONFIG_DEBUG_INFO (Kernel hacking sekcija)
17
Analiza kernelske greške sa kexec-om
kexec sistemski poziv
omogućeva pozivanje novog kernela bez restartovanja sistema
Ideja: posle kernel panike novi kernel se automatski učitava sa rezervisane lokacije u RAM-u i vrši analizu memorije srušenog kernela
18
1. Kopiraj
debag
kernel na
rezervisano
mesto u
RAM-u
standardni
kernel
debag
kernel
RAM
memorija
2. kernel
panika,
kexec
debag
kernel
3. Analiza
RAM-a
srušenog
kernela
Još saveta za debagovanje
Omogućiti CONFIG_KALLSYMS_ALL
General Setup > Configure standard kernel features
poruke o oops-evima se dobijaju sa imenima simbola umesto sa sirovim adresama
Ukoliko kernel ne može da se pokrene a ne ispisuje nikakve poruke može da se uključi debagovanje na niskom nivou
CONFIG_DEBUG_LL=y 19
DEBAGOVANJE
Udaljeno debagovanje
20
Udaljeno debagovanje
U neugrađenim sistemima debagovanje se uglavnom izvršava gdb-om
gdb ima direktan pristup binarnim datotekama i bibliotekama prevednim sa debag simbolima
U ugrađenim sistemima ciljna platforma je često ograničena memorijom i ne može da dozvoli direktno debagovanje gdb-om
Bolja opcija je udaljeno debagovanje
gdb se koristi na lokalnom računaru
gdbserver se koristi na ciljnoj platformi 21
Udaljeno debagovanje - arhitektura
22
Lokalni računar Ciljna platforma
Binarne datoteke i biblioteke sa debag
simbolima
Pokrenut program sa binarnim datotekama i
bibliotekama bez debag simbola
arm-linux-gnueabihf-gdb
gdbserver
Serijska ili
Eternet
veza
Udaljeno debagovanje - zahtevi
Zahtevi
Na lokalnom računaru
alati za prevođenje sa podrškom za gdb (arm-linux-gnueabihf-gdb)
Verzija gdb-a koja se pokreće na lokalnom računaru, ali razume specifičnosti ciljne platforme
Na ciljnoj platformi
gdbserver program preveden za ciljnu arhitekturu
Često se nalazi kao deo alata za prevođenje
Serijska ili Eternet veza između lokalnog računara i ciljne platforme
23
Udaljeno debagovanje - korišćenje
Povezivanje gdbservera na pokrenut program na ciljnoj platformi
$ gdbserver program -p <pid>
Pokrenuti na lokalnom računaru
$ arm-linux-gnueabihf-gdb
Ostvarivanje veze sa gdbserver-om
(gdb) target remote <host:port>
Učitavanje simbola
(gdb) symbol-file <program>
Nakon ovog koraka gdb može da se koristi kao i pri normalnom debagovanju na lokalnom računaru
24
Korišćenje kgdb (serijska veza) (1/2)
Detalji su dostupni u kernel dokumentaciji: Documentation/DocBook/kgdb/
Preporučljivo je uključiti CONFIG_FRAME_POINTER za pomoć u pravljenju pouzdanijih stek tragova u gdb-u.
Potrebno je uključiti kgdb U/I rukovalac. Jedan od njih je kgdb preko serijske konzole (kgdboc: kgdb over console, uključuje se CONFIG_KGDB_SERIAL_CONSOLE)
Konfigurišite kgdboc u vreme pokretanja sistema prosleđivanjem sledećih parametara kernelu:
kgdboc=<tty-device>,<bauds>.
Primer: kgdboc=ttyS0,115200
25
Korišćenje kgdb (serijska veza) (2/2)
Takođe prosledite kgdbwait kernelu: forsira kgdb da čeka na konekciju sa debagerom.
Pokrenite kernel i kada se konzola inicijalizuje, prekinite kernel komandom Alt + SysRq + g.
Na radnoj stanici, pokrenite gdb:
gdb ./vmlinux
(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0
Kada ste ostvarili vezu, možete debagovati kernel kao što biste bilo koji aplikativni program.
26
Debagovanje JTAG spregom
Dva tipa JTAG dongli
Dongle koje nude spregu kompatibilnu sa gdb-om, preko serijskog porta ili Ethernet veze. gdb može direktno da se poveže sa uređajem.
Dongle koje ne nude spregu kompatibilnu sa gdb-om, a najčešće podržavaju OpenOCD (Open On Chip Debugger): http://openocd.sourceforge.net/
OpenOCD je spoj između gdb jezika za debagovanje i JTAG sprege ciljnog CPU.
Pogledajte raznu dokumentaciju: http://openocd.org/documentation/
Za svaku ploču je potreban OpenOCD konfiguraciona datoteka (traži se od proizvođača)
27