{"id":2847,"date":"2017-10-22T16:26:12","date_gmt":"2017-10-22T18:26:12","guid":{"rendered":"http:\/\/gianfratti.com\/?p=2847"},"modified":"2017-10-22T16:36:01","modified_gmt":"2017-10-22T18:36:01","slug":"captura-de-dumps-de-memoria-com-o-debug-diag","status":"publish","type":"post","link":"https:\/\/gianfratti.com\/index.php\/captura-de-dumps-de-memoria-com-o-debug-diag\/","title":{"rendered":"Captura de dumps de mem\u00f3ria com o Debug\u00a0Diag"},"content":{"rendered":"<div id=\"wrap\">\n<div id=\"content\">\n<div id=\"content-left\">\n<div class=\"post-1812 post type-post status-publish format-standard hentry category-debug tag-debug-2 tag-troubleshooting\">\n<div class=\"entry\">\n<p>Uma das ferramentas mais populares na coleta de dumps de mem\u00f3ria \u00e9 o <a href=\"https:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=49924\" target=\"_blank\" rel=\"noopener\">Debug Diag<\/a>. Atualmente na vers\u00e3o 2.1, este utilit\u00e1rio permite que a coleta de dumps seja feita em um formato mais completo, sem perda de informa\u00e7\u00f5es relevantes.<\/p>\n<p>Uma das principais vantagens do uso do Debug Diag \u00e9 a coleta de dumps a partir de triggers.<br \/>\n<!--more--><\/p>\n<p>Como apresentado na imagem abaixo, podemos notar que o Debug Diag nos fornece tr\u00eas regras b\u00e1sicas para a cria\u00e7\u00e3o de triggers coletoras de dumps de mem\u00f3ria.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2851\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image001_thumb.png\" alt=\"\" width=\"460\" height=\"372\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image001_thumb.png 460w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image001_thumb-300x243.png 300w\" sizes=\"auto, (max-width: 460px) 100vw, 460px\" \/><\/p>\n<p>Basicamente essas tr\u00eas regras funcionam da seguinte maneira:<\/p>\n<p>\u2013 Crash (C\u00f3digo gerenciado): regra ativada quando um processo com c\u00f3digo gerenciado lan\u00e7a uma exce\u00e7\u00e3o.<\/p>\n<p>\u2013 Performance (C\u00f3digo gerenciado): regra ativada quando o consumo de recursos computacionais de um processo com c\u00f3digo gerenciado atinge um limiar de performance configurado (seja esse recurso computacional mem\u00f3ria, CPU ou at\u00e9 mesmo tempo de resposta de uma requisi\u00e7\u00e3o HTTP).<\/p>\n<p>\u2013 Native Memory and Handle Leak (C\u00f3digo n\u00e3o-gerenciado): como o nome j\u00e1 diz, essa regra ser\u00e1 ativada quando um processo com c\u00f3digo n\u00e3o-gerenciado consumir mais mem\u00f3ria do que o esperado ou seu consumo de handles estiver acima de um limiar recomendado.<\/p>\n<p>Neste post trataremos de dois cen\u00e1rios comuns: captura de dump de mem\u00f3ria ap\u00f3s o crash em aplica\u00e7\u00f5es web hosteadas no IIS (<b>User Crash<\/b>) e captura de dump de mem\u00f3ria ap\u00f3s lentid\u00e3o na execu\u00e7\u00e3o de uma requisi\u00e7\u00e3o HTTP (<b>Long HTTP Response Time<\/b>).<\/p>\n<p>Para a execu\u00e7\u00e3o destes exemplos criei uma aplica\u00e7\u00e3o <span class=\"skimlinks-unlinked\">ASP.NET<\/span> Web Forms e a publiquei no IIS, dentro de um website chamado \u2018WebExceptionThrower\u2019 com um application pool dedicado, tamb\u00e9m chamado de \u2018WebExceptionThrower\u2019.<\/p>\n<p>Essa aplica\u00e7\u00e3o web consiste de uma \u00fanica p\u00e1gina com dois bot\u00f5es. Cada bot\u00e3o cont\u00e9m c\u00f3digo para estimular os exemplos que queremos exercitar.<\/p>\n<p><b>User Crash <\/b><\/p>\n<p>Para o exemplo de captura de dump a partir de um User Crash, adicionei um c\u00f3digo que for\u00e7asse o estouro de uma exce\u00e7\u00e3o. O quadro a seguir exemplifica o c\u00f3digo utilizado.<\/p>\n<pre>protected void UserCrashButton_Click(object sender, EventArgs e) {\r\n\r\n    int a = 0;\r\n    int b = 10;\r\n\r\n    double c = b \/ a;\r\n}<\/pre>\n<p>A exce\u00e7\u00e3o gerada a partir deste erro \u00e9 uma \u2018System.DivideByZeroException\u2019. O tipo da exce\u00e7\u00e3o lan\u00e7ada j\u00e1 nos diz muito, pois podemos filtrar pelo Debug Diag o tipo de erro que queremos analisar.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2852\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image003_thumb.jpg\" alt=\"\" width=\"447\" height=\"387\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image003_thumb.jpg 447w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image003_thumb-300x260.jpg 300w\" sizes=\"auto, (max-width: 447px) 100vw, 447px\" \/><\/p>\n<p>Voltando ao Debug Diag, devemos selecionar a primeira regra: Crash. Na pr\u00f3xima janela selecionamos a aplica\u00e7\u00e3o\/processo que tem gerado a exce\u00e7\u00e3o. Neste exemplo, como temos uma aplica\u00e7\u00e3o hosteada no IIS, selecionaremos a op\u00e7\u00e3o \u2018A specific IIS web application pool\u2019.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2853\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image005_thumb.jpg\" alt=\"\" width=\"469\" height=\"380\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image005_thumb.jpg 469w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image005_thumb-300x243.jpg 300w\" sizes=\"auto, (max-width: 469px) 100vw, 469px\" \/><\/p>\n<p>Note que todos os application pools existentes no IIS ser\u00e3o listados. Selecione o application pool desejado. Neste exemplo selecionaremos o application pool \u2018WebExceptionThrower\u2019.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2854\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image007_thumb.jpg\" alt=\"\" width=\"460\" height=\"372\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image007_thumb.jpg 460w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image007_thumb-300x243.jpg 300w\" sizes=\"auto, (max-width: 460px) 100vw, 460px\" \/><\/p>\n<p>Na pr\u00f3xima janela iremos configurar a coleta dos dumps de mem\u00f3ria. Siga as seguintes instru\u00e7\u00f5es para configurar o Debug Diag para coleta de dumps de exce\u00e7\u00f5es do tipo \u2018System.DivideByZeroException\u2019:<\/p>\n<p>1 \u2013 No campo \u2018Action type for unconfigured first chance exceptions\u2019 selecione \u2018Full user dump\u2019<\/p>\n<p>2 \u2013 No campo \u2018Action limit for unconfigured first chance exceptions\u2019 configure para \u20183\u2019<\/p>\n<p>3 \u2013 Clique em \u2018Exceptions\u2026\u2019 e siga as seguintes configura\u00e7\u00f5es:<\/p>\n<p>4 \u2013 Clique em \u2018Add Exception\u2026\u2019<\/p>\n<p>5 \u2013 Selecione \u2018CLR (.NET) 4.x Exception\u2019<\/p>\n<p>5.1 \u2013 No campo \u2018Exeption Type Equals\u2019 informe \u2018System.DivideByZeroException\u2019<\/p>\n<p>5.2 \u2013 No campo \u2018Action Type\u2019 selecione \u2018Full Userdump\u2019<\/p>\n<p>5.3 \u2013 No campo \u2018Action Limite\u2019 configure para \u20183\u2019<\/p>\n<p>Clicando em \u2018Ok\u2019, sua janela deve se parecer com a imagem a seguir.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2855\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image008_thumb.png\" alt=\"\" width=\"454\" height=\"307\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image008_thumb.png 454w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image008_thumb-300x203.png 300w\" sizes=\"auto, (max-width: 454px) 100vw, 454px\" \/><\/p>\n<p>Clicando em \u2018Save &amp; Close\u2019, sua janela deve se parecer com a imagem a seguir.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2856\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image010_thumb.jpg\" alt=\"\" width=\"500\" height=\"405\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image010_thumb.jpg 500w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image010_thumb-300x243.jpg 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>Cliquem em \u2018Next\u2019, atribua um nome para a regra criada e um diret\u00f3rio de destino para os dumps de mem\u00f3ria. Ap\u00f3s clicar em \u2018Next\u2019, marque a op\u00e7\u00e3o \u2018Activate the rule now\u2019 e clique em \u2018Finish\u2019.<\/p>\n<p>Volte a aplica\u00e7\u00e3o e simule o erro. Voc\u00ea notar\u00e1 que o Debug Diag possui uma coluna chamada \u2018Userdump Count\u2019, essa coluna exibe quantos dumps de mem\u00f3ria foram capturados durante a execu\u00e7\u00e3o da regra.<\/p>\n<p><a href=\"https:\/\/ferhenriquef.files.wordpress.com\/2014\/12\/clip_image012.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2857\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image012_thumb.jpg\" alt=\"\" width=\"531\" height=\"364\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image012_thumb.jpg 531w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image012_thumb-300x206.jpg 300w\" sizes=\"auto, (max-width: 531px) 100vw, 531px\" \/><\/a><\/p>\n<p><b>Long HTTP Response Time<\/b><\/p>\n<p>Para o exemplo de captura de dump ap\u00f3s a execu\u00e7\u00e3o de uma requisi\u00e7\u00e3o HTTP longa, crie um c\u00f3digo com um thread sleep de 30 segundos. Esse tempo de ir\u00e1 ser\u00e1 utilizado para simular qualquer poss\u00edvel opera\u00e7\u00e3o que onere o tempo de execu\u00e7\u00e3o, como uma consulta no banco de dados, acesso a algum recurso distribu\u00eddo na rede, escrita em disco ou um simples processamento complexo. O c\u00f3digo \u00e9 simples e \u00e9 demonstrado a seguir.<\/p>\n<pre>protected void LongHttpResponseTimeButton_Click(object sender, EventArgs e) {\r\n\r\n    <span class=\"skimlinks-unlinked\">System.Threading.Thread.Sleep(30000<\/span>);\r\n}<\/pre>\n<p>Antes de darmos in\u00edcio ao processo de configura\u00e7\u00e3o do Debug Diag, \u00e9 preciso que a feature de \u2018Tracing\u2019 do IIS esteja instalada no servidor web.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2858\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image014_thumb.jpg\" alt=\"\" width=\"456\" height=\"378\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image014_thumb.jpg 456w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image014_thumb-300x249.jpg 300w\" sizes=\"auto, (max-width: 456px) 100vw, 456px\" \/><\/p>\n<p>Para coleta de dumps a partir de uma regra de performance, selecione o tipo de regra \u2018Performance\u2019 e clique em \u2018Next\u2019.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2859\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image016_thumb.jpg\" alt=\"\" width=\"482\" height=\"391\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image016_thumb.jpg 482w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image016_thumb-300x243.jpg 300w\" sizes=\"auto, (max-width: 482px) 100vw, 482px\" \/><\/p>\n<p>Selecione agora a op\u00e7\u00e3o \u2018HTTP Response Times\u2019, assim a regra ir\u00e1 basear-se no tempo de resposta das requisi\u00e7\u00f5es HTTP.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2860\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image018_thumb.jpg\" alt=\"\" width=\"460\" height=\"372\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image018_thumb.jpg 460w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image018_thumb-300x243.jpg 300w\" sizes=\"auto, (max-width: 460px) 100vw, 460px\" \/><\/p>\n<p>Na tela de configura\u00e7\u00e3o a seguir, forne\u00e7a a url relativa ou o nome da p\u00e1gina que ser\u00e1 analisada (essa funcionalidade tamb\u00e9m funciona para servi\u00e7os WCF que utilizam o protocolo HTTP), al\u00e9m do tempo m\u00e1ximo para gera\u00e7\u00e3o do dump de mem\u00f3ria. No exemplo a seguir, configurei coletas na p\u00e1gina \u2018<span class=\"skimlinks-unlinked\">Default.aspx<\/span>\u2019 e tempo m\u00e1ximo de espera de 15 segundos. Clique em Ok.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2861\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image020_thumb.jpg\" alt=\"\" width=\"469\" height=\"395\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image020_thumb.jpg 469w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image020_thumb-300x253.jpg 300w\" sizes=\"auto, (max-width: 469px) 100vw, 469px\" \/><\/p>\n<p>A janela a seguir ir\u00e1 apresentar todas as urls monitoradas pela regra. Clique em \u2018Next\u2019.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2862\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image022_thumb.jpg\" alt=\"\" width=\"439\" height=\"355\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image022_thumb.jpg 439w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image022_thumb-300x243.jpg 300w\" sizes=\"auto, (max-width: 439px) 100vw, 439px\" \/><\/p>\n<p>Na pr\u00f3xima janela \u00e9 preciso adicionar um \u2018Dump Target\u2019. Clique em \u2018Add Dump Target\u2019 e no campo \u2018Target Type\u2019 selecione \u2018Web Application Pool\u2019. Selecione o application pool de sua aplica\u00e7\u00e3o e clique em \u2018Ok\u2019.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2863\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image024_thumb.jpg\" alt=\"\" width=\"453\" height=\"361\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image024_thumb.jpg 453w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image024_thumb-300x239.jpg 300w\" sizes=\"auto, (max-width: 453px) 100vw, 453px\" \/><\/p>\n<p>Na pr\u00f3xima janela configure a regra para:<\/p>\n<p>1 \u2013 Generate a UserDumo every 3 seconds<\/p>\n<p>2 \u2013 Start the timer when writing the dump file completes<\/p>\n<p>3 \u2013 Stop after generating 3 UserDumps<\/p>\n<p>4 \u2013 Collect Full UserDumps<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2864\" src=\"http:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image026_thumb.jpg\" alt=\"\" width=\"448\" height=\"363\" srcset=\"https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image026_thumb.jpg 448w, https:\/\/gianfratti.com\/wp-content\/uploads\/2017\/10\/clip_image026_thumb-300x243.jpg 300w\" sizes=\"auto, (max-width: 448px) 100vw, 448px\" \/><\/p>\n<p>Cliquem em \u2018Next\u2019, atribua um nome para a regra criada e um diret\u00f3rio de destino para os dumps de mem\u00f3ria. Ap\u00f3s clicar em \u2018Next\u2019, marque a op\u00e7\u00e3o \u2018Activate the rule now\u2019 e clique em \u2018Finish\u2019.<\/p>\n<p>Volte a aplica\u00e7\u00e3o e simule a lentid\u00e3o para coleta dos user dumps.<\/p>\n<p>Fonte: https:\/\/ferhenriquef.com\/2014\/12\/28\/captura-de-dumps-de-memria-com-o-debug-diag\/#more-1812<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Uma das ferramentas mais populares na coleta de dumps de mem\u00f3ria \u00e9 o Debug Diag. Atualmente na vers\u00e3o 2.1, este utilit\u00e1rio permite que a coleta de dumps seja feita em um formato mais completo, sem perda de informa\u00e7\u00f5es relevantes. Uma das principais vantagens do uso do Debug Diag \u00e9 a coleta de dumps a partir <span class=\"ellipsis\">&hellip;<\/span> <span class=\"more-link-wrap\"><a href=\"https:\/\/gianfratti.com\/index.php\/captura-de-dumps-de-memoria-com-o-debug-diag\/\" class=\"more-link\"><span>Read More &rarr;<\/span><\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[201,2,170,200],"tags":[210,211],"class_list":["post-2847","post","type-post","status-publish","format-standard","hentry","category-net","category-net-framework","category-arquitetura","category-troubleshooting","tag-debug-diag","tag-dumps"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/gianfratti.com\/index.php\/wp-json\/wp\/v2\/posts\/2847","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gianfratti.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gianfratti.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gianfratti.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gianfratti.com\/index.php\/wp-json\/wp\/v2\/comments?post=2847"}],"version-history":[{"count":4,"href":"https:\/\/gianfratti.com\/index.php\/wp-json\/wp\/v2\/posts\/2847\/revisions"}],"predecessor-version":[{"id":2867,"href":"https:\/\/gianfratti.com\/index.php\/wp-json\/wp\/v2\/posts\/2847\/revisions\/2867"}],"wp:attachment":[{"href":"https:\/\/gianfratti.com\/index.php\/wp-json\/wp\/v2\/media?parent=2847"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gianfratti.com\/index.php\/wp-json\/wp\/v2\/categories?post=2847"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gianfratti.com\/index.php\/wp-json\/wp\/v2\/tags?post=2847"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}