Ao depurar um programa Java no IntelliJ, como mostrar o Bytecode que está sendo executado?

Aug 30 2020

Estou usando o IntelliJ para depurar um programa Java. No meu caso atual, isso é o próprio IntelliJ - para depurar um problema nele - mas um problema semelhante ocorreu no passado com outro código.

Durante uma única etapa, em um determinado ponto ao entrar em um método, o IntelliJ não mostrará mais o código que está sendo executado. Estou acostumado a percorrer o código de byte descompilado quando a fonte não está disponível, mas neste caso o IntelliJ não mostrará nada - nenhum código-fonte, nenhum código de byte, nada. Isso acontece ao passar de RemoteExternalSystemProjectResolverImplpara o GradleProjectResolver.

De forma bastante suspeita, o problema acontece exatamente ao passar de uma classe que vem de um UrlClassLoader, para uma classe de um PluginClassLoader.

Estou ciente de que o depurador terá problemas para associar o bytecode que está sendo executado com o código-fonte quando o bytecode vier de um carregador de classes de natureza desconhecida, pois não existe um mecanismo bem definido para isso. Observe que estou totalmente bem em percorrer o código descompilado. (Mesmo percorrer as instruções de bytecode seria bom, mas o AFAIK IntelliJ não suporta isso). Não tenho certeza de como fornecer o código-fonte correspondente, então prefiro ver o bytecode para ter certeza de que não estou vendo informações falsas.

O que eu não entendo é por que o IntelliJ não me mostra esse bytecode. Ao contrário do código-fonte, o bytecode está disponível, afinal, ele está sendo executado agora.

O que devo fazer para que o IntelliJ mostre o bytecode que está sendo executado?

Atualização: etapas para reproduzir

  • Use o IntelliJ para criar um projeto de plug-in do IntelliJ
  • crie uma nova pasta com um arquivo build.gradle vazio nela
  • Execute uma instância "convidada" do IntelliJ no modo de depuração
  • Importar o projeto gradle vazio
  • No IntelliJ "host", vá para RemoteExternalSystemProjectResolverImpl.resolveProjectInfo e defina um ponto de interrupção para a chamada interna para this.myDelegate.resolveProjectInfo
  • No IntelliJ "convidado", pressione o botão de reimportação do Gradle. Deve atingir o ponto de interrupção.
  • Entre na função que está sendo chamada. Isso mostrará o quadro na pilha, mas nenhum código - nem mesmo bytecode bruto ou descompilado.

Respostas

Stefan Aug 30 2020 at 16:44

Você possivelmente está depurando uma biblioteca que foi compilada sem informações de depuração. Para isso, o compilador Java possui a opção de linha de comando "-g".

Eu suponho que você não entenda o que é bytecode. Este é um monte de valores numéricos que não podem ser exibidos de maneira semelhante ao código-fonte. Você não seria capaz de ler bytecode.

O que você geralmente está vendo é código de byte descompilado, que depende da existência de informações de depuração.