Adiando o inevitável – Parte 03. Identificando e tratando o consumo dos pools:

Começando por esse post vamos simular ocorre quando temos a exaustão dos pools de memória do Kernel do Windows.

Essa exaustão pode ocorrer devido ao memory leak (ou vazamento de memória), que é quando uma aplicação tem um bug em seu código e em condições de corrida falha em “devolver” ao sistema a memória alocada (comando free da linguagem C por exemplo). Ou ainda, quando a carga de trabalho é maior do que o servidor pode suportar (o que é agravado pelos modificadores “/PAE”, “/3GB” no arquivo “boot.ini”, uso do AWE, múltiplas interfaces de rede, entre outras coisas) nesse último caso, mesmo sem falhas nas aplicações ou serviços a máquina sofre dos efeitos da exaustão de recursos.

Para fins de simulação foi propositalmente causando um leak no paged pool usando a ferramenta “NotMyFault” da SysInternals.

Not_my_faul_ppleak

Ao mesmo tempo em que essa aplicação está “esvaziando” o pool, podemos ver aumentando o total alocado pela sua tag (Leak) através da ferramenta PoolMon:

pool_mon_leak

Por falar nisso, começando com o Windows 2003, é possível “rastrear” as alocações nos pool através das tags que são esses quatro caracteres que servem para identificar qual é o driver é responsável pela alocação. As alocações nos pools de memoria são diferentes daqueles feitas pelas aplicações, uma aplicação tem seu próprio espaço de memória ou VAS (Virtual Address Space), ao passo que, no Kernel Mode,  frações do mesmo espaço são divididas por vários programas, o Kernel mantém uma estrutura de controle dessas alocações.

Sobre a função que os driver utilizam para alocar memória e as regras para fazê-lo:

https://msdn.microsoft.com/en-us/library/windows/hardware/ff544520(v=vs.85).aspx

Uma listagem relacionando drivers e tags pode ser encontrada no link abaixo:

http://blogs.technet.com/b/yongrhee/archive/2009/06/24/pool-tag-list.aspx

Se temos um situação de exaustão do pool (consideramos que o pool está ficando baixo quando restarem menos de 50MB) e temos a predominância do consumo relativa a um  tag. No exemplo da imagem acima nota-se que é a tag “Leak”. Podemos (1) pesquisar uma tabela de tags, ou (2) usar o seguinte comando:

 

find_leak

No Windows os drivers ficam em “c:\Windows\System32\drivers”.

Encontrado o driver que é responsável pelo “vazamento”, uma atualização desse driver deverá resolver o problema. Isso vale tanto para driver do Windows como para driver de dispositivos. Uma falha relativamente comum de ocorrer é a descrita no seguinte KB:
https://support.microsoft.com/en-us/kb/940307

Algumas tags porém, não são exatamente drivers, e nesse caso o “tratamento” poderá ser uma pouco mais complicado.

Abaixo enumerei exemplos e possíveis causas:

MmSt

Se isso ocorre é um servidor de arquivos é imprescindível verificar se temos arquivos “.pst” sendo servidor pela rede.
Maiores e melhores detalhes:

http://blogs.technet.com/b/askperf/archive/2011/09/23/getting-to-know-the-mmst-pool-tag.aspx

http://blogs.technet.com/b/askperf/archive/2007/01/21/network-stored-pst-files-don-t-do-it.aspx

Toke

Essa é a memória utilizada para armazenas os Tokens de segurança do Windows, portanto se temos “pressão” em memória causada por essa tag precisamos investigar a origem das autenticações, para isso é aconselhável utilizar o ProcessExplorer e olhar as handles do processo “lsass.exe”, verificando qual(is) contas e qual(is) aplicações, application pools do IIS, tarefa agenda, etc. é a origem do problema.

CM31

Essa tag tem que ver com o registro do Windows, um registro fragmentado ou demasiado grande (registry bloat) é a razão por trás do consumo excessivo de pool por essa tag.
https://support.microsoft.com/en-us/kb/2498915

Então, após ler esse post, se ao monitorar o “nível” dos pools (como vimos no post anterior) você encontrar o sistema próximo da exaustão, já vai ser possível identificar se temos um leak em algum driver do sistema ou de dispositivo, ou ainda, se a carga de trabalho está “pesada” demais para esse servidor. Num próximo post, vou tratar com um pouco mais detalhe a identificação de um memory leaks (já que isso é útil também em servidores X64).

Use a sessão de comentários se precisa esclarecer alguma dúvida ou quiser deixar sua opinião sobre esse post.

Adiando o inevitável – Parte 02. Pesquisando os limites do Pools.

No artigo anterior tratamos da razão para o problema de exaustão dos pools das versões de Windows 2003 em arquitetura x86. Nesse post vamos tratar de: como saber se meu servidor está próximo de ter esse problema.

E por que dedicarmos um post a isso. Bem, o motivo é que, a utilização dos pools é fácil de ser obtida, já o tamanho máximos dos pools não é assim tão simples. Mas existe algumas alternativas fáceis de se implementar.

Antes de tratamos dos limites vamos a um breve refresh de como saber a utilização corrente de cada pool.

(1) Task manager:


Tsk_Mgr


(2) Performance Counters:

PerfMon

Os contadores utilizados são o Memory\Pool Nonpaged Bytes e o Memory\ Pool Paged Bytes.

(3) Pool Monitor: 

Mais informações sobre essa ferramenta estão nos seguintes  links:
https://support.microsoft.com/en-us/kb/177415
https://msdn.microsoft.com/en-us/library/windows/hardware/ff550442(v=vs.85).aspx
 
E o mais importante, o download dessa ferramenta pode ser feito aqui:
https://www.microsoft.com/en-us/download/details.aspx?id=15326

PoolMon

Destacado em vermelho temos o consumo do Non Paged Pool (N:) e do Paged Pool (P:).
Essas informação ficam visíveis quando usamos o parâmetro “-r”.

A vantagem do Pool Mon é que ele mostra não somente o “quanto” mas “o que” está consumindo o pool, no próximo post vamos falar sobre identificação e tratamento vazamentos de memória (memory leak) e cargas de trabalho e como as Tags das alocação dos pools são úteis para isso.

Como consultar o tamanho dos Pools:

Nos dois casos vamos precisar da instalação do WinDBG (Windows Debugger), não vou cobrir a instalação dessa ferramenta nesse post.

(1) Configurar o Process Explorer com o a DLL “DBGHelp” da pasta em que o WinDBG foi instalado, e os símbolos públicos do Kernel:

Esse post do Guilherme Carnevale, PFE da Microsoft, ensina como fazer isso:
http://blogs.technet.com/b/carnevale/archive/2010/04/11/usando-o-process-explorer-para-mostrar-limites-de-paged-e-non-paged-pool.aspx

Menu Options > Configure Symbols > Apontar o caminho para o arquivo “dgbhelp.dll” da pasta do WinDBG.

ProcExp1
 
Em Symbols Path apontar o servidor de símbolos públicos da Microsoft e o cache local.

Se ficar em dúvida consulte o seguinte KB:
https://support.microsoft.com/en-us/kb/311503
 
Após configurado, em View > System Information  e voilà temos os limites dos Pools:

ProcExp2
 
(2) Uma segunda maneira é usar o já nosso conhecido LiveKD, da SysInternals.

Com o comando !vm obtemos tanto o total alocado (Usage) quanto os limites do Paged Pool e do Non Paged Pool.

LiveKB_!VM
 
Se o Usage estiver próximo do Max (restando menos de 20 MB por exemplo) já é possível haver negativa do VMM (Virtual Memory Manager) às alocações nos pools, em consequência temos eventos de erro e falhas tanto em aplicações como em subsistemas do Kernel (share de rede que falha ao ser acessado, por exemplo).

No próximo post trataremos de “vazamento de memória” e identificação de cargas de trabalho excessivas, e no seguinte, um post sobre tentativas de contornar a exaustão dos pools (adiar o inevitável).

Espero que aproveite de alguma forma esse conteúdo, seja na prática ou apenas por conhecimento, se tiver alguma dúvida, deixe seu contato nos comentários. Novamente, muito obrigado!

Adiando o inevitável, Kit de Sobrevivência – Parte 01

Como você já deve saber, dentro de mais alguns dias, em 14 de Julho de 2015 o suporte ao Windows Server 2003 Sp2 vai, finalmente terminar.

http://www.microsoft.com/en-us/server-cloud/products/windows-server-2003/

É provável que até lá, nem todos as empresas tenham finalizado seus projetos de migração, e alguns administradores se deparem com um problema comum desse Sistema Operacional nas versões para plataforma X86, que é exaustão de recursos para o Sistema Operacional. Não raro, essa é e a causa raiz da indisponibilidade na rede, logon com perfil temporário e travamentos. Esses sintomas são facilmente observáveis em Servidores de Aplicações especialmente aqueles acessados por Terminal Server, e não raro Servidores de Arquivos e Controladores de Domínio de também.

Então, estou preparando uma série de posts que objetiva servir como um “kit de sobrevivência” caso você tenha a falta de sorte de se deparar com a situação proposta acima. Torço que esse não seja seu caso, mas se for, essa série poderá lhe ser útil. Do contrário, esse série não vai lhe agregar muito, então sugiro uma leitura mais produtiva.


Compreendendo a causa “raiz” do problema antes de tentar uma solução

Lá se vão alguns anos desde que a arquitetura X86 deixou de ser usada para servidores, como você sabe, nessa época os processadores eram capazes de processar “palavras” de memória de 32 bits. Logo, com 32 bits era possível endereçar (sem artifícios especiais) 4GB de RAM. Desses 2 GB eram destinados ao processo de uma aplicação e outros 2GB a algo que pode ser entendidocom um processo “especial” que recebe o nome de Kernel.

Como talvez você também já saiba, a memória de um processo pode ser dividida em duas partes, uma delas é o código do processo, esse código nunca é paginado, num processo do Windows esse subconjunto da memória ganha o nome especial de “Working Set”. Já o restante da memória de um processo, que pode ser paginado, recebe o nome de “Private Bytes”. Por exemplo: o código do navegador que você esta usando para ler esse post é parte do Working Set e as páginas da WEB  abertas são parte do Private Bytes.

Acontece que, no caso do processo “especial” que é o Kernel, o Working Set ganha o nome de Non Paged Pool e o Private Bytes o nome Paged Pool. Quando um processo não consegue alocar memória, isso não é lá grande coisa, mas quando o Sistema não consegue alocar memória, o efeito é desastroso.

No exemplo abaixo temos uma VM com suficiente memória (física mais pagefile), embora exista memória disponível, o processo conseguiu ocupar apenas  2GB, isso se deve a limitação imposta pelo projeto da arquitetura.

test_limits

Algumas aplicações utilizam um mecanismo conhecido como AWE esse mecanismo provê às aplicações uma API para manipular diretamente uma região da memória física de até 64GB na arquitetura X86.

Se mensagem “Not enough storage is available” lhe parece familiar é por que essa é justamente a mensagem de erro que é exibida em pop-ups e logs quando Kernel não consegue alocar memória.

A limitação de 2Gigas é “contornável” através do /3GB no arquivo “boot.ini“, aqui vai uma demonstração:

test_limits_3gb

Comparativamente temos um giga de memória a mais disponível para o espaço de memória de cada processo. Mas, ao fazermos isso, reduzimos pela metade o tamanho do espaço de memória disponível para o Kernel. Assim, se ocorrer um vazamento de memória em algum dos Pools ou a  carga de trabalho no servidor demandar um uso maior desse recurso, ocorre a “exaustão” e seus sintomas já mecionados.

Para saber qual o consumo total de memória de cada Pool, podemos utilizar o “Task Manager”.

task_mgr_pp_npp

Agora, saber o tamanho máximo que é definido pelo Sistema para cada Pool, e então saber se está sendo atingido o limite, não é tão direto assim.

Num próximo post vamos tratar de como descobrir o tamanho de cada Pool, e como tratar os eventos de exaustão.

Memory dump de Virtual Machines

Há vários posts atrás nesse blog tratamos da NMI que é um forma eficiente de se conseguir um Memory Dump em cenários de Hang.

Mas, que dizer de uma máquina virtual rodando em um Host com Hyper-V e que, esporadicamente, tem um hang para o qual precisamos de investigação?

A máquina virtual não tem um botão para causar uma NMI no seu “chassis”, e não é possível utilizar o gatilho de teclado (Ctrl+Scroll Lock), uma opção é usar o “NotMyFault” (SysInternals) mas isso depende de a console do sistema estar responsiva durante ou perto do hang, o que nem sempre acontece.

A opção mais viável nesse cenário é utilizar o LiveKD para criar um dump da memória da VM direto do host.

Link para download do LiveKD:

https://technet.microsoft.com/en-us/sysinternals/bb897415.aspx

Depois de baixar o executável, é interessante copiá-lo para mesma pasta onde o WinDBG está instalado, no meu caso:
C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x64

Ao executar o programa ele sugere criar um variável de ambiente com o endereço do servidor público de símbolos da Microsoft, e pede pela pasta onde os símbolos serão armazenados localmente.

dump_VM_01

Como uma variável global de ambiente é definida, o servidor (host) precisa ser reiniciado.

Ao usar a seguinte linha de comando:
livekd -o memory.dmp -p -hv <GUID ou nome da VM>

Iniciamos a gravação do dump:

dump_VM_02

Abrindo o arquivo dump resultante no WinDBG, confirmamos que:

(1) É de um S.O. diferente do que rodava no host:

dump_VM_03

(2) Não temos um error code para o bugcheck, isso é esperado uma vez que nenhum evento causou o dump, o qual foi gerado no Kernel do Host através do KD, despejando as páginas de memória do guest para o arquivo dump.

Finalizamos com por aqui com a imagem que comprova que de fato o dump é de um VM:

dump_VM_04

O nome LiveKD, assim como o prompt “kd>” (que vemos na janela do WinDBG apenas quando carregamos um arquivo dump do Windows) vem de “Kernel Debugging“. Parte do LiveKB é driver instalado no Kernel do Windows que permite marcar páginas de memória e despejá-las para um arquivo dump, isso permite o “live debugging“, que é quando temos o debugger conectado a uma máquina em funcionamento. Mas isso fica para um próximo post.

Mais uma vez obrigado pela leitura e como sempre, dúvidas e críticas são sempre bem vindas.


Fontes:

http://blogs.technet.com/b/markrussinovich/archive/2010/10/14/3360991.aspx

Bugchecks e Special Pool – Parte 2.

O que afinal é o Special Pool?

Special Pool é o nome que recebe o recurso que permite usar um “espaço” de segurança entre as alocações nos pools do Kernel Mode. Entre essas é alocado com um intervalo com identificador especial, de forma que, quando detectado que uma alocação sobrescreveu esse espaço de segurança, o código causador da falha é prontamente identificado.

Existe a possibilidade de usar esse recurso de forma granular, para uma pool tag especifica, por exemplo, ou para alocações maiores que um limiar. Não vamos entrar em maiores detalhes já que intensão é dar uma visão ampla de algo que pode facilmente ser feito no dia-a-dia.

Como habilitar:

Podemos habilitar o Special Pool através do “driver verifier“, que é nativo do Windows. Essa ferramenta  objetiva auxiliar usuários e desenvolvedores na  detecção de bugs e uma enorme variedade de outros comportamentos inconsistentes no código executado em Kernel  Mode (leia-se drivers).

Para habilitar a verificação de driver execute o comando “verifier” (com credenciais de administrador).
01

02

Que cuidados precisamos ter ao usar em ambiente de produção:

(1) O espaço de memória utilizado no Kernel Mode será “inflado” o que não deve ser preocupação quando estamos utilizando uma máquina X64 com razoável quantidade de memória, mas é preocupante se ainda estiver lidando com um sistema de 32 bits.

Abaixo temos uma comparação antes e depois de habilitar o Special Pool, em um instalação nova de uma VM com Windows Server 2008 R2 Sp1 tendo somente o pacote de integração instalado, (nenhum driver de terceiro, antivírus, e afins).

03 04

Fica perceptível um aumento no consumo de memória.

(2) Ao serem detectados os comportamentos inconsistentes o sistema não vai alerta-lo disso de outra forma que não um bugcheck, geralmente os com código de erro 0XC?. Outra possibilidade é o sistema entrar em loop, tendo um bugcheck a cada inicialização. Nesse caso á solução é: entrar no modo de segurança e desabilitar o driver verifier.

Finalizando esse post, o mesmo driver que causou os bugchecks da Parte 1 desse artigo, foi finalmente “pêgo” após ter habilitado o Special Pool, o que podemos comprovar pelo arquivo dump a seguir:

05

06

Referência: http://msdn.microsoft.com/en-us/library/windows/hardware/ff560267(v=vs.85).aspx

Numa situação real, estaríamos prontos para entrar em contato com o vendor do driver e pedir por uma atualização e com boas chances, resolver o problema.

Espero que tenha gostado dessa séria de dois posts sobre Special Pool, se alguma informação está incorreta, ou quiser dar algum feedback isso será apreciado.

Bugchecks e Special Pool – Parte 1.

Overrun ou overflow é quando um driver escreve além do limite da memória alocada para ele. Como no Kernel Mode (diferentemente do user mode em que cada processo tem seu VAS – Virtual Address Space) vários processos compartilham as mesmas páginas de memória, um overflow acaba por causar uma exceção em outro, e como já é sabido, exceção não tratável ocorrendo com um processo do Kernel Mode invariavelmente causa o bugcheck (BSOD).

Um overflow não vai causar sempre o mesmo código de bugcheck, diversos códigos (dos 300 possíveis) tem como sua causa um “pool corruption“.

Nesse post vamos falar também do Special Pool, que é um recurso que facilita a vida do Administrador de Sistemas ou Engenheiro de Suporte quando da necessidade investigar e normalizar um bugcheck causado por corrupção no pool.

Utilizando o NotMyFault da SysInternals “causei” alguns crashes utilizando buffer overflow.
É interessante notar que, o bugcheck não ocorre imediatamente após pressionar crash mas leva tempo até que corrupção no pool faça uma “vítima” causando o bugcheck.

 

01

Vejamos alguns exemplos:

 

Todos os bugchecks abaixo foram causados por um mesmo driver (NotMyFault.sys) fazendo buffer overflow:

(1)

BSOD1

(2)

0X19

(3)
BSOD3

Nesse último caso é interessante notar o código da exceção C0000005, justamente umInvalid Access”.

Em todos os cenários acima as chances de descobrir a origem da corrupção do pool através da análise dump é pequena, essa análise dependeria de um pool walk, que só seria bem sucedido se no dump ainda tivesse indicações da instrução que escreveu no pool, causando a corrupção, levando assim ao causador da falha.

O que fazer se enfrentarmos situações de bugcheck com indicação de corrupção do pool? No próximo post vamos tratar de como configurar o special pool, quais os cuidados ao fazer isso, e como esse recurso é útil para pegamos “em flagrante” o driver que corrompeu o pool.

Até lá. E como sempre feedbacks são bem vindos.

Bugcheck com código de erro 0X9F:

BSOD é o acrônimo para Blue Screen of Death, a chamada “tela azul”,esse não é um termo técnico e jamais vamos encontrar esse termo em documentos da Microsoft.

Até porque uma tela azul não implica inerentemente em morte, mas sim na constatação de uma falha que pode (e deve) ser diagnosticada e resolvida.

A tela azul – de texto até o Windows 2008 R2, e mais recemente gráfica – é o resultado da seguinte função do Kernel:

01

Sempre que vemos essa função numa stack de um arquivo dump, estamos olhando dentro do processo em que uma exceção não tratada, ou um comportamento considerado não consistente, foi detectada. O que não equivale dizer que a exceção foi causa pelo processo em questão, muitas vezes a falha em um código faz outro parecer um “culpado” quando foi na verdade uma vítima.

O motivo de existir o bugcheck é basicamente: evitar que uma corrupção de memória seja gravada no disco. É como um “botão do pânico” sempre que uma falha grave ou comportamento inconsistente é detectado no Kernel Mode do Windows, essa função é invocada.

O Kernel Mode do Windows é um segmento de memória protegido, ou seja, as aplicações normais não têm permissão para, por exemplo, alocarem memória nesse segmento. Basicamente falando, o que é executado em Kernel Mode são: boa parte do sistema operacional e os drivers. Portanto, se o seu computador tiver um bugcheck comece por desconfiar de drivers de dispositivos recentemente instalados ou atualizados. Contudo, hardware defeituoso (memória, processador, discos e outros) também causam o sintoma.

Essa semana vamos dar uma olhada no arquivo dump que um amigo me enviou, a queixa é que não era possível utilizar um determinado modelo de mouse, sem que ocorre o crash do sistema.

Para ver o conteúdo de um arquivo dump, utilizamos o WinDBG, que pode ser baixado do link abaixo:
http://msdn.microsoft.com/en-us/windows/hardware/hh852365.aspx

Configurado com os símbolos públicos que são disponibilizados por servidores da Microsoft:
http://support.microsoft.com/kb/31503


1.5O comando “vertarget” mostra informações sobre o computador em que o  dump de memória foi gerado.


02O comando “!analyze -v” (-v para modo verboso) expõe qual o valor semântico de cada um dos quatro parâmetros possíveis para a função que gera o bugcheck (KeBugCheckEx).

Aqui vemos que a causa raiz foi a demora em completar um IRP criado pelo driver POWER. Ou seja, ocorreu uma mudança de status no Kernel Power desse computador, o driver notificou isso e todos os demais drivers deveriam responder a essa mudança dentro de um tempo que por padrão é 10 minutos.

Referências:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff559329(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/ff565766(v=vs.85).asp

Uma olhada rápida nesse dump poderia sugerir que a falha foi devida ao seguinte driver o sistema:

03

E a deduzir que a solução seja encontrar uma atualização para o driver do Windows usbhub.sys.
Mas se executamos o comando “!irp” com o endereço da IRP que apontado pelo quarto parâmetro da função, (The blocked IRP). Vemos o seguinte:

04

A IRP causadora do bugcheck estava aguardando uma operação feita pelo driver “Btfilter”.

Quando executamos o comando “lmvm btfilter”, confirmarmos através da falta dos símbolos, que esse driver não é da Microsoft.

05

Ou seja, para uma atualização desse driver não precisamos de um HotFix e sim de uma nova versão do driver , disponibilizada pelo fabricante do hardware. Nesse caso a Atheros.

No caso do meu amigo, bastou atualizar o driver de Blue Tooth e o problema foi sanado.

Espero que essas informações lhe sejam úteis, e até a próxima semana.
Dúvidas, sugestões e/ou criticas são bem vindas.

 

O que é uma NMI e qual sua utilidade.

Na semana que passou mostrei um problema causado pela falta de posições na IRP Stack, estrutura que é alocada pelo I/O manager para conter as IRPs (I/O Request Packet, numa tradução livre: Pacote de Requisição de Entrada/Saída). Nesse semana seguirei o mesmo tema e vou discorrer sobre a NMI.

NMI, é o acrônimo para “Non Maskable Interruption”, ou interrupção não “mascarável”. Então, para compreendermos esse mecanismo basta entender o que é uma “interrupção” e como é processo de mascaramento das requisições de interrupções.

Uma interrupção em termos simples é uma notificação emitida por um dispositivo de hardware de que um evento precisa processamento. Por exemplo, cada tecla pressionada ao digitar esse texto gerou uma interrupção tratada pelo driver do teclado.

Um componente do hardware chamado PIC (Programmable Interruption Controller ou Controlador Programável de Interrupções) converte aqueles eventos em um número, que é usado como índice de uma estrutura que é criada no boot do sistema e se chamada IDT (Interruption Dispatch Table ou Tabela de Despachos de Interrupções). Essa estrtura contêm ponteiros para a rotina do driver responsável pelo tratamento da interrupção, essa rotina se chama ISR (Interruption Service Routine ou Rotina de Serviço da Interrupção).

Quando o código de uma interrupção está sendo processado (não entraremos nos detalhes de DPC, IRQL e escalonamento preemptivo nesse post) o processador tem seu nível de prioridade alterado para o nível da interrupção que está sendo tratado, enquanto esse nível não for alterado, as interrupção cujos níveis de prioridade são inferiores estão “mascaradas”. Portanto, não serão atendidas até que algum processador possa fazê-lo. Isso vale exceto para a NMI, o hardware possui fisicamente recursos para que, quando ocorrer essa interrupção, seu tratamento seja imediato.

Uma interrupção é assíncrona, podendo ocorrer a qualquer momento no sistema, diferente, por exemplo, de uma exceção, que somente pode ocorrer quando o código que a gerou for executado. Apenas uma interrupção ocorre por vez no sistema, e existem níveis diferentes de prioridade, que são definas pela HAL (Hardware Abstraction Layer ou Camada de Abstração do Hardware). O tratamento de uma interrupção de maior prioridade é sobreposto ao tratamento  de outra de menor prioridade. Na arquitetura atual de hardware (X64) são 15 os possíveis níveis de prioridade.

Qual é a utilidade da NMI?

A utilidade de existir NMI é a certeza de que sob qualquer condição de workload, e até mesmo durante um hang (travamento) severo, ao ocorrer essa interrupção, a mesma será prontamente e inevitávelmente atendida.

Para fins de diagnóstico é possível configurar o as versões do Windows até o 2008 R2 para que um dump de memória seja feito sempre que ocorra uma NMI.

Como configurar seu servidor para um dump de memória através de NMI:
http://support.microsoft.com/kb/927069

Nas versões posteriores ao Windows Server 2012 o dump quando de uma NMI é o comportamento esperado do sistema:
http://support.microsoft.com/kb/2750146

Uma boa recomendação é manter os servidores físicos configurados para que o dump de memória seja provocado por NMI, dessa forma, quando de um travamento, saímos do campo das especulações para o campo das comprovações, através da análise do arquivo de despejo da memória (dump).

O que causa uma NMI?
Alguns modelos de hardware possuem um botão específico para esse fim, por exemplo os servidores do fabricante Dell, como na imagem abaixo copiada de um manual de instruções:

Image

Também é possível “enviar” a NMI através dos consoles de administração remota como System X (IBM), ILO (HP) ou iDRAC (Dell).
Vale lembrar que possuir o botão não significa que o mesmo esteja operante, é necessário configurar o funcionamento do mesmo através da BIOS.

Apenas lembrando, o comportamento esperado para sistemas com Windows Server 2012 é o dump de memória, que ocorre após o bugcheck com código de erro 0X50 no caso de uma NMI. Assim sendo, jamais faça isso inadvertidamente com um servidor em produção sob pena de perder/ corromper dados.

Dúvidas ou correções não hesite em me comunicar.

Referências:

Evento de erro de sistema ID 2011

A seguinte mensagem de erro é mostrada no log de eventos de Sistema:

Event Type: Error
Event Source: Srv
Event ID: 2011
Date: 1/1/2008
Time: 12:00:00 AM
Computer: MachineName
Description:
The server’s configuration parameter “irpstacksize” is too small for the server to use a local device. Please increase the value of this parameter.

E/ou a seguinte é mostrada no log de Cluster:

1/1/2008 12:00:00 AM 1 2055 1055 ClusSvc N/A MachineName(PhysicalNode) Cluster File Share resource
‘Share: FOLDERSHARENAME’ has failed a status check. The error code is 1130.

Usando o comando “NET HELPMSG 1130” obtemos a seguinte saída:

Not enough storage was available to complete the operation.

O que certamente pode levar a desconfiança com problemas no sistema de storage o que certamente não vem ao caso.

Uma descrição desse problema é feita aqui:
http://blogs.technet.com/b/askcore/archive/2008/01/25/irpstacksize-and-clusters.aspx

A solução para este problemas está descrita aqui:
http://support.microsoft.com/kb/106167/en-us

Mais detalhes sobre esse mecanismo:
http://msdn.microsoft.com/en-us/library/windows/hardware/ff551821(v=vs.85).aspx

De onde vale a pena destacar o seguinte:
Any higher-level driver that allocates IRPs for lower-level drivers also determines how many I/O stack locations the new IRPs should have, according to the StackSizevalue of the next-lower driver’s device object.

O que equivale dizer que: o driver do mais alto nível deve fazer a alocação dessa estrutura (IRP stack) com níveis suficientes, de forma que todos os driver de níveis mais baixos tenham garantida sua posição no “array”. Como na figura:

 

Image

 

Nesse contexto estamos falando especificamente de IRPs que foram alocadas pelo driver (Srv.sys) que o componente Kernel Mode do serviço LanManServer.

Referência: http://www.thenetworkencyclopedia.com/entry/server-service/

Em outras circunstâncias a falta de espaço na stack de uma IRP é a causa do bugcheck com código de erro 0X35.
http://msdn.microsoft.com/en-us/library/windows/hardware/ff557494(v=vs.85).aspx

Bom exemplo de debugging de um cenário desse tipo de bugcheck:
http://www.osronline.com/article.cfm?article=337

Bem essa é minha primeira experiência postando conteúdo técnico em um blog, espero que lhe seja útil, terei prazer em ler seus comentários.