xref: /linux/Documentation/translations/pt_BR/process/4.Coding.rst (revision 72fdff1416e280e2baaa3cca69574defb998437e)
1*a5d47da3SDaniel Pereira.. SPDX-License-Identifier: GPL-2.0
2*a5d47da3SDaniel Pereira
3*a5d47da3SDaniel PereiraEscrever o código corretamente
4*a5d47da3SDaniel Pereira==============================
5*a5d47da3SDaniel Pereira
6*a5d47da3SDaniel PereiraEmbora haja muito o que se dizer sobre um processo de design sólido e orientado
7*a5d47da3SDaniel Pereiraà comunidade, a prova de qualquer projeto de desenvolvimento de kernel está no
8*a5d47da3SDaniel Pereiracódigo resultante. É o código que será examinado por outros desenvolvedores e
9*a5d47da3SDaniel Pereiramesclado (ou não) na árvore principal (*mainline*). Portanto, é a qualidade
10*a5d47da3SDaniel Pereiradeste código que determinará o sucesso final do projeto.
11*a5d47da3SDaniel Pereira
12*a5d47da3SDaniel PereiraEsta seção examinará o processo de codificação. Começaremos analisando uma série
13*a5d47da3SDaniel Pereirade maneiras pelas quais os desenvolvedores de kernel podem errar. Em seguida, o
14*a5d47da3SDaniel Pereirafoco mudará para como fazer as coisas do jeito certo e as ferramentas que podem
15*a5d47da3SDaniel Pereiraajudar nessa busca.
16*a5d47da3SDaniel Pereira
17*a5d47da3SDaniel Pereira
18*a5d47da3SDaniel PereiraArmadilhas
19*a5d47da3SDaniel Pereira----------
20*a5d47da3SDaniel Pereira
21*a5d47da3SDaniel PereiraEstilo de Codificação
22*a5d47da3SDaniel Pereira*********************
23*a5d47da3SDaniel Pereira
24*a5d47da3SDaniel PereiraO kernel há muito possui um estilo de codificação padrão, descrito em
25*a5d47da3SDaniel Pereira:ref:`Documentation/process/coding-style.rst <codingstyle>`. Por grande parte
26*a5d47da3SDaniel Pereiradesse tempo, as políticas descritas naquele arquivo eram consideradas, no
27*a5d47da3SDaniel Pereiramáximo, como recomendações. Como resultado, há uma quantidade substancial
28*a5d47da3SDaniel Pereirade código no kernel que não cumpre as diretrizes de estilo de codificação.
29*a5d47da3SDaniel PereiraA presença desse código leva a dois riscos independentes para os
30*a5d47da3SDaniel Pereiradesenvolvedores do kernel.
31*a5d47da3SDaniel Pereira
32*a5d47da3SDaniel PereiraO primeiro deles é acreditar que os padrões de codificação do kernel não importam
33*a5d47da3SDaniel Pereirae não são exigidos. A verdade é que adicionar novo código ao kernel é muito
34*a5d47da3SDaniel Pereiradifícil se esse código não estiver escrito de acordo com o padrão; muitos
35*a5d47da3SDaniel Pereiradesenvolvedores solicitarão que o código seja reformatado antes mesmo de
36*a5d47da3SDaniel Pereirarevisá-lo. Uma base de código tão grande quanto a do kernel exige certa
37*a5d47da3SDaniel Pereirauniformidade para tornar possível que os desenvolvedores entendam rapidamente
38*a5d47da3SDaniel Pereiraqualquer parte dela. Portanto, não há mais espaço para códigos com formatações
39*a5d47da3SDaniel Pereiraestranhas.
40*a5d47da3SDaniel Pereira
41*a5d47da3SDaniel PereiraOcasionalmente, o estilo de codificação do kernel entrará em conflito com o
42*a5d47da3SDaniel Pereiraestilo exigido por um empregador. Nesses casos, o estilo do kernel terá que
43*a5d47da3SDaniel Pereiravencer para que o código possa ser mesclado. Colocar código no kernel significa
44*a5d47da3SDaniel Pereiraabrir mão de um certo grau de controle de várias maneiras — incluindo o controle
45*a5d47da3SDaniel Pereirasobre como o código é formatado.
46*a5d47da3SDaniel Pereira
47*a5d47da3SDaniel PereiraA outra armadilha é presumir que o código já presente no kernel necessita
48*a5d47da3SDaniel Pereiraurgentemente de correções de estilo de codificação. Os desenvolvedores podem
49*a5d47da3SDaniel Pereiracomeçar a gerar patches de reformatação como uma forma de ganhar familiaridade
50*a5d47da3SDaniel Pereiracom o processo, ou como um meio de incluir seus nomes nos logs de alterações
51*a5d47da3SDaniel Pereira(*changelogs*) do kernel  ou ambos. No entanto, patches puramente de estilo de
52*a5d47da3SDaniel Pereiracodificação são vistos como ruído pela comunidade de desenvolvimento; eles tendem
53*a5d47da3SDaniel Pereiraa receber uma recepção fria. Portanto, é melhor evitar esse tipo de patch. É
54*a5d47da3SDaniel Pereiranatural corrigir o estilo de um trecho de código ao trabalhar nele por outros
55*a5d47da3SDaniel Pereiramotivos, mas mudanças de estilo de codificação não devem ser feitas apenas por
56*a5d47da3SDaniel Pereirafazer.
57*a5d47da3SDaniel Pereira
58*a5d47da3SDaniel PereiraO documento de estilo de codificação também não deve ser lido como uma lei
59*a5d47da3SDaniel Pereiraabsoluta que nunca pode ser transgredida. Se houver um bom motivo para ir contra
60*a5d47da3SDaniel Pereirao estilo (uma linha que se torna muito menos legível se for dividida para caber
61*a5d47da3SDaniel Pereirano limite de 80 colunas, por exemplo), simplesmente faça isso.
62*a5d47da3SDaniel Pereira
63*a5d47da3SDaniel PereiraNote que você também pode usar a ferramenta ``clang-format`` para ajudá-lo com
64*a5d47da3SDaniel Pereiraessas regras, para reformatar rapidamente partes do seu código de forma automática
65*a5d47da3SDaniel Pereirae para revisar arquivos completos a fim de identificar erros de estilo de
66*a5d47da3SDaniel Pereiracodificação, erros de digitação e possíveis melhorias. Ela também é útil para
67*a5d47da3SDaniel Pereiraordenar ``#includes``, alinhar variáveis/macros, reajustar o fluxo de textos e
68*a5d47da3SDaniel Pereiraoutras tarefas semelhantes. Veja o arquivo
69*a5d47da3SDaniel Pereira:ref:`Documentation/dev-tools/clang-format.rst <clangformat>` para mais detalhes.
70*a5d47da3SDaniel Pereira
71*a5d47da3SDaniel PereiraAlgumas configurações básicas do editor, como indentação e fins de linha,
72*a5d47da3SDaniel Pereiraserão definidas automaticamente se você estiver usando um editor compatível
73*a5d47da3SDaniel Pereiracom o EditorConfig. Consulte o site oficial do EditorConfig para obter mais
74*a5d47da3SDaniel Pereirainformações: https://editorconfig.org/
75*a5d47da3SDaniel Pereira
76*a5d47da3SDaniel PereiraCamadas de Abstração
77*a5d47da3SDaniel Pereira********************
78*a5d47da3SDaniel Pereira
79*a5d47da3SDaniel PereiraOs professores de Ciência da Computação ensinam os alunos a fazerem uso
80*a5d47da3SDaniel Pereiraextensivo de camadas de abstração em nome da flexibilidade e da ocultação de
81*a5d47da3SDaniel Pereirainformações. Certamente o kernel faz uso extensivo de abstração; nenhum
82*a5d47da3SDaniel Pereiraprojeto que envolva vários milhões de linhas de código poderia fazer o
83*a5d47da3SDaniel Pereiracontrário e sobreviver. No entanto, a experiência tem mostrado que a
84*a5d47da3SDaniel Pereiraabstração excessiva ou prematura pode ser tão prejudicial quanto a otimização
85*a5d47da3SDaniel Pereiraprematura. A abstração deve ser usada até o nível necessário e não além.
86*a5d47da3SDaniel Pereira
87*a5d47da3SDaniel PereiraEm um nível simples, considere uma função que possui um argumento que é
88*a5d47da3SDaniel Pereirasempre passado como zero por todos os chamadores. Alguém poderia manter esse
89*a5d47da3SDaniel Pereiraargumento caso alguém eventualmente precise usar a flexibilidade extra que ele
90*a5d47da3SDaniel Pereiraoferece. A essa altura, no entanto, as chances são grandes de que o código que
91*a5d47da3SDaniel Pereiraimplementa esse argumento extra tenha sido quebrado de alguma forma sutil que
92*a5d47da3SDaniel Pereiranunca foi percebida — porque ele nunca foi usado. Ou, quando surge a
93*a5d47da3SDaniel Pereiranecessidade de flexibilidade extra, ela não ocorre de uma forma que corresponda
94*a5d47da3SDaniel Pereiraà expectativa inicial do programador. Os desenvolvedores do kernel enviam
95*a5d47da3SDaniel Pereirapatches rotineiramente para remover argumentos não utilizados; eles não devem,
96*a5d47da3SDaniel Pereiraem geral, ser adicionados em primeiro lugar.
97*a5d47da3SDaniel Pereira
98*a5d47da3SDaniel PereiraCamadas de abstração que ocultam o acesso ao hardware — frequentemente para
99*a5d47da3SDaniel Pereirapermitir que a maior parte de um driver seja usada com múltiplos sistemas
100*a5d47da3SDaniel Pereiraoperacionais — são especialmente malvistas. Essas camadas obscurecem o código
101*a5d47da3SDaniel Pereirae podem impor uma penalidade de desempenho; elas não pertencem ao kernel
102*a5d47da3SDaniel PereiraLinux.
103*a5d47da3SDaniel Pereira
104*a5d47da3SDaniel PereiraPor outro lado, se você se pegar copiando quantidades significativas de código
105*a5d47da3SDaniel Pereirade outro subsistema do kernel, é hora de perguntar se faria sentido, de fato,
106*a5d47da3SDaniel Pereiraextrair parte desse código em uma biblioteca separada ou implementar essa
107*a5d47da3SDaniel Pereirafuncionalidade em um nível superior. Não há valor em duplicar o mesmo código
108*a5d47da3SDaniel Pereirapor todo o kernel.
109*a5d47da3SDaniel Pereira
110*a5d47da3SDaniel Pereira
111*a5d47da3SDaniel PereiraUso de #ifdef e do pré-processador em geral
112*a5d47da3SDaniel Pereira*******************************************
113*a5d47da3SDaniel Pereira
114*a5d47da3SDaniel PereiraO pré-processador C parece apresentar uma forte tentação para alguns
115*a5d47da3SDaniel Pereiraprogramadores C, que o veem como uma forma de codificar eficientemente uma grande
116*a5d47da3SDaniel Pereiraquantidade de flexibilidade em um arquivo-fonte. No entanto, o pré-processador
117*a5d47da3SDaniel Pereiranão é C, e o uso pesado dele resulta em um código muito mais difícil de ser lido
118*a5d47da3SDaniel Pereirapor outros e mais difícil para o compilador verificar a correção. O uso pesado
119*a5d47da3SDaniel Pereirado pré-processador é quase sempre um sinal de código que precisa de algum
120*a5d47da3SDaniel Pereiratrabalho de limpeza.
121*a5d47da3SDaniel Pereira
122*a5d47da3SDaniel PereiraA compilação condicional com #ifdef é, de fato, um recurso poderoso, e é
123*a5d47da3SDaniel Pereirautilizada dentro do kernel. Mas há pouco desejo de ver um código que seja
124*a5d47da3SDaniel Pereirasalpicado liberalmente com blocos #ifdef. Como regra geral, o uso de #ifdef
125*a5d47da3SDaniel Pereiradeve ser confinado a arquivos de cabeçalho (headers) sempre que possível. O
126*a5d47da3SDaniel Pereiracódigo compilado condicionalmente pode ser confinado a funções que, se o código
127*a5d47da3SDaniel Pereiranão estiver presente, simplesmente se tornam vazias. O compilador irá então,
128*a5d47da3SDaniel Pereirasilenciosamente, otimizar e remover a chamada para a função vazia. O resultado
129*a5d47da3SDaniel Pereiraé um código muito mais limpo e fácil de acompanhar.
130*a5d47da3SDaniel Pereira
131*a5d47da3SDaniel PereiraAs macros do pré-processador C apresentam uma série de riscos, incluindo a
132*a5d47da3SDaniel Pereirapossível avaliação múltipla de expressões com efeitos colaterais e a falta de
133*a5d47da3SDaniel Pereirasegurança de tipos. Se você se sentir tentado a definir uma macro, considere a
134*a5d47da3SDaniel Pereiracriação de uma função inline em seu lugar. O código resultante será o mesmo,
135*a5d47da3SDaniel Pereiramas as funções inline são mais fáceis de ler, não avaliam seus argumentos
136*a5d47da3SDaniel Pereiramúltiplas vezes e permitem que o compilador realize a checagem de tipos nos
137*a5d47da3SDaniel Pereiraargumentos e no valor de retorno.
138*a5d47da3SDaniel Pereira
139*a5d47da3SDaniel Pereira
140*a5d47da3SDaniel PereiraFunções Inline
141*a5d47da3SDaniel Pereira**************
142*a5d47da3SDaniel Pereira
143*a5d47da3SDaniel PereiraNo entanto, as funções inline apresentam um perigo próprio. Os programadores
144*a5d47da3SDaniel Pereirapodem ficar encantados com a eficiência percebida inerente a evitar uma chamada
145*a5d47da3SDaniel Pereirade função e encher um arquivo de código-fonte com funções inline. Essas
146*a5d47da3SDaniel Pereirafunções, contudo, podem na verdade reduzir o desempenho. Como seu código é
147*a5d47da3SDaniel Pereirareplicado em cada local de chamada, elas acabam inflando o tamanho do kernel
148*a5d47da3SDaniel Pereiracompilado. Isso, por sua vez, cria pressão nos caches de memória do
149*a5d47da3SDaniel Pereiraprocessador, o que pode desacelerar a execução drasticamente. As funções
150*a5d47da3SDaniel Pereirainline, como regra, devem ser bastante pequenas e relativamente raras. O custo
151*a5d47da3SDaniel Pereirade uma chamada de função, afinal de contas, não é tão alto; a criação de um
152*a5d47da3SDaniel Pereiragrande número de funções inline é um exemplo clássico de otimização prematura.
153*a5d47da3SDaniel Pereira
154*a5d47da3SDaniel PereiraEm geral, os programadores de kernel ignoram os efeitos de cache por sua própria
155*a5d47da3SDaniel Pereiraconta e risco. O clássico compromisso entre tempo e espaço (tradeoff) ensinado
156*a5d47da3SDaniel Pereiranas aulas introdutórias de estruturas de dados frequentemente não se aplica ao
157*a5d47da3SDaniel Pereirahardware contemporâneo. Espaço *é* tempo, no sentido de que um programa maior
158*a5d47da3SDaniel Pereiraserá executado mais lentamente do que um que seja mais compacto.
159*a5d47da3SDaniel Pereira
160*a5d47da3SDaniel PereiraCompiladores mais recentes desempenham um papel cada vez mais ativo em decidir
161*a5d47da3SDaniel Pereirase uma determinada função deve ou não ser realmente inline. Portanto, a inserção
162*a5d47da3SDaniel Pereiraliberal da palavra-chave "inline" pode não apenas ser excessiva; ela também pode
163*a5d47da3SDaniel Pereiraser irrelevante.
164*a5d47da3SDaniel Pereira
165*a5d47da3SDaniel Pereira
166*a5d47da3SDaniel PereiraMecanismo de Trava
167*a5d47da3SDaniel Pereira******************
168*a5d47da3SDaniel Pereira
169*a5d47da3SDaniel PereiraEm maio de 2006, a pilha de rede "Devicescape" foi, com grande alarde, lançada
170*a5d47da3SDaniel Pereirasob a GPL e disponibilizada para inclusão no kernel mainline. Essa doação foi uma
171*a5d47da3SDaniel Pereiranotícia bem-vinda; o suporte para redes sem fio no Linux era considerado abaixo do
172*a5d47da3SDaniel Pereirapadrão, na melhor das hipóteses, e a pilha da Devicescape oferecia a promessa de
173*a5d47da3SDaniel Pereiracorrigir essa situação. No entanto, esse código só entrou de fato no mainline em
174*a5d47da3SDaniel Pereirajunho de 2007 (2.6.22). O que aconteceu?
175*a5d47da3SDaniel Pereira
176*a5d47da3SDaniel PereiraEsse código mostrava vários sinais de ter sido desenvolvido a portas fechadas em
177*a5d47da3SDaniel Pereiraambiente corporativo. Mas um grande problema em particular era que ele não havia
178*a5d47da3SDaniel Pereirasido projetado para funcionar em sistemas multiprocessados. Antes que essa pilha
179*a5d47da3SDaniel Pereirade rede (agora chamada de mac80211) pudesse ser integrada, um esquema de locking
180*a5d47da3SDaniel Pereira(bloqueio) precisou ser adaptado a ela.
181*a5d47da3SDaniel Pereira
182*a5d47da3SDaniel PereiraEra uma vez uma época em que o código do kernel Linux podia ser desenvolvido sem
183*a5d47da3SDaniel Pereirapensar nos problemas de concorrência apresentados por sistemas multiprocessados.
184*a5d47da3SDaniel PereiraHoje, no entanto, este documento está sendo escrito em um laptop dual-core.
185*a5d47da3SDaniel PereiraMesmo em sistemas com um único processador, o trabalho feito para melhorar a
186*a5d47da3SDaniel Pereiracapacidade de resposta aumentará o nível de concorrência dentro do kernel. Os
187*a5d47da3SDaniel Pereiradias em que o código do kernel podia ser escrito sem pensar em locking ficaram
188*a5d47da3SDaniel Pereirahá muito tempo no passado.
189*a5d47da3SDaniel Pereira
190*a5d47da3SDaniel PereiraQualquer recurso (estruturas de dados, registradores de hardware, etc.) que
191*a5d47da3SDaniel Pereirapossa ser acessado concorrentemente por mais de uma linha de execução deve ser
192*a5d47da3SDaniel Pereiraprotegido por uma trava (lock). O novo código deve ser escrito com esse
193*a5d47da3SDaniel Pereirarequisito em mente; adaptar o locking após o fato é uma tarefa consideravelmente
194*a5d47da3SDaniel Pereiramais difícil. Os desenvolvedores do kernel devem dedicar um tempo para
195*a5d47da3SDaniel Pereiracompreender as primitivas de locking disponíveis bem o suficiente para escolher
196*a5d47da3SDaniel Pereiraa ferramenta certa para o trabalho. Códigos que mostrem falta de atenção à
197*a5d47da3SDaniel Pereiraconcorrência terão um caminho difícil para entrar no mainline.
198*a5d47da3SDaniel Pereira
199*a5d47da3SDaniel Pereira
200*a5d47da3SDaniel PereiraRegressions
201*a5d47da3SDaniel Pereira***********
202*a5d47da3SDaniel Pereira
203*a5d47da3SDaniel PereiraUm perigo final que vale a pena mencionar é este: pode ser tentador fazer uma
204*a5d47da3SDaniel Pereiraalteração (que pode trazer grandes melhorias) que faça algo quebrar para os
205*a5d47da3SDaniel Pereirausuários existentes. Esse tipo de alteração é chamado de "regressão", e as
206*a5d47da3SDaniel Pereiraregressões tornaram-se totalmente indesejadas no kernel mainline. Com poucas
207*a5d47da3SDaniel Pereiraexceções, as alterações que causarem regressões serão revertidas se a regressão
208*a5d47da3SDaniel Pereiranão puder ser corrigida em tempo hábil. É muito melhor evitar a regressão em
209*a5d47da3SDaniel Pereiraprimeiro lugar.
210*a5d47da3SDaniel Pereira
211*a5d47da3SDaniel PereiraMuitas vezes argumenta-se que uma regressão pode ser justificada se ela fizer as
212*a5d47da3SDaniel Pereiracoisas funcionarem para mais pessoas do que os problemas que ela cria. Por que
213*a5d47da3SDaniel Pereiranão fazer uma alteração se ela trouxer uma nova funcionalidade para dez sistemas
214*a5d47da3SDaniel Pereirapara cada um que ela quebrar? A melhor resposta para essa pergunta foi expressa
215*a5d47da3SDaniel Pereirapor Linus em julho de 2007:
216*a5d47da3SDaniel Pereira
217*a5d47da3SDaniel Pereira::
218*a5d47da3SDaniel Pereira
219*a5d47da3SDaniel Pereira  Portanto, nós não corrigimos bugs introduzindo novos problemas. Esse caminho
220*a5d47da3SDaniel Pereira  leva à loucura, e ninguém nunca sabe se você está realmente fazendo algum
221*a5d47da3SDaniel Pereira  progresso real. São dois passos para frente, um passo para trás, ou um passo
222*a5d47da3SDaniel Pereira  para frente e dois passos para trás?
223*a5d47da3SDaniel Pereira
224*a5d47da3SDaniel Pereira(https://lwn.net/Articles/243460/).
225*a5d47da3SDaniel Pereira
226*a5d47da3SDaniel PereiraUm tipo de regressão especialmente indesejado é qualquer tipo de alteração na
227*a5d47da3SDaniel PereiraABI do espaço do usuário (user-space ABI). Uma vez que uma interface tenha sido
228*a5d47da3SDaniel Pereiraexportada para o espaço do usuário, ela deve receber suporte indefinidamente.
229*a5d47da3SDaniel PereiraEsse fato torna a criação de interfaces de espaço do usuário particularmente
230*a5d47da3SDaniel Pereiradesafiadora: já que elas não podem ser alteradas de maneiras incompatíveis, elas
231*a5d47da3SDaniel Pereiradevem ser feitas corretamente na primeira vez. Por essa razão, exige-se sempre
232*a5d47da3SDaniel Pereiramuita reflexão, documentação clara e uma ampla revisão para as interfaces do
233*a5d47da3SDaniel Pereiraespaço do usuário.
234*a5d47da3SDaniel Pereira
235*a5d47da3SDaniel Pereira
236*a5d47da3SDaniel PereiraFerramentas de verificação de código
237*a5d47da3SDaniel Pereira------------------------------------
238*a5d47da3SDaniel Pereira
239*a5d47da3SDaniel PereiraPor enquanto, pelo menos, a escrita de código livre de erros continua sendo um
240*a5d47da3SDaniel Pereiraideal que poucos de nós conseguem alcançar. O que podemos esperar fazer, no
241*a5d47da3SDaniel Pereiraentanto, é capturar e corrigir o máximo possível desses erros antes que nosso
242*a5d47da3SDaniel Pereiracódigo entre no kernel mainline. Para esse fim, os desenvolvedores do kernel
243*a5d47da3SDaniel Pereirareuniram um conjunto impressionante de ferramentas que podem capturar uma ampla
244*a5d47da3SDaniel Pereiravariedade de problemas obscuros de forma automatizada. Qualquer problema
245*a5d47da3SDaniel Pereiracapturado pelo computador é um problema que não afligirá um usuário mais tarde,
246*a5d47da3SDaniel Pereiraportanto, é lógico que as ferramentas automatizadas devem ser usadas sempre que
247*a5d47da3SDaniel Pereirapossível.
248*a5d47da3SDaniel Pereira
249*a5d47da3SDaniel PereiraO primeiro passo é simplesmente prestar atenção aos avisos (warnings) produzidos
250*a5d47da3SDaniel Pereiracom o compilador. As versões contemporâneas do gcc podem detectar (e alertar
251*a5d47da3SDaniel Pereirasobre) um grande número de erros potenciais. Com bastante frequência, esses
252*a5d47da3SDaniel Pereiraavisos apontam para problemas reais. O código enviado para revisão deve, como
253*a5d47da3SDaniel Pereiraregra, não produzir nenhum aviso do compilador. Ao silenciar os avisos, tome o
254*a5d47da3SDaniel Pereiracuidado de entender a real causa e tente evitar "correções" que façam o aviso
255*a5d47da3SDaniel Pereiradesaparecer sem resolver a sua origem.
256*a5d47da3SDaniel Pereira
257*a5d47da3SDaniel PereiraNote que nem todos os avisos do compilador ficam ativados por padrão. Compile o
258*a5d47da3SDaniel Pereirakernel com "make KCFLAGS=-W" para obter o conjunto completo.
259*a5d47da3SDaniel Pereira
260*a5d47da3SDaniel PereiraO kernel fornece várias opções de configuração que ativam recursos de
261*a5d47da3SDaniel Pereiradepuração; a maioria delas é encontrada no submanu "kernel hacking". Várias
262*a5d47da3SDaniel Pereiradessas opções devem ser ativadas para qualquer kernel usado para fins de
263*a5d47da3SDaniel Pereiradesenvolvimento ou teste. Em particular, você deve ativar:
264*a5d47da3SDaniel Pereira
265*a5d47da3SDaniel Pereira - FRAME_WARN para obter avisos sobre quadros de pilha (stack frames) maiores
266*a5d47da3SDaniel Pereira   que um determinado valor. A saída gerada pode ser volumosa, mas não é
267*a5d47da3SDaniel Pereira   necessário se preocupar com os avisos de outras partes do kernel.
268*a5d47da3SDaniel Pereira
269*a5d47da3SDaniel Pereira - DEBUG_OBJECTS adicionará código para rastrear o tempo de vida de vários
270*a5d47da3SDaniel Pereira   objetos criados pelo kernel e alertará quando as ações forem feitas fora de
271*a5d47da3SDaniel Pereira   ordem. Se você estiver adicionando um subsistema que cria (e exporta) seus
272*a5d47da3SDaniel Pereira   próprios objetos complexos, considere adicionar suporte à infraestrutura de
273*a5d47da3SDaniel Pereira   depuração de objetos.
274*a5d47da3SDaniel Pereira
275*a5d47da3SDaniel Pereira - DEBUG_SLAB pode encontrar uma variedade de erros de alocação e uso de
276*a5d47da3SDaniel Pereira   memória; ele deve ser usado na maioria dos kernels de desenvolvimento.
277*a5d47da3SDaniel Pereira
278*a5d47da3SDaniel Pereira - DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP e DEBUG_MUTEXES encontrarão uma série de
279*a5d47da3SDaniel Pereira   erros comuns de locking (bloqueio).
280*a5d47da3SDaniel Pereira
281*a5d47da3SDaniel PereiraExistem várias outras opções de depuração, algumas das quais serão discutidas
282*a5d47da3SDaniel Pereiraabaixo. Algumas delas têm um impacto significativo no desempenho e não devem ser
283*a5d47da3SDaniel Pereirausadas o tempo todo. Mas um tempo gasto aprendendo as opções disponíveis
284*a5d47da3SDaniel Pereiraprovavelmente se pagará muitas vezes em pouco tempo.
285*a5d47da3SDaniel Pereira
286*a5d47da3SDaniel PereiraUma das ferramentas de depuração mais pesadas é o verificador de locking, ou
287*a5d47da3SDaniel Pereira"lockdep". Esta ferramenta rastreará a aquisição e a liberação de cada trava
288*a5d47da3SDaniel Pereira(spinlock ou mutex) no sistema, a ordem em que as travas são adquiridas umas em
289*a5d47da3SDaniel Pereirarelação às outras, o ambiente de interrupção atual e muito mais. Ela pode,
290*a5d47da3SDaniel Pereiraentão, garantir que as travas sejam sempre adquiridas na mesma ordem, que as
291*a5d47da3SDaniel Pereiramesmas suposições de interrupção se apliquem em todas as situações e assim por
292*a5d47da3SDaniel Pereiradiante. Em outras palavras, o lockdep pode encontrar uma série de cenários nos
293*a5d47da3SDaniel Pereiraquais o sistema poderia, em raras ocasiões, entrar em deadlock. Esse tipo de
294*a5d47da3SDaniel Pereiraproblema pode ser doloroso (tanto para desenvolvedores quanto para usuários) em
295*a5d47da3SDaniel Pereiraum sistema implantado; o lockdep permite que eles sejam encontrados de maneira
296*a5d47da3SDaniel Pereiraautomatizada e antecipada. Códigos com qualquer tipo de locking não trivial
297*a5d47da3SDaniel Pereiradevem ser executados com o lockdep ativado antes de serem enviados para inclusão.
298*a5d47da3SDaniel Pereira
299*a5d47da3SDaniel PereiraComo um programador de kernel diligente, você irá, sem dúvida, verificar o
300*a5d47da3SDaniel Pereirastatus de retorno de qualquer operação (como uma alocação de memória) que possa
301*a5d47da3SDaniel Pereirafalhar. O fato, porém, é que os caminhos de recuperação de falha resultantes
302*a5d47da3SDaniel Pereiraestão, provavelmente, completamente não testados. Código não testado tende a ser
303*a5d47da3SDaniel Pereiracódigo quebrado; você poderia estar muito mais confiante em seu código se todos
304*a5d47da3SDaniel Pereiraesses caminhos de tratamento de erros tivessem sido exercitados algumas vezes.
305*a5d47da3SDaniel Pereira
306*a5d47da3SDaniel PereiraO kernel fornece um framework de injeção de falhas (fault injection) que pode
307*a5d47da3SDaniel Pereirafazer exatamente isso, especialmente onde alocações de memória estão
308*a5d47da3SDaniel Pereiraenvolvidas. Com a injeção de falhas ativada, uma porcentagem configurável das
309*a5d47da3SDaniel Pereiraalocações de memória será forçada a falhar; essas falhas podem ser restritas a
310*a5d47da3SDaniel Pereiraum intervalo específico de código. Executar o código com a injeção de falhas
311*a5d47da3SDaniel Pereiraativada permite ao programador ver como o código responde quando as coisas vão
312*a5d47da3SDaniel Pereiramal. Veja Documentation/fault-injection/fault-injection.rst para mais
313*a5d47da3SDaniel Pereirainformações sobre como usar esse recurso.
314*a5d47da3SDaniel Pereira
315*a5d47da3SDaniel PereiraOutros tipos de erros podem ser encontrados com a ferramenta de análise estática
316*a5d47da3SDaniel Pereira"sparse". Com o sparse, o programador pode ser alertado sobre confusões entre
317*a5d47da3SDaniel Pereiraendereços do espaço do usuário e do espaço do kernel, mistura de quantidades
318*a5d47da3SDaniel Pereirabig-endian e small-endian, a passagem de valores inteiros onde um conjunto de
319*a5d47da3SDaniel Pereirasinalizadores de bits (bit flags) é esperado, e assim por diante. O sparse deve
320*a5d47da3SDaniel Pereiraser instalado separadamente (ele pode ser encontrado em
321*a5d47da3SDaniel Pereirahttps://sparse.wiki.kernel.org/index.php/Main_Page se a sua distribuição não o
322*a5d47da3SDaniel Pereiraincluir como pacote); ele pode então ser executado no código adicionando "C=1"
323*a5d47da3SDaniel Pereiraao seu comando make.
324*a5d47da3SDaniel Pereira
325*a5d47da3SDaniel PereiraA ferramenta "Coccinelle" (http://coccinelle.lip6.fr/) é capaz de encontrar uma
326*a5d47da3SDaniel Pereiraampla variedade de potenciais problemas de codificação; ela também pode propor
327*a5d47da3SDaniel Pereiracorreções para esses problemas. Uma quantidade considerável de "patches
328*a5d47da3SDaniel Pereirasemânticos" para o kernel foi empacotada sob o diretório scripts/coccinelle;
329*a5d47da3SDaniel Pereiraexecutar "make coccicheck" passará por esses patches semânticos e relatará
330*a5d47da3SDaniel Pereiraquaisquer problemas encontrados. Veja
331*a5d47da3SDaniel Pereira:ref:`Documentation/dev-tools/coccinelle.rst <devtools_coccinelle>`
332*a5d47da3SDaniel Pereirapara mais informações.
333*a5d47da3SDaniel Pereira
334*a5d47da3SDaniel PereiraOutros tipos de erros de portabilidade são encontrados mais facilmente ao
335*a5d47da3SDaniel Pereiracompilar seu código para outras arquiteturas. Se você por acaso não tiver um
336*a5d47da3SDaniel Pereirasistema S/390 ou uma placa de desenvolvimento Blackfin à mão, ainda assim poderá
337*a5d47da3SDaniel Pereirarealizar a etapa de compilação. Um grande conjunto de compiladores cruzados
338*a5d47da3SDaniel Pereira(cross-compilers) para sistemas x86 pode ser encontrado em:
339*a5d47da3SDaniel Pereira
340*a5d47da3SDaniel Pereira  https://www.kernel.org/pub/tools/crosstool/
341*a5d47da3SDaniel Pereira
342*a5d47da3SDaniel PereiraUm tempo gasto instalando e usando esses compiladores ajudará a evitar
343*a5d47da3SDaniel Pereiraconstrangimentos mais tarde.
344*a5d47da3SDaniel Pereira
345*a5d47da3SDaniel Pereira
346*a5d47da3SDaniel PereiraDocumentação
347*a5d47da3SDaniel Pereira-------------
348*a5d47da3SDaniel Pereira
349*a5d47da3SDaniel PereiraA documentação frequentemente tem sido mais a exceção do que a regra no
350*a5d47da3SDaniel Pereiradesenvolvimento do kernel. Mesmo assim, uma documentação adequada ajudará a
351*a5d47da3SDaniel Pereirafacilitar a integração de novos códigos ao kernel, tornará a vida mais fácil para
352*a5d47da3SDaniel Pereiraoutros desenvolvedores e será útil para os seus usuários. Em muitos casos, a
353*a5d47da3SDaniel Pereiraadição de documentação tornou-se essencialmente obrigatória.
354*a5d47da3SDaniel Pereira
355*a5d47da3SDaniel PereiraA primeira parte da documentação de qualquer patch é o seu log de alterações
356*a5d47da3SDaniel Pereira(changelog) associado. As entradas do log devem descrever o problema que está
357*a5d47da3SDaniel Pereirasendo resolvido, a forma da solução, as pessoas que trabalharam no patch,
358*a5d47da3SDaniel Pereiraquaisquer efeitos relevantes no desempenho e qualquer outra coisa que possa ser
359*a5d47da3SDaniel Pereiranecessária para entender o patch. Certifique-se de que o changelog diga o
360*a5d47da3SDaniel Pereira*porquê* de o patch valer a pena ser aplicado; um número surpreendente de
361*a5d47da3SDaniel Pereiradesenvolvedores falha em fornecer essa informação.
362*a5d47da3SDaniel Pereira
363*a5d47da3SDaniel PereiraQualquer código que adicione uma nova interface de espaço do usuário — incluindo
364*a5d47da3SDaniel Pereiranovos arquivos sysfs ou /proc — deve incluir a documentação dessa interface, de
365*a5d47da3SDaniel Pereiramodo a permitir que os desenvolvedores do espaço do usuário saibam com o que
366*a5d47da3SDaniel Pereiraestão trabalhando. Veja Documentation/ABI/README para uma descrição de como essa
367*a5d47da3SDaniel Pereiradocumentação deve ser formatada e quais informações precisam ser fornecidas.
368*a5d47da3SDaniel Pereira
369*a5d47da3SDaniel PereiraO arquivo :ref:`Documentation/admin-guide/kernel-parameters.rst
370*a5d47da3SDaniel Pereira<kernelparameters>` descreve todos os parâmetros de boot do kernel. Qualquer
371*a5d47da3SDaniel Pereirapatch que adicione novos parâmetros deve adicionar as entradas apropriadas a
372*a5d47da3SDaniel Pereiraeste arquivo.
373*a5d47da3SDaniel Pereira
374*a5d47da3SDaniel PereiraQuaisquer novas opções de configuração devem ser acompanhadas por um texto de
375*a5d47da3SDaniel Pereiraajuda que explique claramente as opções e quando o usuário pode querer
376*a5d47da3SDaniel Pereiraselecioná-las.
377*a5d47da3SDaniel Pereira
378*a5d47da3SDaniel PereiraAs informações de API interna de muitos subsistemas são documentadas por meio de
379*a5d47da3SDaniel Pereiracomentários com formatação especial; esses comentários podem ser extraídos e
380*a5d47da3SDaniel Pereiraformatados de várias maneiras pelo script "kernel-doc". Se você estiver
381*a5d47da3SDaniel Pereiratrabalhando em um subsistema que possui comentários kerneldoc, você deve
382*a5d47da3SDaniel Pereiramantê-los e adicioná-los, conforme apropriado, para funções disponíveis
383*a5d47da3SDaniel Pereiraexternamente. Mesmo em áreas que não tenham sido documentadas dessa forma, não há
384*a5d47da3SDaniel Pereiramal nenhum em adicionar comentários kerneldoc para o futuro; de fato, esta pode
385*a5d47da3SDaniel Pereiraser uma atividade útil para desenvolvedores iniciantes de kernel. O formato
386*a5d47da3SDaniel Pereiradesses comentários, junto com algumas informações sobre como criar modelos de
387*a5d47da3SDaniel Pereirakerneldoc, pode ser encontrado em :ref:`Documentation/doc-guide/ <doc_guide>`.
388*a5d47da3SDaniel Pereira
389*a5d47da3SDaniel PereiraQualquer pessoa que leia uma quantidade significativa de código existente do
390*a5d47da3SDaniel Pereirakernel notará que, frequentemente, os comentários chamam a atenção por sua
391*a5d47da3SDaniel Pereiraausência. Mais uma vez, as expectativas para códigos novos são mais altas do que
392*a5d47da3SDaniel Pereiraeram no passado; integrar código sem comentários será mais difícil. Dito isso,
393*a5d47da3SDaniel Pereirahá pouco interesse em códigos comentados de forma prolixa. O código deve, por si
394*a5d47da3SDaniel Pereirasó, ser legível, com os comentários explicando os aspectos mais sutis.
395*a5d47da3SDaniel Pereira
396*a5d47da3SDaniel PereiraCertas coisas devem sempre ser comentadas. O uso de barreiras de memória
397*a5d47da3SDaniel Pereira(memory barriers) deve ser acompanhado por uma linha explicando por que a
398*a5d47da3SDaniel Pereirabarreira é necessária. As regras de locking (bloqueio) para estruturas de dados
399*a5d47da3SDaniel Pereirageralmente precisam ser explicadas em algum lugar. Grandes estruturas de dados
400*a5d47da3SDaniel Pereiraprecisam de uma documentação abrangente em geral. Dependências não óbvias entre
401*a5d47da3SDaniel Pereiratrechos distintos de código devem ser apontadas. Qualquer coisa que possa tentar
402*a5d47da3SDaniel Pereiraum "faxineiro de código" (code janitor) a fazer uma "limpeza" incorreta precisa
403*a5d47da3SDaniel Pereirade um comentário dizendo por que foi feita daquela maneira. E assim por diante.
404*a5d47da3SDaniel Pereira
405*a5d47da3SDaniel Pereira
406*a5d47da3SDaniel PereiraAlterações de API interna
407*a5d47da3SDaniel Pereira-------------------------
408*a5d47da3SDaniel Pereira
409*a5d47da3SDaniel PereiraA interface binária fornecida pelo kernel para o espaço do usuário não pode ser
410*a5d47da3SDaniel Pereiraquebrada, exceto sob as circunstâncias mais graves. Por outro lado, as
411*a5d47da3SDaniel Pereirainterfaces de programação internas do kernel são altamente fluidas e podem ser
412*a5d47da3SDaniel Pereiraalteradas quando surgir a necessidade. Se você se encontrar tendo que criar uma
413*a5d47da3SDaniel Pereiragambiarra para contornar uma API do kernel, ou simplesmente deixando de usar uma
414*a5d47da3SDaniel Pereirafuncionalidade específica porque ela não atende às suas necessidades, isso pode
415*a5d47da3SDaniel Pereiraser um sinal de que a API precisa mudar. Como desenvolvedor de kernel, você tem
416*a5d47da3SDaniel Pereirao poder de fazer tais alterações.
417*a5d47da3SDaniel Pereira
418*a5d47da3SDaniel PereiraExistem, é claro, algumas pegadinhas. Alterações de API podem ser feitas, mas
419*a5d47da3SDaniel Pereiraprecisam ser bem justificadas. Portanto, qualquer patch que faça uma alteração de
420*a5d47da3SDaniel PereiraAPI interna deve ser acompanhado por uma descrição do que é a mudança e do porquê
421*a5d47da3SDaniel Pereiraela é necessária. Esse tipo de alteração também deve ser separado em um patch
422*a5d47da3SDaniel Pereiraindependente, em vez de ser enterrado dentro de um patch maior.
423*a5d47da3SDaniel Pereira
424*a5d47da3SDaniel PereiraA outra pegadinha é que o desenvolvedor que altera uma API interna é geralmente
425*a5d47da3SDaniel Pereiraencarregado da tarefa de corrigir qualquer código dentro da árvore do kernel que
426*a5d47da3SDaniel Pereiratenha sido quebrado pela mudança. Para uma função amplamente utilizada, esse
427*a5d47da3SDaniel Pereiradever pode levar a literalmente centenas ou milhares de alterações — muitas das
428*a5d47da3SDaniel Pereiraquais provavelmente entrarão em conflito com o trabalho que está sendo feito por
429*a5d47da3SDaniel Pereiraoutros desenvolvedores. Desnecessário dizer que isso pode ser um grande
430*a5d47da3SDaniel Pereiratrabalho, então é melhor ter certeza de que a justificativa é sólida. Note que
431*a5d47da3SDaniel Pereiraa ferramenta Coccinelle pode ajudar com alterações de API de amplo alcance.
432*a5d47da3SDaniel Pereira
433*a5d47da3SDaniel PereiraAo fazer uma alteração incompatível de API, deve-se, sempre que possível,
434*a5d47da3SDaniel Pereiragarantir que o código que não foi atualizado seja capturado pelo compilador.
435*a5d47da3SDaniel PereiraIsso ajudará você a ter certeza de que encontrou todos os usos dessa interface
436*a5d47da3SDaniel Pereiradentro da árvore (in-tree). Isso também alertará os desenvolvedores de códigos
437*a5d47da3SDaniel Pereirafora da árvore (out-of-tree) de que há uma mudança à qual eles precisam
438*a5d47da3SDaniel Pereiraresponder. Dar suporte a código fora da árvore não é algo com que os
439*a5d47da3SDaniel Pereiradesenvolvedores do kernel precisem se preocupar, mas também não temos que
440*a5d47da3SDaniel Pereiratornar a vida dos desenvolvedores fora da árvore mais difícil do que precisa ser.
441