CPU de 24 núcleos, mas não consigo digitar um email

Não procurei problemas. Não iniciei o processo de criação do Chrome mil vezes no fim de semana , mas apenas fiz as tarefas mais comuns do século 21 - acabei de escrever um email às 10:30 da manhã. E de repente o Gmail continuou. Continuei imprimindo por alguns segundos, mas nenhum caractere apareceu na tela. De repente, o Gmail cedeu e voltei ao meu e-mail muito importante . Mas depois tudo se repetiu, só que desta vez o Gmail não respondeu às solicitações por mais tempo. Isso é estranho ...

É difícil resistir à oportunidade de conduzir uma boa investigação, mas, neste caso, o desafio é especialmente forte. Afinal, estou no Google trabalhando para melhorar o desempenho do Chrome para Windows. Descobrir a causa do congelamento é o meu trabalho . E, depois de muitas falsas partidas e muito trabalho, ainda consegui descobrir como o Chrome, Gmail, Windows e nosso departamento de TI juntos me impediram de digitar um email. Ao longo do caminho, havia uma maneira de economizar uma quantidade significativa de memória para algumas páginas da web no Chrome.

Havia tantas nuances na investigação que deixarei algumas para outro artigo , e agora vou explicar completamente as razões das suspensões.

Como de costume, o UIforETW funciona em meu plano de fundo e monitora os buffers circulares, então eu apenas tive que inserir Ctrl + Win + R - e os buffers foram salvos em disco pelos últimos trinta segundos de atividade do sistema. Fiz o download no Windows Performance Analyzer (WPA), mas não consegui instalar permanentemente o congelamento.

Quando o programa Windows para de enviar mensagens, os eventos ETW são lançados indicando exatamente onde isso aconteceu ; portanto, é trivial encontrar esses tipos de interrupções. Mas, aparentemente, o Chrome continuou a enviar mensagens. Procurei um momento em que um dos principais fluxos do Chrome entrou no ciclo ativo ou estava completamente ocioso, mas não encontrou nada explícito. Em alguns lugares, o Chrome permaneceu ocioso, mas mesmo assim todos os principais tópicos continuaram funcionando, portanto, você não podia ter certeza de onde ocorreu o travamento - o Chrome poderia ficar ocioso na ausência de eventos:



O UIforETW possui um keylogger interno, que geralmente é útil na identificação de pontos-chave em um rastreamento. No entanto, por razões óbvias de segurança, por padrão anonimiza as teclas, tratando cada número digitado como "1" e cada letra como "A". Isso torna difícil encontrar o momento exato do congelamento, então mudei o tipo de rastreio de "particular" para "cheio" e estava esperando um congelamento. Por volta das 10h30 da manhã seguinte, o desligamento foi repetido. Salvei os buffers de rastreamento e salvei essa marca no campo de informações de rastreamento do UIforETW:

Ele digitou "adiar para aqueles que têm mais experiência com mergulho" - e o Gmail parou no final da palavra "aqueles" e depois retomou o trabalho na área da palavra "experiência". Guia Gmail com PID 27368.

Esta é uma discussão comum sobre maneiras de chegar ao escritório , mas é importante que agora haja uma maneira de encontrar um travamento no rastreamento da ETW. Carrego o rastreio, olho para os dados do keylogger no campo Generic Events (os eventos são emitidos pelo próprio UIforETW e cada um é um losango roxo na captura de tela abaixo) - e posso ver imediatamente onde ocorreu o travamento, com o qual a falha no uso da CPU se correlaciona claramente:



Ok, mas por que o Chrome parou? Aqui estão algumas dicas: as capturas de tela não mostram que cada vez que o WmiPrvSE.exe usa totalmente o hyperthread da CPU. Mas isso não deveria importar. Minha máquina possui 24 núcleos / 48 threads, portanto, consumir um hyper-thread significa que o sistema ainda está 98% gratuito.

Então, cheguei a um período claramente importante em que o Chrome estava ocioso - e observei, em particular, o processo CrRendererMain no chrome.exe (27368), correspondente à guia Gmail.

Nota: Quero agradecer a mim mesmo a partir de 2015 por solicitar à Microsoft que melhore os mecanismos de nomeação de fluxo e obrigado pela Microsoft por implementar todas as sugestões - os nomes dos threads no WPA são ótimos!

O problema foi esclarecido. Durante uma interrupção de 2,81 segundos, esse encadeamento foi iniciado em um agendamento 440 vezes. Normalmente, iniciar a cada 6 ms é suficiente para tornar o programa responsivo, mas por algum motivo isso não aconteceu. Percebi que toda vez que ele acordava, ele estava na mesma pilha. Para simplificar:

chrome_child.dll (stack base)
KernelBase.dll!VirtualAlloc
ntoskrnl.exe!MiCommitVadCfgBits
ntoskrnl.exe!MiPopulateCfgBitMap
ntoskrnl.exe!ExAcquirePushLockExclusiveEx
ntoskrnl.exe!KeWaitForSingleObject (stack leaf)

Chrome VirtualAlloc, “CfgBits” . , Chrome VirtualAlloc 440 , . . Chrome VirtualAlloc — . Chrome ,  — 439  — Chrome , . , .

Windows — , , . . .

, Chrome , WmiPrvSE., :

ntoskrnl.exe!KiSystemServiceCopyEnd (stack base)
ntoskrnl.exe!NtQueryVirtualMemory
ntoskrnl.exe!MmQueryVirtualMemory
ntoskrnl.exe!MiUnlockAndDereferenceVad
ntoskrnl.exe!ExfTryToWakePushLock (stack leaf)

WMI ( ), WMI. CPU, , WmiPrvSE.exe ( ):

WmiPerfClass.dll!EnumSelectCounterObjects (stack base)
WmiPerfClass.dll!ConvertCounterPath
pdh.dll!PdhiTranslateCounter
pdh.dll!GetSystemPerfData
KernelBase.dll!blah-blah-blah
advapi32.dll!blah-blah-blah
perfproc.dll!blah-blah-blah
perfproc.dll!GetProcessVaData
ntdll.dll!NtQueryVirtualMemory
ntoskrnl.exe!NtQueryVirtualMemory
ntoskrnl.exe!MmQueryVirtualMemory
ntoskrnl.exe!MiQueryAddressSpan
ntoskrnl.exe!MiQueryAddressState
ntoskrnl.exe!MiGetNextPageTable (stack leaf)

. NtQueryVirtualMemory, GetProcessVaData, Va, , . VirtualScan NtQueryVirtualMemory , Gmail (10-15 ) — . ?

, . NtQueryVirtualMemory . « », « » .. Gmail 26 000 , ( , WPA) 16 000 , .

- Gmail vmmap , Gmail (361 836 ) (49 719), — 2 147 483 648 , 2 . ?



, 2 Control Flow Guard (CFG), , “CFG” , Gmail Chrome — MiCommitVadCfgBits. , CFG !

Control Flow Guard (CFG) . , 128- . , CFG ( 2 ), . CFG , CFG . 98 24 866 CFG-. :

      Scan time,  Committed, page tables, committed blocks
Total: 41.763s, 1457.7 MiB,    67.7 MiB,  32112, 98 code blocks
CFG: 41.759s,  353.3 MiB,    59.2 MiB,  24866

vmmap ,  — vmmap 49 684 , 24 866

, CFG ? CFG , ? .


— VAllocStress, . 64- CFG, , , , . , / , , . VAllocStress:

  1. :
    • VirtualAlloc .
    • .
  2. :
    • 500 ( ).
    • VirtualAlloc .
    • , VirtualAlloc ~500 
    • .

. . , . , VirtualScan VAllocStress. , CFG , . VAllocStress !

CFG, . !


, JavaScript- v8 CodeRange , CodeRange 128 . , , CFG, .

, CodeRange, , ? CodeRange, Gmail — . ( ) CodeRange. , WorkerThread::Start . :

  1. Gmail -, , .
  2. , -.
  3. CodeRange, JITted- JavaScript 47- .
  4. CFG 2 .
  5. CFG .
  6. NtQueryVirtualMemory CFG ( 1  ) , .

CFG Windows 10 RS4 ( 2018 ), , . , .


CFG  — . CFG , . . , CFG ! , . CFG . , 2 !

, — Gmail 353,3  CFG 59,2  , 400 . - , .


v8 ( JavaScript Chrome) , CodeRange, . Microsoft CFG. , - Microsoft CFG , , , . vmmap .

. :

  • Gmail.
  • Windows 10.
  • IT- WMI- .
  • .
  • .

, , , . , , , , .

, 10:30 , IT- . , Control PanelConfiguration ManagerActions, Hardware Inventory Cycle Run Now.




, VAllocStress VirtualScan Github.


. ( ), (), ( WMI). vmmap. — — crbug.com/870054.

UPD.

Source: https://habr.com/ru/post/pt420579/


All Articles