Você está na página 1de 5

Depurao do kernel Linux | TUTORIAL

Depurao do kernel Linux

O poder da depurao

TUTORIAL
Depurar o kernel de um sistema operacional
em funcionamento sempre foi uma coisa
traioeira, mas com o emulador Qemu, isso
pode no ser mais uma tarefa to rdua.
por Eva-Katharina Kunst e Jrgen Quade

A
lgumas das operaes bsicas segundo sistema, que ter memria a ferramenta pode lhe dar um espao
que um depurador (ou debu- e gerenciamento de arquivos funcio- do usurio bem definido e um kernel
gger) realiza em um sistema, nando e ajudar voc a pesquisar no enxuto que pode ser rapidamente re-
incluem congelar sequncias de c- cdigo-fonte por variveis, estruturas configurado e modificado.
digo e subsequentemente analisar o de dados, funes e linhas de cdigo. Todas as etapas para essa aborda-
contedo da memria RAM. Se a Isso significa que necessrio apenas gem so mostradas no quadro 2. Voc
sequncia de cdigo pertencer a um um servidor de depurao para o ker- pode comear baixando o Buildroot
aplicativo, a depurao, comparativa- nel a ser depurado. Este servidor pode e descompactando o pacote. Depois,
mente, no envolve grandes proble- executar comandos simples, como ler crie a configurao padro prefe-
mas. Mas se voc congelar o prprio ou gravar clulas de memria ou de- rivelmente para um sistema x86
kernel, no ter mais um ambiente finir pontos de parada de cdigo (bre- digitando make qemu_x86_defconfig.
de execuo que aceite entrada do akpoints) no sistema sob investigao. preciso modificar quatro opes
teclado, sada para um monitor, aces- O emulador Qemu tem um servi- aps digitar make menuconfig:
so ao contedo da memria ou que dor de depurao embutido (quadro Em Toolchain, habilite a opo
continue a executar o kernel depois. 1). Se voc usar tambm o gerador de Build gdb para Host; em Kernel/
Podemos comparar a depurao do sistemas Buildroot [1], a depurao Kernel version, digite 3.2; em System
kernel com a tentativa de realizar de kernel fica relativamente fcil de Configuration/Port to run getty (login
uma cirurgia em si mesmo. implementar. A condio para reali- prompt) on, digite tty1; e finalmente
De um ponto de vista tcnico, zarmos isso ter um kernel com sm- para Build Options/Number of jobs to
esse problema resolvido ao transfe- bolos de debug. Isso no problema run simultaneously, digite o nmero
rirmos funes complexas para um graas ao Buildroot: em pouco tempo, de ncleos da mquina geradora.

Figura 1 No Linux h diversas opes para depurao de cdigo do kernel e dos mdulos: o emulador Qemu, o kgdb e o kdb

Linux Magazine #91 | Junho de 2012 69


TUTORIAL | Depurao do kernel Linux

Figura 2 As opes do kernel necessrias para depurao Figura 3 O GDB iniciado no diretrio do cdigo-fonte
esto localizadas no menu Kernel hacking. Linux para ter acesso aos arquivos C.

Digitar um outro make dispara a O resultado disso basicamente se contm as informaes de depurao.
execuo do primeiro gerador. Isso resume a dois arquivos: voc ter um Obviamente, o depurador tambm
criar o cdigo-fonte do kernel, en- arquivo vmlinux que contm tanto o necessita de acesso ao cdigo-fonte.
tre outras coisas, mas ser necessrio cdigo quanto as informaes de de- Assim que gerar o kernel e o sis-
modificar a configurao novamen- purao correspondentes no diretrio tema de arquivos principal com o
te para depurar o kernel em algum do cdigo-fonte do kernel. O subdire- Buildroot, necessrio em primei-
momento no futuro. trio de arquitetura arch/x86/boot/ ro lugar test-los sem depurao, o
Para faz-lo, execute make para a plataforma x86 contm o que pode ser feito com o comando:
linux-menuconfig no diretrio raiz do kernel compactado no arquivo bzI-
Buildroot. As opes relevantes no mage. Outras plataformas podem cha- qemu -kernel output/images/bzImage
-hda output/images/rootfs.ext2
menu subsequente esto localizadas mar o kernel de zImage. Carregadores -append "root=/dev/sda rw"
no item Kernel Hacking (figura 2). As de boot, como o GRUB, precisam
opes Kernel debugging e Compile do kernel compactado (bzImage). O Se tudo funcionar, voc pode
the kernel with debug info so neces- depurador em si tambm precisa iniciar a depurao acrescentando
srias. Digitar mais um make gera um da imagem do kernel, mas usar a os parmetros -s e -S:
kernel com a configurao modificada. verso no compactada vmlinux, que
qemu -kernel output/images/bzImage
-hda output/images/rootfs.ext2
Listagem 1: Makefile -append "root=/dev/sda rw" -s -S
01 ifneq ($(KERNELRELEASE),)
02 obj-m := hello.o A opo -s inicia o servidor de
03 depurao (gdbserver), e -S para o
04 else kernel no incio.
05 PWD:= $(shell pwd)
06 KDIR:= ~/buildroot-2011.08/output/build/linux-3.1/
07 Mudana de pgina
08 default: Para o GNU debugger (GDB) en-
09 $(MAKE) -C $(KDIR) M=$(PWD) modules
contrar o cdigo C do kernel e dos
10 endif
11 arquivos de cabealho, inicie a ferra-
12 clean: menta no diretrio do cdigo-fonte
13 rm -rf *.ko *.o *.mod.c *.mod.o modules.order do Linux (figura 3). Se voc compilou
14 rm -rf Module.symvers .*.cmd .tmp_versions
um sistema x86, pode usar o GNU

70 www.linuxmagazine.com.br
Depurao do kernel Linux | TUTORIAL

debugger pr-instalado no sistema de Listagem 2: Mdulo hello.c


desenvolvimento; seno, use o GDB 01 #include <linux/fs.h>
compilado para o sistema host; que 02 #include <linux/cdev.h>
reside no diretrio Buildroot output/ 03 #include <linux/device.h>
04 #include <linux/module.h>
host/usr/bin:
05 #include <asm/uaccess.h>
cd output/build/linux-3.2/gdb 06
07 static char hello_world[]="Hello World\n";
O comando gdb inicia a sesso de 08 static dev_t hello_dev_number;
09 static struct cdev *driver_object;
depurao. Para comear, carregue o 10 static struct class *hello_class;
cdigo do kernel e os smbolos com 11 static struct device *hello_dev;
o comando file vmlinux. Se surgir a 12
13 static ssize_t driver_read(struct file *instanz,char __user
mensagem no debug-symbols found, *user, size_t count, loff_t *offset)
ser necessrio verificar as opes de 14 {
depurao em sua configurao do 15 unsigned long not_copied, to_copy;
kernel e, possivelmente, recompil- 16
17 to_copy = min(count, strlen(hello_world)+1);
-lo. Com os smbolos, o vmlinux no 18 no_copied=copy_to_user(user,hello_world,to_copy);
maior que 40 MB. 19
Em seguida, abra uma conexo 20 }
21
com o servidor de depurao digitan- 22 static struct file_operations fops = {
do target remote :1234 (figura 3). O 23 .owner= THIS_MODULE,
comando gdb, ento, prossegue com 24 .read= driver_read,
25 };
o curso da execuo (tabela 1). O co- 26
mando continue inicia o sistema Linux 27 static int __init mod_init( void )
em modo convidado e pressionar as 28 {
29 if (alloc_chrdev_region(&hello_dev_number,0,1,"Hello")&lt;0)
teclas [Ctrl] + [C] interrompe a exe- 30 return -EIO;
cuo. A figura 3 mostra o comando 31 driver_object = cdev_alloc();
GDB break vfs_mknod definindo um 32 if (driver_object==NULL)
breakpoint para a funo vfs_mknod. 33 goto free_device_number;
34 driver_object->owner = THIS_MODULE;
Para o kernel 3.2, use sys_mknod em vez 35 driver_object&#8208;&gt;ops = &fops;
disso, devido a mudanas no kernel 36 if (cdev_add(driver_object, hello_dev_number,1))
Linux. Quando um usurio no Linux 37 goto free_cdev;
38 hello_class = class_create( THIS_MODULE, "Hello" );
executa o comando mknod /dev/hello c 39 if (IS_ERR( hello_class )) {
254 0, a execuo paralisada e voc 40 pr_err( "hello: no udev support\n");
pode inspecionar as variveis de am- 41 goto free_cdev;
42 }
biente. Para continuar a execuo do 43 hello_dev = device_create( hello_class, NULL,
programa, use o comando continue. hello_dev_number, NULL, "%s", "hello" );
Para isolar o depurador do sistema 44 return 0;
Linux, primeiro pressione as teclas 45 free_cdev:
46 kobject_put( &driver_object&#8208;&gt;kobj );
[Ctrl] + [C] e depois use o coman- 47 free_device_number:
do GDB detach para interromper a 48 unregister_chrdev_region( hello_dev_number, 1 );
conexo com o servidor. Digitar quit 49 return -EIO;
50 }
finaliza o depurador. 51
52 static void __exit mod_exit( void )
Mdulos 53 {
54 device_destroy( hello_class, hello_dev_number );
Os mdulos do kernel tambm po- 55 class_destroy( hello_class );
dem ser depurados no nvel da lingua- 56 cdev_del( driver_object );
gem de programao com o Qemu. 57 unregister_chrdev_region( hello_dev_number, 1 );
Para faz-lo, preciso ativar a opo 58 return;
59 }
Enable loadable module support no 60
submenu Module unloading. Em 61 module_init( mod_init );
outras palavras, esse processo envolve 62 module_exit( mod_exit );
63 MODULE_LICENSE("GPL");
reconfigurar e gerar novamente o ker-

Linux Magazine #91 | Junho de 2012 71


TUTORIAL | Depurao do kernel Linux

nel que voc criou com o Buildroot. necessrio definir as variveis de am- o servidor de depurao, mas o Li-
Como tambm impossvel prever biente CROSS_COMPILE e ARCH. nux ainda inicializar diretamente.
o endereo do cdigo do mdulo na Para depurar o mdulo, preciso Aps logar-se como root, carregue
memria principal, voc precisa car- usar a listagem 1 como Makefile e a o mdulo com o comando insmod
regar o mdulo, encontrar o endereo listagem 2 como arquivo hello.c em hello.ko (figura 4).
e informar ao depurador. uma pasta abaixo do diretrio raiz Os comando seguintes determi-
Ser preciso verificar as entradas do Buildroot. Voc tambm pode nam os endereos dos segmentos de
no sistema de arquivos /sys para precisar modificar o caminho para o cdigo e os dois segmentos de dados:
faz-lo, mas trataremos disso posterior- cdigo-fonte Linux na varivel KDIR.
# cat /sys/module/hello/sections/.text
mente. Antes da depurao, primeiro O Makefile modificado gera o mdulo # cat /sys/module/hello/sections/.data
gere o mdulo para o kernel criado hello.ko, que voc pode ento copiar # cat /sys/module/hello/sections/.bss
com o Buildroot. A maneira mais para o sistema de arquivos raiz:
fcil de fazer isso usar um arquivo Como o sistema Linux gerado pelo
cp hello.ko ../output/target/root/
Makefile modificado, apontando a Buildroot no inclui compatibilida-
varivel KDIR para o caminho com Um make no diretrio Buildroot de udev, voc tambm precisa usar
o cdigo-fonte Linux que voc est gera novamente o sistema de arqui-
usando, que estar abaixo do diret- vos raiz. Isso coloca o mdulo no Quadro 1: Opes de
rio raiz, neste caso. diretrio home do usurio root aps a depurao do kernel
Se o sistema Linux no Qemu que inicializao. A abordagem mais fcil No Linux, h trs abordagens para
voc est depurando no for proje- omitir a opo -S e usar -s quando depurao de cdigo do kernel e
tado para uma arquitetura x86, ser o Qemu for inicializado. Isso habilita seus mdulos: o Qemu, o kgdb e
o kdb (figura 1). Embora o Qemu
no precise de nenhum suporte
especial no kernel, Linus Torvalds
relutantemente aceitou o servidor
de depurao embutido no kernel,
kgdb, h trs anos.
Assim como no Qemu, o depurador
em si executado em um segundo
computador, o host de depurao.
A comunicao entre o servidor e
o depurador utiliza uma conexo
serial. Se voc no tem nem uma
segunda mquina nem uma cone-
Figura 4 Aps entrar como usurio root, carregue o mdulo do kernel no Qemu xo serial, pode usar uma soluo
e determine os endereos do cdigo e dos segmentos de dados. de virtualizao como o VirtualBox
para emular a interface requerida.
Comando Funo Alm disso, Torvalds integrou ao
kdb, um frontend do kgdb, na ver-
Add-symbol-file Carrega arquivo de smbolos adicional
so 2.6.35 do kernel para haver
break Define um breakpoint compatibilidade com operaes
bt Retorna a sequncia de chamadas para funes simples, como ler e definir endere-
os de memria, ler mensagens do
continue Continua o programa
kernel ou mostrar os processos de
del Apaga um breakpoint criado computao instanciados todos
detach Faz logout do depurador no servidor de depurao acontecendo no mesmo sistema.
Caso seja configurada para isso, a
file Carrega cdigo (programa)
ferramenta kdb habilitada automa-
help Retorna dados sobre as funes implementadas ticamente quando o kernel sofre al-
info Exibe diversas informaes guma pane (kernel crash).
next Processa linha de cdigo De outro modo, voc pode pres-
sionar o atalho de teclado [Alt] +
Exibe a sada de variveis, estruturas
print [PrtScr] + [g]. Contudo, isso ainda
de dados e clulas de memria
no permite que os desenvolvedo-
quit Termina o GDB res depurem o kernel no nvel da lin-
Tabela 1 Comandos GDB importantes. guagem de programao.

72 www.linuxmagazine.com.br
Depurao do kernel Linux | TUTORIAL

o comando mknod /dev/hello c 254 target remote :1234, o Qemu paralisa funo driver_read. O comando
0 para criar o arquivo de dispositivos o sistema Linux. O seguinte comando continue pede para o sistema Linux
externos, que um aplicativo usaria informa ao sistema o endereo hexa- voltar ao trabalho. Se voc digitar o
para acessar um driver neste exemplo. decimal do segmento de cdigo e dos comando cat /dev/hello no terminal
Voc pode descobrir se o sistema usa dois segmentos de dados: do sistema que est depurando, ver
um nmero maior do que 254 digi- que agora o driver_read est habili-
tando o comando cat /proc/devices add-symbol-file path/hello.ko tado e o GDB interrompe o kernel
0xd8817000 -s .data 0xd88170e0
| grep Hello. Depois, inicie o GDB -s .bss 0xd8817294 no ponto definido antes. Voc pode,
no sistema host, normalmente a par- ento, investigar as clulas de me-
tir do diretrio fonte do kernel. Aps Agora, voc pode definir um mria do mdulo e acompanhar as
digitar os comandos file vmlinux e breakpoint, por exemplo, para a etapas do processo.

Quadro 2: Breve guia do Buildroot Concluso


Vrias etapas so necessrias para tornar um ambiente apto para depurar o Pode ser confuso ver o depurador
kernel Linux e seus mdulos. saltar entre as linhas de cdigo, apa-
1. Baixe e descompacte o Buildroot: rentemente sem motivo. O acesso s
wget http://buildroot.uclibc.org/downloads/buildroot-2011.11.tar.bz2 variveis locais explica a razo disso:
tar xvfj buildroot-2011.11.tar.bz2 value optimized out o compilador
2. Configure o Buildroot e gere o sistema: otimizou o cdigo do kernel. Isso
cd buildroot-2011.11 significa que algumas das variveis
make qemu_x86_defconfig definidas esto invisveis para o de-
make menuconfig (build-option, Kernel-Version 3.2, gdb, tty1)
make
purador; fragmentos de cdigo foram
make linux-menuconfig (debug info) remodelados. Como algumas macros
make esto sendo usadas no kernel, a reso-
3. Compile o mdulo e copie-o no diretrio raiz: luo de problemas tambm no
cd driver nem um pouco facilitada. Em muitos
export CROSS_COMPILE=... casos, descobrimos que uma varivel
export ARCH=... na verdade uma macro inteligente.
make
cp module.ko .../output/target/root/ Assim, a depurao do kernel
continua a ser um desafio que exige
4. Gere novamente o sistema de arquivos principal:
muita pacincia e prtica.
cd buildroot-2011.11
make
5. Inicie o sistema com o Qemu e o servidor de depurao: Mais informaes
qemu -kernel output/images/bzImage -hda [1] Download do Buildroot:
output/images/rootfs.ext2 -append "root=/dev/sda rw" -s -S & http://buildroot.uclibc.
6. Inicie o depurador: org/download.html
gdb
Sesso do depurador: Os autores
file vmlinux Eva-Katharina Kunst, jornalista, e
target remote :1234 Jrgen Quade, professor da Fa-
continue culdade do Baixo Reno (Alemanha),
7. Faa login, carregue o driver e identifique os endereos de memria (por so fs do Cdigo Aberto desde os
exemplo, para hello.ko): primrdios do Linux. Juntos, publi-
insmod hello.ko caram o livro Desenvolvimento de
cat /sys/module/hello/sections/.text drivers no Linux, sobre o kernel 2.6.
cat /sys/module/hello/sections/.data
cat /sys/module/hello/sections/.bss
Gostou do artigo?
igo?
8. Carregue os dados de smbolos do mdulo: Queremos ouvir sua opinio.
pinio.
add-symbol-file module.ko text_address -s .data data_address Fale conosco em
-s .bss bss_address cartas@linuxmagazine.com.br
zine.com
9. Depurao: defina os pontos de parada de cdigo (breakpoints) ou realize Este artigo no nosso
sso site:
s :
uma depurao personalizada. r/artic 6939
http://lnm.com.br/article/6939

Linux Magazine #91 | Junho de 2012 73

Você também pode gostar