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:
- :
- :
- 500 ( ).
- VirtualAlloc .
- , VirtualAlloc ~500
- .
. . , . , VirtualScan VAllocStress. , CFG ,
. VAllocStress !
CFG, . !
, JavaScript- v8 CodeRange , CodeRange
128 . , , CFG, .
, CodeRange, , ? CodeRange, Gmail — . ( ) CodeRange. , WorkerThread::Start . :
- Gmail -, , .
- , -.
- CodeRange, JITted- JavaScript 47- .
- CFG 2 .
- CFG .
- 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 Panel →
Configuration Manager →
Actions,
Hardware Inventory Cycle Run Now.

, VAllocStress VirtualScan
Github.
. ( ), (), ( WMI). vmmap. — —
crbug.com/870054.
UPD.