24-Kern-CPU, aber ich kann keine E-Mail eingeben

Ich habe nicht nach Ärger gesucht. Ich habe den Chrome-Erstellungsprozess am Wochenende nicht tausendmal gestartet, sondern nur die häufigsten Aufgaben des 21. Jahrhunderts ausgeführt. Ich habe gerade um 10:30 Uhr morgens eine E-Mail geschrieben. Und plötzlich hielt Google Mail an. Ich druckte einige Sekunden lang weiter, aber es wurden keine Zeichen auf dem Bildschirm angezeigt. Dann sackte Google Mail plötzlich zusammen und ich kehrte zu meiner sehr wichtigen E-Mail zurück. Aber später wiederholte sich alles, nur dass Google Mail diesmal keine Anfragen mehr beantwortete. Das ist seltsam ...

Es ist schwierig, der Gelegenheit zu widerstehen, eine gute Untersuchung durchzuführen, aber in diesem Fall ist die Herausforderung besonders groß. Schließlich arbeite ich bei Google daran, die Leistung von Chrome für Windows zu verbessern. Die Ursache des Einfrierens herauszufinden, ist meine Aufgabe . Und nach vielen Fehlstarts und harter Arbeit konnte ich immer noch herausfinden, wie Chrome, Gmail, Windows und unsere IT-Abteilung mich daran hinderten, eine E-Mail zu schreiben. Auf dem Weg dorthin gab es eine Möglichkeit, für einige Webseiten in Chrome eine erhebliche Menge an Speicherplatz zu sparen.

Es gab so viele Nuancen in der Untersuchung, dass ich einige für einen anderen Artikel belassen werde , und jetzt werde ich die Gründe für die Suspendierungen vollständig erläutern.

Wie üblich arbeitet UIforETW in meinem Hintergrund und überwacht kreisförmige Puffer, sodass ich nur Strg + Win + R eingeben musste - und die Puffer wurden für die letzten 30 Sekunden der Systemaktivität auf der Festplatte gespeichert. Ich habe sie in Windows Performance Analyzer (WPA) heruntergeladen, konnte das Einfrieren jedoch nicht dauerhaft installieren.

Wenn das Windows-Programm keine Nachrichten mehr sendet, werden ETW-Ereignisse ausgelöst, die genau angeben , wo dies geschehen ist. Daher ist es trivial, diese Arten von Hängen zu finden. Aber anscheinend hat Chrome weiterhin Nachrichten gesendet. Ich habe nach einem Moment gesucht, in dem einer der wichtigsten Chrome-Streams entweder in den aktiven Zyklus eingetreten ist oder vollständig inaktiv war, aber nichts Explizites gefunden hat. Es gab einige Stellen, an denen Chrome größtenteils im Leerlauf stand, aber selbst dann funktionierten alle wichtigen Threads weiter, sodass Sie nicht sicher sein konnten, wo der Hang aufgetreten ist. Chrome konnte ohne Ereignisse einfach im Leerlauf stehen:



UIforETW verfügt über einen integrierten Keylogger, der häufig zum Identifizieren von Schlüsselpunkten in einer Ablaufverfolgung hilfreich ist. Aus offensichtlichen Sicherheitsgründen werden jedoch standardmäßig Tastenanschläge anonymisiert, wobei jede eingegebene Zahl als "1" und jeder Buchstabe als "A" behandelt wird. Dies macht es schwierig, den genauen Zeitpunkt des Einfrierens zu finden, daher habe ich die Art der Spur von "privat" in "voll" geändert und ein Einfrieren erwartet. Gegen 10:30 Uhr am nächsten Morgen wiederholte sich das Auflegen. Ich habe die Ablaufverfolgungspuffer gespeichert und diese Markierung im Feld UIforETW-Ablaufverfolgungsinformationen gespeichert:

Er tippte "Verschieben für diejenigen, die mehr Erfahrung mit dem Tauchen haben" - und Google Mail hielt am Ende des Wortes "diese" an und nahm dann die Arbeit im Bereich des Wortes "Erfahrung" wieder auf. Registerkarte "Google Mail" mit PID 27368.

Dies ist eine häufige Diskussion über Wege, um ins Büro zu gelangen. Es ist jedoch wichtig, dass es jetzt eine Möglichkeit gibt, einen Hang in der ETW-Ablaufverfolgung zu finden. Ich lade den Trace, schaue mir die Keylogger-Daten im Feld "Allgemeine Ereignisse" an (Ereignisse werden von UIforETW selbst ausgegeben, und jedes ist eine lila Raute im folgenden Screenshot) - und ich kann sofort erkennen, wo der Hang aufgetreten ist, mit dem der Fehler in der CPU-Auslastung eindeutig korreliert:



Ok, aber warum hat Chrome aufgehört? Hier einige Hinweise: Die Screenshots zeigen nicht, dass WmiPrvSE.exe jedes Mal den CPU-Hyperthread vollständig verwendet. Das sollte aber keine Rolle spielen. Mein Computer verfügt über 24 Kerne / 48 Threads. Wenn Sie also einen Hyper-Thread verwenden, ist das System immer noch zu 98% frei.

Dann näherte ich mich einer eindeutig wichtigen Zeit, in der Chrome im Leerlauf war - und betrachtete insbesondere den CrRendererMain-Prozess in chrome.exe (27368), der der Registerkarte "Google Mail" entspricht.

Hinweis: Ich möchte mich ab 2015 bei mir bedanken, dass ich Microsoft gebeten habe, die Mechanismen für die Flussbenennung zu verbessern, und bei Microsoft für die Implementierung aller Vorschläge - die Thread-Namen in WPA sind einfach großartig!

Das Problem wurde behoben. Während eines 2,81-Sekunden-Hangs wurde dieser Thread 440 Mal nach einem Zeitplan gestartet. Normalerweise reicht es aus, alle 6 ms zu starten, um das Programm ansprechbar zu machen. Aus irgendeinem Grund ist dies jedoch nicht geschehen. Ich bemerkte, dass er jedes Mal, wenn er aufwachte, auf dem gleichen Stapel war. Zur Vereinfachung:

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/de420579/


All Articles