Debug - Getting Traces (Português)

From ArchWiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Status de tradução: Esse artigo é uma tradução de Debug - Getting Traces. Data da última tradução: 2020-09-14. Você pode ajudar a sincronizar a tradução, se houver alterações na versão em inglês.

Esse artigo visa ajudar na criação de um pacote de depuração do Arch e usá-lo para fornecer informações de rastro e depuração para relatar bugs de software para desenvolvedores.

Normalmente, os arquivos executáveis têm símbolos removidos (strip) de contexto legível por humanos para torná-los menores. Além disso, as informações de depuração aprimoradas geralmente não são adicionadas ao executável em primeiro lugar, o que reduz drasticamente a qualidade do rastreamento. Portanto, antes de obter rastreamentos com informações de depuração, é necessário recompilar o pacote sem remover e com informações de depuração.

Nomes de pacotes

A primeira coisa a fazer é obter os nomes dos pacotes que precisam ser recompilados.

Ao procurar por mensagens de depuração, como, por exemplo, usando gdb em um despejo de núcleo:

[...]
Backtrace was generated from '/usr/bin/epiphany'

(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".
(no debugging symbols found)
[Thread debugging using libthread_db enabled]
[New Thread -1241265952 (LWP 12630)]
(no debugging symbols found)
0xb7f25410 in __kernel_vsyscall ()
#0  0xb7f25410 in __kernel_vsyscall ()
#1  0xb741b45b in ?? () from /lib/libpthread.so.0
[...]

?? mostra onde a informação de depuração está faltando, assim como o nome da biblioteca ou executável que chamou a função. Similarmente, quando (no debugging symbols found) aparece, você deve procurar pelos nomes de arquivos mencionados. Por exemplo, com pacman:

$ pacman -Qo /lib/libthread_db.so.1
/lib/libthread_db.so.1 pertence a glibc 2.5-8

O pacote é chamado glibc na versão 2.5-8. Repita essa etapa para todo pacote que precisa de depuração.

PKGBUILD

Para compilar um pacote a partir do fonte, o arquivo PKGBUILD file é necessário. Veja ABS (Português) para pacotes nos repositórios oficiais, e AUR (Português)#Obtendo arquivos de compilação para pacotes no AUR.

Configurações de compilação

Neste estágio, você pode modificar o arquivo de configuração global do makepkg se você for usá-lo apenas para propósito de depuração. Nos demais casos, você deve modificar o arquivo PKGBUILD do pacote apenas para cada pacote que você gostaria de recompilar.

Geral

Desde o pacman 4.1, /etc/makepkg.conf possui flags de depuração de compilação em DEBUG_CFLAGS e DEBUG_CXXFLAGS. Para usá-las, habilite a opção do makepkg debug e desabilite strip.

OPTIONS+=(debug !strip)

Estas configurações vão forçar a compilação com símbolos de depuração e vai desabilitar a remoção deles dos executáveis. Para aplicar essa configuração a um único pacote, modifique o PKGBUILD:

options=(debug !strip)

Alternativamente, você pode colocar as informações de depuração em um pacote separado habilitando debug e strip, símbolos de depuração serão então removidos do pacote principal e colocados, junto com seus arquivos fontes para ajudar a analisá-los no depurador, em um pacote separado foo-debug.

Nota: Não é suficiente só instalar o pacote de depuração de recentemente compilado, porque o depurador vai conferir se o arquivo contendo os símbolos de depuração é o da mesma compilação que a biblioteca e executável associados. Você deve instalar os pacotes recompilados. No Arch, os arquivos de símbolo de depuração são instalados sob /usr/lib/debug e os arquivos fontes são instalados sob /usr/src/debug. Veja a documentação do GDB para mais informações sobre os pacotes de depuração.

Note que certos pacotes como glibc são removidos. Verifique o PKGBUILD para seções como:

strip $STRIP_BINARIES usr/bin/{gencat,getconf,getent,iconv,iconvconfig} \
                      usr/bin/{ldconfig,locale,localedef,nscd,makedb} \
                      usr/bin/{pcprofiledump,pldd,rpcgen,sln,sprof} \
                      usr/lib/getconf/*

strip $STRIP_STATIC usr/lib/*.a

strip $STRIP_SHARED usr/lib/{libanl,libBrokenLocale,libcidn,libcrypt}-*.so \
                    usr/lib/libnss_{compat,db,dns,files,hesiod,nis,nisplus}-*.so \
                    usr/lib/{libdl,libm,libnsl,libresolv,librt,libutil}-*.so \
                    usr/lib/{libmemusage,libpcprofile,libSegFault}.so \
                    usr/lib/{audit,gconv}/*.so

E, então, remova onde apropriado.

GTK3/GLib2

O repositório do eschwartz contém pacotes GTK3 e GLib2 com pacotes de símbolo de depuração desanexada.

Qt4

Além das configurações gerais anteriores, passe a opção -developer-build para o script configure no PKGBUILD. Por padrão, -developer-build passa -Werror para o compilador, o que pode fazer com que a compilação falhe. Para evitar erros de compilação, você pode precisar passar -no-warnings-are-errors também.

Qt5

O repositório qt-debug contém pacotes Qt/PyQt pré-compilados com símbolos de depuração. Veja também as instruções do upstream.

O repositório eschwartz contém pacotes pré-compilados de qt5-base e pyqt5 com pacotes de símbolo de depuração desanexados.

Aplicativos CMAKE (KDE)

KDE e programas relacionados geralmente usam cmake. Para habilitar informações de depuração e desabilitar otimização, altere -DCMAKE_BUILD_TYPE para Debug, para que os aplicativos KDE alterem isso para debugfull. Para habilitar informações de depuração enquanto mantém as otimizações habilitadas, altere -DCMAKE_BUILD_TYPE para RelWithDebInfo.

dhcpcd

Lembre-se de passar o sinalizador --debug para o script configure ao compilar dhcpcd.

Compilando e instalando o pacote

Compile o pacote a partir do fonte usando makepkg no diretório do PKGBUILD. Isso pode levar algum tempo:

$ makepkg

Então, instale o pacote compilado:

# pacman -U glibc-2.26-1-x86_64.pkg.tar.gz

Obtendo o rastro

O backtrace real (ou rastro de pilha) pode agora ser obtido por meio de, p.ex. gdb, o GNU Debugger. Execute-o através de:

# gdb /caminho/para/arquivo

ou:

# gdb
(gdb) exec /caminho/para/arquivo

O caminho é opcional, se já definido na variável $PATH.

Então, dentro do gdb, digite run seguido por quaisquer argumentos que você deseje que o programa inicie com, p.ex.:

(gdb) run --no-daemon --verbose

para iniciar a execução do arquivo. Faça o que for necessário para evocar o erro. Para registrar log, digite as linhas:

(gdb) set logging file rastro.log
(gdb) set logging on

e então:

(gdb) thread apply all bt full

para emitir o rastro para rastro.log no diretório no qual gdb foi iniciado. Para sair, digite:

(gdb) set logging off
(gdb) quit
Dica: Para depurar um aplicativo escrito em python:
# gdb /usr/bin/python
(gdb) run <aplicativo em python>

Você também pode depurar um aplicativo em execução, p.ex.:

 # gdb --pid=$(pidof firefox)
 (gdb) continue

Para depurar um aplicativo que já travou, você vai querer usar o gdb despejo de núcleo.

Conclusão

Use o rastro de pilha completo para informar os desenvolvedores de um erro que você descobriu. Isso será muito apreciado por eles e ajudará a melhorar o seu programa favorito

Veja também