Pergunta

Estou tentando despejar uma lista de todos os tópicos ativos, incluindo a pilha atual de cada um. Eu posso obter uma lista de todos os threads usando Threading.enumerate (), mas não consigo descobrir uma maneira de chegar à pilha a partir daí.

Antecedentes: Um aplicativo Zope/Plone surge de tempos em tempos, consumindo 100% da CPU e precisa ser reiniciado. Tenho a sensação de que é um loop que não termina corretamente, mas não posso reproduzi-lo no teste de teste para verificação. Consegui registrar um manipulador de sinal que pode ser acionado por fora, para que eu possa acionar algum código assim que a situação ocorrer novamente. Se eu pudesse despejar o Stacktrace para todos os threads ativos, isso me daria uma pista do que dá errado. A coisa do buraco é executada no Python 2.4 ...

Qualquer idéia sobre como rastrear situações como essas são apreciadas :)

Saúde, Chriss

Foi útil?

Solução

Ao usar o Zope, você deseja instalar Products.signalstack ou Sr. Freeze; Estes foram projetados para esse fim!

Envie um sinal USR1 para o seu servidor Zope e ele despejará imediatamente traços de pilha para todos os threads no console. Fará isso mesmo que todos os threads zope estejam trancados.

Sob o capô, esses pacotes usam indiretamente threadframes; para versões python 2.5 ou mais, quando não Usando zope, você pode construir a mesma funcionalidade usando o sys._current_frames() função para acessar os quadros de pilha por thread.

AS Zope 2.12.5 Essa funcionalidade é integrada ao próprio Zope e não há mais necessidade de instalar pacotes adicionais.

Outras dicas

Como Jitter aponta em uma resposta anterior sys._current_frames() Dá o que você precisa para v2.5+. Para os preguiçosos, o snippet de código a seguir funcionou para mim e pode ajudá -lo:

print >> sys.stderr, "\n*** STACKTRACE - START ***\n"
code = []
for threadId, stack in sys._current_frames().items():
    code.append("\n# ThreadID: %s" % threadId)
    for filename, lineno, name, line in traceback.extract_stack(stack):
        code.append('File: "%s", line %d, in %s' % (filename,
                                                    lineno, name))
        if line:
            code.append("  %s" % (line.strip()))

for line in code:
    print >> sys.stderr, line
print >> sys.stderr, "\n*** STACKTRACE - END ***\n"

Para Python 3.3 e mais tarde, existe faulthandler.dump_traceback().

O código abaixo produz saída semelhante, mas inclui o nome do thread e pode ser aprimorado para imprimir mais informações.

for th in threading.enumerate():
    print(th)
    traceback.print_stack(sys._current_frames()[th.ident])
    print()

2.4. Que pena. Do Python 2.5, existe sys._current_frames().

Mas você poderia tentar quadro de thread. E se o makefile lhe causar problemas, você poderá tentar isso setup.py para quadro de thread

Saída de amostra ao usar o quadro de threadfra

Apenas por uma questão de completude, Product.LonGrequestLogger é super útil para identificar gargalos e, para fazer isso, despeja tracas de empilhamento em intervalos específicos.

Existe uma receita aplicável em Aspn. Você pode usar threading.enumerate() Para obter todas as marés, basta ligar para _async_raise () com alguma exceção adequada para forçar um rastreamento de pilha.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top