Obtendo o ponteiro para a parte inferior da pilha de chamadas e resolvendo símbolo por endereço (como DLADDR) no Windows?
Pergunta
Quero implementar um análogo do utilitário backtrace no Windows para adicionar essas informações à exceção, por exemplo.
Preciso capturar endereços de retorno e depois traduzi -lo em nomes de símbolos.
Estou ciente de Stackwalk64 e de Projeto Stackwalker Mas, infelizmente, tem várias desvantagens importantes:
- É conhecido por ser muito lento (o Stackwalk64) e não quero perder muito tempo para coletar o traço que o basicamente pode ser feito tão rápido quanto caminhar na lista vinculada.
- Sabe -se que a função Stackwalk64 não é segura.
Eu quero apoiar apenas x86 e possíveis arquiteturas x86_64
A ideia básica que tenho é seguir:
- Execute na pilha usando registros ESP/EBP de maneira semelhante à do GCC's
__builtin_return_address(x)
/__builtin_frame_address(x)
Doe até eu chegar ao fundo da pilha (é isso que o Glibc faz). - Traduzir endereços para símbolos
- Demange -os.
Problemas/perguntas:
- Como sei que alcancei a pilha? Por exemplo, a implementação do GLIBC tem
__libc_stack_end
Portanto, é fácil descobrir onde parar. Existe algum análogo de tal coisa no Windows? Como posso obter o endereço inferior da pilha? - Quais são os análogos da funcionalidade DLADDR. Agora eu sei que, diferentemente da plataforma ELF que mantém a maioria dos nomes de símbolos, o formato PE não. Portanto, deve ler de alguma forma as informações de depuração. Alguma ideia?
Solução
- Capturando rastreamento da pilha: Rtlcapturestackbacktrace
Obtendo símbolos: usando a biblioteca de ajuda DBG (somente MSVC). Principais funções:
// Initialization hProcess = GetCurrentProcess() SymSetOptions(SYMOPT_DEFERRED_LOADS) SymInitialize(hProcess, NULL, TRUE) // Fetching symbol SymFromAddr(...)
A implementação pode ser encontrada lá
Outras dicas
Você usa StackWalk
mas resolva símbolos mais tarde.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow