Resposta curta: pyrasite

pip install pyrasite
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
pyrasite $PID dump_stacks.py
pyrasite-shell <pid>
Utilizando pyrasite para injetar código num console Python

Utilizando pyrasite para injetar código num console Python

Contexto Link to heading

Esses dias estava com um bug intermitente que só ocorria no servidor de desenvolvimento, então não estava conseguindo reproduzir localmente.

Tentando descobrir o problema, dei SSH para o servidor e vi que num processo estava justamente acontecendo o que eu queria corrigir.

Então comecei a tentar debugar o código que já estava em execução, sem ter que recomeçar o processo, pois se fizesse isso provavelmente o bug não iria ocorrer.

Foi assim que descobri o pyrasite e como debugar um processo Python que já está em execução.

Pyrasite Link to heading

Com o pyrasite conseguimos injetar código em um processo Python e debugar em tempo de execução.

Fonte: http://pyrasite.com/

Instalação Link to heading

pip install pyrasite

Habilitar o trace Link to heading

No Linux, por uma questão de segurança, o trace é desabilitado por padrão. Então temos que habilitar para conseguir debugar com o pyrasite.

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

Recomendo voltar o ptrace_scope para o valor padrão (1) após o debug.

Mais informações sobre o ptrace_scope na documentação do Kernel.

Utilização Link to heading

Para utilizar o pyrasite chamamos com o ID do Processo (PID) e o script que queremos executar:

pyrasite $PID my_script.py

A ferramenta já vem com alguns scripts prontos para injetar no processo, são eles:

Além desses, também temos reverse_python_shell.py, reverse_shell.py, start_callgraph.py, stop_callgraph.py, mas esses eu não consegui usar e não fui muito a fundo.

Para, por exemplo, utilizar o dump_stacks.py, rodamos:

pyrasite $PID dump_stacks.py

Shell Link to heading

Além de executar scripts, também podemos habilitar um shell Python para depurar o que está acontecendo na aplicação. Com o shell conseguimos rodar comandos, acessar variáveis e tudo mais que fazemos num console Python

pyrasite-shell $PID

Troubleshooting Link to heading

  1. Rodei o pyrasite e não apareceu nenhum resultado
    • O output do código injetado aparecerá no stdout do processo principal que está recebendo a injeção. Se o seu processo redireciona o stdout para um arquivo, a saída do código injetado também irá para o mesmo arquivo.