Este artigo foi traduzido por máquina.

Tudo sobre CLR

Aprimoramentos no diagnóstico de produção do CLR 4

Jon Langdon

Equipe do CLR (Common Language Runtime), temos um grupo cujo foco está fornecendo APIs e serviços que permitem que outras pessoas para criar ferramentas de diagnóstico para código gerenciado. Os dois maiores componentes temos (em termos de recursos dedicados de engenharia) são depurando o gerenciado e APIs de criação de perfil (ICorDebug * e ICorProfiler *, respectivamente).

Como o restante das equipes de CLR e estrutura, nosso valor é percebido somente através de aplicativos criados sobre nossas contribuições. Por exemplo, as equipes do Visual Studio consumam esses depuração e APIs de criação de perfil para seus depurador gerenciado e ferramentas para criação de perfis de desempenho e um número de desenvolvedores de terceiros está criando ferramentas com a API de criação de perfil.

Nos últimos 10 anos, grande parte do foco nesta área, para o CLR e o Visual Studio, tem sido como habilitar cenários da área de trabalho do desenvolvedor: revisão de origem em um depurador para localizar erros de código; iniciar um aplicativo em um gerador de perfil de desempenho para ajudar a identificar os caminhos de código lenta; edição-e-continuam a ajudar a reduzir o tempo gasto no ciclo de depuração de compilação de edição; e assim por diante. Essas ferramentas podem ser úteis para encontrar bugs nos aplicativos depois de ter sido instalados na máquina do usuário ou implantados em um servidor (ambos os casos de agora em diante chamados de produção), e têm um número de outros fornecedores criando ferramentas de diagnóstico na parte superior do nosso trabalho de produção de nível internacional.

No entanto, podemos consistentemente obter comentários dos clientes e esses fornecedores sobrecarga a importância de torná-lo ainda mais fácil de encontrar bugs durante o ciclo de vida de um aplicativo. Após todos os bugs de software geralmente são considerados como ser mais caro corrigir o mais tarde encontradas no ciclo de vida do aplicativo.

4 De CLR (o tempo de execução subjacente 4 o Microsoft .NET Framework) é a primeira versão na qual fizemos um esforço significativo para abordar esse feedback e começar a expandindo os cenários de nosso suporte APIs diagnóstico no final de produção do espectro.

Neste artigo, eu levará uma olhada em alguns cenários que entendemos para ser particularmente doloroso hoje, a abordagem nós está fazendo para solucioná-los e os tipos de ferramentas permitem. Especificamente, explicarei como nós já evoluiu da API de depuração para oferecer suporte à depuração de despejo de falha de aplicativo - travar cenários e como fizemos isso mais fácil detectar quando trava é causada por problemas de vários segmentos.

Também descreverei como adicionando a capacidade de anexar ferramentas de criação de perfil para um aplicativo de execução já será ainda mais facilidade esses mesmos cenários de solução de problemas e reduzir muito o tempo necessário para diagnosticar problemas causados pelo consumo excessivo de memória.

Por fim, brevemente explicarei como fizemos ferramentas de criação de perfil mais fácil de implantar, removendo a dependência do registro. Em todo, o foco está principalmente nos tipos de novas ferramentas que permite que nosso trabalho, mas onde aplicável incluí as referências a recursos adicionais que o ajudará a entender como você pode tirar proveito de nosso trabalho por meio do Visual Studio.

Depuração de despejo

Um recurso popular que nós estiver oferecendo com o Visual Studio 2010 é gerenciado a depuração de despejo. Despejos de processo, geralmente chamados simplesmente de despejos, são normalmente usados em cenários para código nativo e gerenciado de depuração de produção. Um despejo é essencialmente um instantâneo do estado de ’ um processo em um determinado ponto no tempo. Especificamente, é o conteúdo da memória virtual do processo (ou alguns subconjuntos dos mesmos) despejado em um arquivo.

Antes para Visual Studio 2010, para depurar código gerenciado em despejos você precisava usar o sos.dll de extensão especializados Windows Debugger para analisar despejos, em vez de mais familiares ferramentas como o Visual Studio (em que você provavelmente escreveu e depurado seu código durante o desenvolvimento do produto). Nossa meta para a experiência de alto nível queremos ter ao usar um despejo para diagnosticar problemas no Visual Studio é que do estado interrompido live depuração: o que você enfrenta ao depurar o código e interrompido no ponto de interrupção.

O mais comum point-in-time para coletar um dump é quando há uma exceção não tratada em um aplicativo — um travamento. Você pode usar o despejo para descobrir por que a falha ocorreu, normalmente inicial, observando a pilha de chamadas do thread com falha. Outros cenários despejos sejam utilizados são travamentos de aplicativos e problemas de uso de memória.

Por exemplo, se seu site parou de processamento de solicitações, você pode anexar um depurador, coletar um dump e reinicie o aplicativo. Análise off-line do despejo de pode mostrar, por exemplo, que todos os seus segmentos processamento de solicitações aguardando uma conexão com o banco de dados ou talvez você encontrar um deadlock no seu código. Problemas de uso de memória podem se manifestar de várias maneiras de perspectiva do usuário final: o aplicativo mais lento devido a coleta de lixo excessiva de; serviço for interrompido porque o aplicativo ficou sem memória virtual e precisava ser reiniciado e assim por diante.

A CLR 2, as APIs de depuração ofereciam suporte para depuração de processos em execução, que dificultou a ferramentas direcionar os cenários que acabamos de descrever. Basicamente, a API não foi projetada com cenários Lembre-se a depuração de despejo. O fato de que a API utiliza um segmento auxiliar executado no processo de destino a solicitações de serviço de depurador enfatiza esse ponto.

Por exemplo, no CLR 2, quando um depurador gerenciado deseja movimentar a pilha do segmento, ele envia uma solicitação para o thread auxiliar no processo que está sendo depurado. O CLR no processo de solicitação de serviços e retorna os resultados ao depurador. Como um despejo é apenas um arquivo, não é nenhum thread auxiliar a solicitações de serviço nesse caso.

Para fornecer uma solução depurando código gerenciado em um arquivo de despejo, precisávamos criar uma API que não exigem a execução de código no destino para inspecionar o estado do código gerenciado. Mas porque gravadores (principalmente Visual Studio) o depurador já tem um investimento significativo em CLR depuração API para fornecer depuração em tempo real, nós não deseja forçar o uso de duas APIs diferentes.

Onde estamos trouxe no CLR 4 foi reimplementação um número de APIs (principalmente aquelas necessárias para a inspeção de código e dados) o depurador para remover o uso de thread auxiliar. O resultado é que a API existente não precisa se preocupar se o destino é um arquivo de despejo ou um processo em tempo real. Além disso, os criadores de depurador são capazes de usar a mesma API para o destino em tempo real e cenários de depuração de despejo. Quando live depuração especificamente para o controle de execução — definindo pontos de interrupção e Avançar no código — a API de depuração ainda usa um segmento auxiliar. A longo prazo, pretendemos remover a dependência para esses cenários também. Rick Byers (um desenvolvedor antigo nos serviços de depuração API) tem uma postagem de blog útil que descreve esse trabalho em mais detalhes blogs.msdn.com/rmbyers/archive/2008/10/27/icordebug-re-Architecture-in-CLR-4-0.aspx.

Agora você pode usar ICorDebug para inspecionar o código gerenciado e dados em um arquivo de despejo: movimentar pilhas, enumerar locais, obter o tipo de exceção e assim por diante. Para falhas e paradas, freqüentemente há suficiente contexto disponível das pilhas de thread e dados auxiliares para encontrar a causa do problema.

Embora sabemos o diagnóstico de memória e outros cenários também são importantes, que simplesmente não tínhamos tempo suficiente na agenda CLR 4 para criar novas APIs que fornecem a capacidade de inspecionar a heap gerenciada da maneira depuradores requer esse cenário. No futuro, continuaremos a expandir os cenários de diagnóstico de produção, oferecemos suporte, espero que isso é algo que adicionaremos. Mais adiante neste artigo falarei sobre outro trabalho que fizemos para ajudar a tratar desse cenário.

Eu também gostaria de explicitamente destacar que esse trabalho oferece suporte à destinos de 32 e 64 bits e depuração somente gerenciados e modo misto (nativo e gerenciado). Visual Studio 2010 oferece o modo misto para despejos contendo código gerenciado.

Monitor lock inspeção

Programação multithread pode ser difícil. Se estiver explicitamente escrevendo código multithread ou aproveitando estruturas ou bibliotecas que estão fazendo para você, diagnosticar problemas no código assíncrono e paralelo pode ser bastante desafiador. Quando você tiver uma unidade lógica de trabalho em execução em um único segmento, compreensão precária é muito mais simples e geralmente pode ser determinada examinando simplesmente pilha de chamadas do thread. Mas quando esse trabalho é dividido entre vários threads, o fluxo de rastreamento fica muito mais difícil. Por que o trabalho está concluindo não? É a parte dele bloqueado em algo?

Com vários núcleos se tornando comuns, os desenvolvedores buscam mais e mais para paralela de programação como um meio de melhorias de desempenho, em vez de simplesmente contar com chip avanços de velocidade. Desenvolvedores da Microsoft estão inclusos neste lote e nos últimos anos alguns nós já foi significativamente voltadas tornando mais fácil para os desenvolvedores a ser bem-sucedido nessa área. Da perspectiva do diagnóstico, acrescentamos algumas APIs simples, porém útil que permitem a ferramentas para ajudar os desenvolvedores melhor lidar com as complexidades de vários segmentos de código.

O depurador CLR APIs adicionamos inspeção APIs para bloqueios do monitor. Em outras palavras, monitores fornecem uma maneira de programas sincronizar o acesso a um recurso compartilhado (algum objeto em seu código .NET) entre vários threads. Assim, enquanto um segmento tem o recurso bloqueado, outro thread espera por ele. Quando o segmento proprietário do bloqueio libera a ele, a primeira segmento em espera agora pode obter o recurso.

No .NET Framework, monitores estão expostos diretamente por meio do namespace System.Threading.Monitor, mas com mais freqüência através de bloqueio e palavras-chave SyncLock translation from VPE for Csharp e Visual Basic, respectivamente. Eles também são usados na implementação de métodos sincronizados, a TPL (biblioteca paralela de tarefas) e outros modelos de programação assíncronos. O depurador novo APIs permitem que você compreender melhor o objeto, se houver, um determinado thread está bloqueado no e qual thread, se houver, mantém um bloqueio em um determinado objeto. Utilizando essas APIs, depuradores podem ajudar a desenvolvedores identificar travamentos e entender quando vários threads disputando para um recurso (comboios de bloqueio) podem estar afetando desempenho de um aplicativo.

Para obter um exemplo do tipo de ferramentas permite que esse trabalho, check-out paralelo recursos no Visual Studio 2010 de depuração. Daniel Moth e Stephen Toub fornecido uma visão geral excelente na edição de setembro de 2009 da MSDN Magazine (MSDN.Microsoft.com/magazine/ee410778).

Uma das coisas assimila nos mais sobre o despejo de depuração de trabalho é que criar uma exibição abstrata de destino de depuração significa nova funcionalidade de inspeção é adicionada, como o recurso de inspeção de bloqueio de monitor, que fornece o valor para ambos ao vivo e cenários de depuração de despejo. Espero que este recurso para ser extremamente valiosos para desenvolvedores, enquanto que inicialmente estão desenvolvendo um aplicativo, mas é o despejo de depuração de suporte que faz um acréscimo convincente para os recursos de diagnóstico de produção inspeção de bloqueio de monitor no CLR 4.

Tess Ferrandez, um engenheiro de suporte da Microsoft, tem um vídeo do Channel 9 (channel9.msdn.com/posts/Glucose/Hanselminutes-on-9-Debugging-Crash-Dumps-with-tess-Ferrandez-and-VS2010/) em que ela simula um cenário comboio de bloqueio comum para que ela encontrou ao solucionar problemas de aplicativos do cliente. Em seguida, ela apresenta como usar o Visual Studio 2010 para diagnosticar o problema. Ele é um ótimo exemplo dos tipos de cenários que esses novos recursos permitem.

Além de dumps

Embora acreditamos que as ferramentas que esses recursos permitem ajudará a reduzir a quantidade de tempo que leva os desenvolvedores a resolver problemas na produção, we não esperar (nem deseja) despejo de depuração a única maneira para diagnosticar problemas de produção.

No caso de diagnóstico de problemas problemas de uso excessivo de memória, normalmente começamos com uma lista de instâncias de objetos agrupados por tipo com contagem e tamanho agregado e o progresso em relação a Noções básicas sobre cadeias de referência de objeto. Shuttling arquivos de despejo que contém essas informações entre máquinas de desenvolvimento, equipe de operações de produção e os desenvolvedores e engenheiros de suporte podem ser complicado e demorado. E aplicativos à medida que crescem em tamanho — isso é especialmente predominante com aplicativos de 64 bits — os arquivos de despejo também crescer em tamanho e levar mais tempo para mover-se e processar. Ele foi com esses cenários de alto nível em mente que nós executou os recursos de criação de perfil descritos nas seções a seguir.

Ferramentas de criação de perfil

Há vários tipos diferentes de ferramentas internas de CLR da API de perfil. Cenários que envolvem a API de criação de perfil geralmente concentram-se em três categorias funcionais: desempenho, memória e instrumentação.

Desempenho geradores de perfis (como o que vem em algumas versões da Visual Studio) focalizar informando onde seu código está gastando tempo. Geradores de perfis de memória focalizar detalhando o consumo de memória do seu aplicativo. Geradores de perfis Instrumenting fazer, bem, tudo.

Deixe-me esclarecer um pouco essa última instrução. Dentre os recursos da API de criação de perfil fornece é a capacidade de inserir linguagem intermediária (IL) código gerenciado em tempo de execução. Chamamos essa instrumentação do código. Os clientes usam essa funcionalidade para criar ferramentas que oferecem uma ampla variedade de cenários de cobertura de código para injeção de falhas ao monitoramento de produção corporativos de aplicativos baseados no .NET Framework.

Um dos benefícios que da API de criação de perfil tem sobre a API de depuração é que ele foi projetado para ser extremamente leve. Ambos são APIs orientadas por eventos — por exemplo, há eventos em ambos para o carregamento de assembly, criar thread, exceção lançada e assim por diante — mas com a API de criação de perfil você registrar somente para os eventos que você se preocupa. Além disso, a DLL de criação de perfil é carregada dentro do processo de destino, garantindo o acesso rápido para executar o estado do tempo.

Por outro lado, o depurador API relata todos os eventos para um depurador fora de processo, quando conectada e suspende o tempo de execução em cada evento. Esses são apenas alguns dos motivos que a API de criação de perfil é uma opção atraente para criar ferramentas de diagnóstico on-line direcionamento de ambientes de produção.

Gerador de perfil anexar e desanexar

Embora vários fornecedores estão criando ferramentas ativada, a monitorização de aplicativos de produção por meio de instrumentação de IL, não temos muitas ferramentas aproveitando os recursos de monitoramento de desempenho e memória na API de criação de perfil para fornecer suporte a diagnóstico reativo. A principal barreira neste cenário tem sido a incapacidade de anexar CLR ferramentas baseadas em API para um processo de execução já de criação de perfil.

Em versões anterior 4 CLR, o CLR verifica durante a inicialização para verificar se um gerador de perfil foi registrado. Se ele encontrar um gerador de perfil registrado, o CLR, ele é carregado e fornece retornos de chamada como solicitado. A DLL nunca é descarregada. Isso é geralmente aceitável se o trabalho da ferramenta é criar uma imagem de ponta a ponta do comportamento do aplicativo, mas não funciona para problemas que não sabia existiam quando o aplicativo foi iniciado.

Talvez o mais penoso exemplo disso é o cenário de diagnóstico de uso de memória. Hoje, nesse cenário normalmente achamos que o padrão de diagnósticos é reunir vários despejos, examinar as diferenças em tipos alocados entre cada um, criar um cronograma de crescimento e localize no código do aplicativo onde os tipos suspeitos estão sendo referenciados. Talvez o problema é um mal implementado esquema de cache, ou talvez manipuladores de eventos em um tipo estiver mantendo as referências a outro tipo de outra forma fora do escopo. Os clientes e engenheiros de suporte gastam muito tempo diagnosticar esses tipos de problemas.

Para começar, como rapidamente mencionei anteriormente, despejos de processos de grandes são grandes e ao obter a um especialista para diagnóstico pode introduzir longos atrasos no tempo de resolução. Além disso, é o problema que você tenha que envolvem um especialista, principalmente devido ao fato de que os dados só são expostos por meio de uma extensão de depurador do Windows. Não há nenhuma API pública que permite que ferramentas consumir os dados e criar exibições intuitivas em cima dela ou integrá-lo com outras ferramentas que podem ajudar na análise.

Para facilitar a dificuldade de neste cenário (e alguns outros), adicionamos uma nova API que permite que criadores de perfis anexar a um processo em execução e aproveitar um subconjunto das APIs de criação de perfil existentes. Aqueles disponíveis depois de anexar ao processo de permitem a amostragem (consulte “ VS 2010: Anexar o Profiler a um aplicativo gerenciado ” no blogs.msdn.com/Profiler/Archive/2009/12/07/vs2010-Attaching-the-Profiler-to-a-Managed-Application.aspx) e diagnóstico de memória: movimentar a pilha; mapeamento de função endereços para nomes simbólicos; a maioria dos retornos de chamada Garbage Collector (GC); e inspeção de objeto.

No cenário que acabamos de descrever, ferramentas podem aproveitar essa funcionalidade para permitir aos clientes anexar a um aplicativo tendo tempos de resposta lento ou crescimento excessivo de memória, entender o que é atualmente em execução e saber quais tipos são ativo no heap gerenciado e o que é mantê-las vivas. Após coletar as informações, é possível desanexar a ferramenta e o CLR descarregará a DLL do gerador de perfil. Enquanto o restante do fluxo de trabalho serão semelhante — localização onde esses tipos são referenciados ou criados no seu código — esperamos ferramentas dessa natureza para ter um impacto ajustável na média de tempo-de resolução para esses problemas. Dave Broman, desenvolvedor no CLR definindo o perfil de API, aborda este e outros recursos de criação de perfil mais detalhadamente em seu blog (blogs.msdn.com/davbr).

Fazer, contudo, quero destacar duas limitações explicitamente neste artigo. Primeiro, anexe o diagnóstico de memória em está limitado a modos de GC não simultâneas (ou bloqueio): Quando o GC suspende a execução de todo o código gerenciado ao executar um GC. Enquanto simultânea GC é o padrão, o ASP.NET usa modo de servidor GC, que é um modo simultâneo não. Isso é o ambiente em que vemos a maioria desses problemas. Agradecemos a utilidade de perfilação anexar diagnósticos para aplicativos cliente e pretende oferecer isso em uma versão futura. Nós simplesmente priorizado o caso mais comum CLR 4.

Em segundo lugar, você não conseguir usar a API de criação de perfil para instrumentar IL após anexar. Essa funcionalidade é especialmente importante para nossos fornecedores de ferramenta de monitoramento corporativo que desejam ser capaz de alterar sua instrumentação dinamicamente em resposta a condições de tempo de execução. Comumente referimo-na esse recurso como re JIT. Hoje, você tem uma oportunidade de alterar o corpo de IL de um método: Quando é primeiro sendo compilado em JIT. Nós esperam oferecendo re-JIT seja uma tarefa significativa e importante e está investigando ativamente o valor do cliente e implicações técnicas como consideramos o fornecimento do trabalho em uma versão futura.

Ativação do registro de chumbo para geradores de perfis

Anexar Profiler e anexe o trabalho de suporte de APIs específicas de criação de perfil após a ativação foi o maior parte do trabalho fizemos no CLR API de criação de perfil para o CLR 4. Mas foi prazer localizar outro recurso muito pequeno (em termos de custo de engenharia) que tem um surpreendentemente grande impacto sobre os clientes a criar ferramentas de classe produção.

Antes do CLR 4, de uma ferramenta obter seu gerador de perfil DLL carregados em um aplicativo gerenciado, que ele teria que criar duas partes principais informações de configuração. A primeira era um par de variáveis de ambiente que disse o CLR para habilitar a criação de perfil e implementação que gerador de perfil para carregar (seu CLSID ou ProgID) quando o CLR é inicializado. Considerando que o profiler DLLs são implementados como servidores COM no processo (com o CLR que está sendo o cliente), a segunda parte de dados de configuração foi as informações de registro COM correspondentes armazenadas no registro. Isso basicamente disse o tempo de execução, por meio de COM, onde localizar a DLL no disco.

Durante o planejamento de CLR 4, durante a tentativa de entender como nós poderia tornar mais fácil para fornecedores criar ferramentas de classe produção-, tivemos alguns conversas interessantes com alguns dos nossos fornecedores de ferramentas e engenheiros de suporte. Os comentários que recebemos foram que, ao se deparar com uma falha de aplicativo de produção, os clientes geralmente cuidado menos impacto no aplicativo do (já está falhando; eles apenas desejam obter as informações de diagnóstico e mover) e mais informações sobre o impacto sobre o estado da máquina. Muitos clientes vá para comprimentos excelentes para documentar e vigiar a configuração de suas máquinas e apresenta alterações para que a configuração pode apresentar riscos.

Portanto, à parte do CLR da solução, queríamos para que seja possível ativar diagnóstico xcopy implantável ferramentas para ambos minimizam o risco de alterações de estado e para reduzir o tempo necessário para obter as ferramentas de e em execução na máquina.

4 CLR removemos a necessidade de registrar o profiler COM DLL no registro do. Ainda precisamos de variáveis de ambiente se você deseja iniciar o aplicativo no criador de perfil mas nos cenários de anexação detalhados anteriormente, não há nenhuma configuração necessária. A ferramenta simplesmente chamadas anexar o novo API, passa o caminho para a DLL e o CLR carrega o profiler. No futuro, queremos em maneiras para simplificar ainda mais o profiler configuração pois os clientes ainda encontrar a solução de variável de ambiente desafiador em alguns cenários.

Combinados, os recursos de criação de perfil dois que abordei apenas permitem uma classe de Low sobrecarga ferramentas que os clientes podem, no caso de falhas inesperadas, implantar rapidamente em uma máquina de produção para obter o desempenho ou informações de diagnóstico de memória para ajudar a identificar com precisão a causa do problema. Em seguida, apenas o mais rápido, o usuário poderá retornar a máquina ao seu estado original.

Resumo

Trabalhar em recursos de diagnóstico para o CLR é bittersweet. Consigo ver muitos exemplos de quanto os clientes enfrentam determinados problemas e ainda há sempre trabalho interessante que podemos fazer para ajudar a facilitar o desenvolvimento e faça os clientes mais satisfeitos. Se não estiver alterando essa lista de problemas desafiadores nossos clientes — ou seja, nós não está removendo itens dele — e, em seguida, nós não está funcionando.

4 CLR acho que criamos recursos que não apenas fornecem valor imediato no endereçamento alguns problemas do cliente superior, mas também estabelecer uma base que podemos continuar a criar no futuro. No futuro, continuaremos a investir em APIs e serviços que tornam ainda mais fácil de expor as informações de diagnóstico significativas em todas as fases de vida do aplicativo para que você possa se concentrar mais tempo na criação de novos recursos para seus clientes e menos tempo depuração existentes.

Se você estiver interessado em fornecer feedback no trabalho de diagnóstico que está considerando para nossa próxima versão, nós já lançada uma pesquisa em surveymonkey.com/s/Developer-Productivity-Survey. Como estamos agora sobre a remessa 4 CLR, nós estiver concentrado parte de nosso tempo sobre o planejamento de futuras versões e dados de pesquisa nos ajudará priorizar os esforços. Se você tiver alguns minutos, seria Adoramos ouvir de você.

Jon Langdoné gerente de programa na equipe do CLR onde ele se concentra no diagnóstico. Antes de ingressar na equipe do CLR, ele foi consultor com os serviços da Microsoft, ajudando os clientes a diagnosticar e corrigir problemas com aplicativos corporativos, em grande escala.

Graças ao especialista técnico seguir para revisar este artigo: Rick Byers