Pergunta

Eu estou olhando para um belo Estouro de Pilha-estilo de resposta para a primeira pergunta no antigo post de blog O Código C++ Tamanho, que eu vou repetir abaixo:

Eu realmente gostaria de alguma ferramenta (idealmente, g++ baseado), que me mostra que as partes do compilado/vinculada de código são gerados a partir de quais partes do código-fonte C++.Por exemplo, para ver se um determinado modelo está sendo instanciado por centenas de diferentes tipos (solucionáveis através de um modelo de especialização) ou se o código está sendo excessivamente lineares, ou se determinadas funções são maiores do que o esperado.

Foi útil?

Solução

Não parece algo como isto deve existir, mas eu não tenho usado nada parecido.Eu posso dizer a você como eu iria sobre scripts juntos, embora.Há, provavelmente, mais rápida e/ou mais sexy maneiras de fazê-lo.

Primeiro algumas coisas que você já deve saber:

O addr2line comando leva em um endereço de e posso dizer a você onde o código-fonte que o código de computador não implementa.O executável precisa ser construído com símbolos de depuração, e você provavelmente não quer otimizá-lo muito (-O0, -O1, ou -So é provavelmente tão alta como você gostaria de ir em primeiro lugar, de qualquer maneira).addr2line tem várias opções, e você vai querer ler sua página de manual, mas você vai precisar usar -C ou --demangle se você quiser ver a função de C++ nomes que façam sentido na saída.

O objdump comando pode imprimir todos os tipos de coisas interessantes sobre o material em vários tipos de arquivos de objeto.Uma das coisas que ele pode fazer é imprimir uma tabela representando os símbolos ou referido por um objeto de arquivo (incluindo arquivos executáveis).

Agora, o que você quer fazer com que:

O que você vai querer é para o objdump para dizer-lhe o endereço e o tamanho do .secção do texto.Este é o lugar onde executável real de código de máquina vidas.Existem várias maneiras de fazer isso, mas o mais fácil (por isso, de qualquer forma) é, provavelmente, para você fazer:

objdump -h my_exe | grep text

Que deve resultar em algo como:

 12  .text       0000049  000000f000  0000000f000 00000400  2**4

Se você não grep-lo seria dar-lhe um título como:

Idx  Name        Size     VMA         LMA         File off  Algn

Eu acho que para executáveis do VMA e LMA deve ser o mesmo, por isso não importa o que você usa, mas eu acho que a LMA é o melhor.Você também vai querer o tamanho.

Com a LMA e tamanho que você pode chamar repetidamente addr2line pedindo o código-fonte de origem do código de máquina.Eu não tenho certeza de como isso vai funcionar se você passou um endereço que estava dentro de uma instrução, mas eu acho que ele deve funcionar.

addr2line -e my_exe <address>

A saída de que este será um caminho/nome de arquivo, uma vírgula e um número de linha.Se você fosse contar a ocorrência de cada um único caminho/ficheiro:núm você deve ser capaz de olhar para aqueles que têm a mais alta conta.Perl hashes usando o caminho/ficheiro:num como a chave e um contador, pois o valor seria uma maneira fácil de implementar isso, mas há maneiras mais rápidas se você achar que corre muito lento.Você também pode filtrar as coisas que você pode determinar não precisa ser incluído no início.Para mostrar a sua saída, você pode filtrar as linhas diferentes de uma mesma função, mas você pode notar que linhas diferentes dentro de uma função têm contagens diferentes, o que pode ser interessante.De qualquer forma, isso poderia ser feito por fazer addr2line dizer o nome da função ou usando o objdump -t na primeira etapa de trabalho e uma função de cada vez.

Se você ver que alguns modelos de código ou de outras linhas de código que estão aparecendo no seu executáveis mais frequentemente do que você acha que eles devem, em seguida, você pode facilmente localizá-los e ter um olhar mais atento.Macros e funções de linha pode mostrar acabam manifestando-se de forma diferente do que você espera.

Se você não sabia, o objdump e addr2line são da GNU binutils o pacote, que inclui várias outras ferramentas úteis.

Outras dicas

Se você estiver olhando para encontrar fontes de código de inchaço no seu código C++, eu usei 'nm' para isso.O seguinte comando listará todos os símbolos no seu aplicativo com o maior código e blocos de dados no topo:

nm --demangle --print-size --size-sort --reverse-sort <executable_or_lib_name> | less

Eu escrevi recentemente uma ferramenta, inchaço-culpa, que faz algo similar ao que nategoose proposta.

Eu não sei se vai ajudar, mas há um gcc bandeira para escrever o código de assembly ele gera um arquivo de texto para o seu exame.

"-S Usado no lugar de c para provocar a fonte em assembler arquivo a ser gerado, usando .s, como a extensão, em vez do ficheiro de objecto.Isto pode ser útil se você precisa examinar o código assembly gerado."

Na maioria dos compiladores C existe uma maneira de gerar um .o arquivo de mapa.Este arquivo lista todas as bibliotecas compiladas seu endereço e o seu tamanho.Você pode usar esse arquivo de mapa para ajudar você a determinar quais arquivos você deve estar olhando para otimizar o primeiro.

Eu não sei como código do mapa->assembly gerado em geral.

Para instanciações de modelo que você pode usar algo como "seqüências de caracteres-a |grep |sort-u|gc++filt" para obter uma imagem aproximada do que está sendo criado.

Os outros dois itens que você mencionou parecer muito subjetivo, na verdade.O que é "demais" inlining?Você tem medo de que seu arquivo binário é ficar inflado?A única coisa a fazer é, na verdade, ir para o gdb e desmontar o chamador para ver o que é gerado, nada a verificação de "excessivo" inlining em geral.

Para a função de tamanho, novamente estou curioso para saber por que isso é importante?Você está tentando encontrar o código que se expande inesperadamente quando compilado?Como fazer você mesmo definir um tamanho esperado é uma ferramenta para examinar?Novamente, você sempre pode dissimular qualquer função que você suspeitar que está compilando para muito mais do que você deseja, e veja exatamente o que o compilador faz.

No Visual C++, isso é essencialmente o que .Arquivos PDB são para.

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