Capítulo 17. Tópicos Avançados

17.1. Como posso aprender mais sobre os componentes internos do FreeBSD?
17.2. Como posso contribuir para o FreeBSD? O que posso fazer para ajudar?
17.3. O que são Snapshots e Releases?
17.4. Como posso aproveitar ao máximo os dados que vejo quando meu kernel entra em panic?
17.5. Por que dlsym() parou de funcionar para executáveis ​​ELF?
17.6. Como posso aumentar ou reduzir o espaço de endereçamento do kernel em uma máquina i386?

17.1.

Como posso aprender mais sobre os componentes internos do FreeBSD?

Veja o Handbook de Arquitetura do FreeBSD .

Além disso, muito do conhecimento geral sobre o UNIX® é diretamente aplicável ao FreeBSD.

17.2.

Como posso contribuir para o FreeBSD? O que posso fazer para ajudar?

Nós aceitamos todos os tipos de contribuições: documentação, código e até mesmo arte. Veja o artigo Contribuindo com o FreeBSD para obter maiores informações sobre como fazer isso.

E obrigado por considerar nos ajudar!

17.3.

O que são Snapshots e Releases?

Atualmente existem 3 branches ativas/semi-ativas no Repositório Subversion do FreeBSD. (Os branches anteriores são alterados muito raramente, e é por isso que existem apenas 3 branches ativas de desenvolvimento):

  • stable/11/ AKA 11-STABLE

  • stable/12/ AKA 12-STABLE

  • head/ AKA -CURRENT AKA 13-CURRENT

HEAD não é uma tag de branch real. É uma constante simbólica para o fluxo de desenvolvimento atual, não ramificado, conhecido como -CURRENT.

No momento, o -CURRENT é o fluxo de desenvolvimento 13.X; o branch 12-STABLE, stable/12/, derivou do -CURRENT em Dezembro de 2018 e o branch ​​11-STABLE,stable/11/, derivou do -CURRENT em Outubro de 2016.

17.4.

Como posso aproveitar ao máximo os dados que vejo quando meu kernel entra em panic?

Aqui está um panic típico do kernel:

Fatal trap 12: page fault while in kernel mode
fault virtual address   = 0x40
fault code              = supervisor read, page not present
instruction pointer     = 0x8:0xf014a7e5
stack pointer           = 0x10:0xf4ed6f24
frame pointer           = 0x10:0xf4ed6f28
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, def32 1, gran 1
processor eflags        = interrupt enabled, resume, IOPL = 0
current process         = 80 (mount)
interrupt mask          =
trap number             = 12
panic: page fault

Esta mensagem não é suficiente. Embora o valor do ponteiro de instrução seja importante, ele também depende da configuração, pois varia dependendo da imagem do kernel. Se for uma imagem de kernel GENERIC de um dos snapshots, é possível que alguém rastreie a função problemática, mas para um kernel personalizado, somente você pode nos dizer onde a falha ocorreu.

Para prosseguir:

  1. Anote o valor do ponteiro de instrução. Note que a parte 0x8: no começo não é relevante neste caso: é a parte 0xf0xxxxxx que nós queremos.

  2. Quando o sistema for reinicializado, faça o seguinte:

    % nm -n kernel.that.caused.the.panic | grep f0xxxxxx

    no qual f0xxxxxx é o valor do ponteiro de instrução. As probabilidades são de que você não obterá uma correspondência exata, pois os símbolos na tabela de símbolos do kernel são para os pontos de entrada das funções e o endereço do ponteiro de instrução estará em algum lugar dentro de uma função, não no início. Se você não obtiver uma correspondência exata, omita o último dígito do valor do ponteiro de instrução e tente novamente:

    % nm -n kernel.that.caused.the.panic | grep f0xxxxx

    Se isso não produzir nenhum resultado, corte outro dígito. Repita até que haja algum tipo de saída. O resultado será uma possível lista das funções que causaram o panic. Este é um mecanismo menos do que exato para rastrear o ponto de falha, mas é melhor do que nada.

No entanto, a melhor maneira de rastrear a causa de um panic é capturar um despejo de memória e usar o kgdb(1) para gerar um rastreamento de pilha no despejo de memória.

Em qualquer caso, o método é este:

  1. Certifique-se de que a seguinte linha esteja incluída no arquivo de configuração do kernel:

    makeoptions     DEBUG=-g          # Build kernel with gdb(1) debug symbols
  2. Mude para o diretório /usr/src:

    # cd /usr/src
  3. Compile o kernel:

    # make buildkernel KERNCONF=MYKERNEL
  4. Aguarde até o make(1) terminar a compilação.

  5. # make installkernel KERNCONF=MYKERNEL
  6. Reinicie.

Nota:

Se a variável KERNCONF não for informada na linha de comando, o kernel GENERIC será compilado e instalado.

O processo make(1) terá compilado dois kernels. O /usr/obj/usr/src/sys/MYKERNEL/kernel e o /usr/obj/usr/src/sys/MYKERNEL/kernel.debug . O kernel foi instalado como /boot/kernel/kernel, enquanto o kernel.debug pode ser usado como fonte de símbolos de depuração para o kgdb(1).

Para capturar um despejo de memória, edite o /etc/rc.conf e defina o dumpdev para apontar para a partição de swap ou para AUTO. Isso fará com que os scripts rc(8) usem o comando dumpon(8) para ativar os despejos de memória. Este comando também pode ser executado manualmente. Após um panic, o despejo de memória pode ser recuperado usando o savecore(8); se o dumpdev estiver configurado em /etc/rc.conf, os scripts rc(8) executarão o savecore(8) automaticamente e colocarão o despejo de memória em /var/crash.

Nota:

Os despejos de memória do FreeBSD são geralmente do mesmo tamanho que a RAM física. Portanto, verifique se há espaço suficiente em /var/crash para manter o despejo. Como alternativa, execute savecore(8) manualmente e faça com que recupere o despejo de memória para outro diretório com mais espaço. É possível limitar o tamanho do despejo de memória usando options MAXMEM=N onde N é o tamanho da memória utilizada do kernel em KBs. Por exemplo, para 1 GB de RAM, limite o uso de memória pelo kernel a 128 MB, para que o tamanho do despejo de memória seja de 128 MB em vez de 1 GB.

Depois que o despejo de memória for recuperado, obtenha um rastreamento de pilha da seguinte maneira:

% kgdb /usr/obj/usr/src/sys/MYKERNEL/kernel.debug /var/crash/vmcore.0
(kgdb) backtrace

Note que pode haver várias telas de informação valiosa. Idealmente, use script(1) para capturar todas elas. Usar a imagem do kernel unstripped com todos os símbolos de depuração deve mostrar a linha exata do código fonte do kernel onde o panic ocorreu. O rastreamento de pilha geralmente é lido de baixo para cima para rastrear a sequência exata de eventos que levam à falha. O kgdb(1) também pode ser usado para imprimir o conteúdo de várias variáveis ​​ou estruturas para examinar o estado do sistema no momento da falha.

Dica:

Se um segundo computador estiver disponível, o kgdb(1) pode ser configurado para fazer uma depuração remota, incluindo pontos de interrupção de configuração e passos únicos através do código do kernel.

Nota:

Se o DDB estiver habilitado e o kernel cair no depurador, um panic e um despejo de memória podem ser forçados digitando panic no prompt do ddb. O processo pode parar no depurador novamente durante a fase de panic. Se isso acontecer, digite continue e ele concluirá o despejo de memória.

17.5.

Por que dlsym() parou de funcionar para executáveis ​​ELF?

A toolchain ELF não faz, por padrão, os símbolos definidos em um executável visíveis para o vinculador dinâmico. Consequentemente, a busca da função dlsym() por identificadores obtidos de chamadas para dlopen(NULL, flags) não conseguirá encontrar tais símbolos.

Para pesquisar, usando a função dlsym(), os símbolos presentes no executável principal de um processo, vincule o executável usando a opção - export-dynamic ao vinculador ELF (ld(1)).

17.6.

Como posso aumentar ou reduzir o espaço de endereçamento do kernel em uma máquina i386?

Por padrão, o espaço de endereço do kernel é de 1 GB (2 GB para PAE) para a arquitetura i386. Se você estiver executando um servidor com uso intensivo de rede ou utilizando o ZFS, isso provavelmente não será suficiente.

Adicione a seguinte linha ao arquivo de configuração do kernel para aumentar o espaço disponível e recompile o kernel:

options KVA_PAGES=N

Para encontrar o valor correto de N, divida o tamanho do espaço de endereço desejado (em megabytes) por quatro. (Por exemplo, é 512 para 2 GB.)

All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.