@@ -1098,11 +1098,6 @@ foreach ($k in $kids) {{
10981098 ((Get-Process -Id $k.ProcessId -ErrorAction SilentlyContinue).Modules | ForEach-Object ModuleName) -join ' '
10991099 "== PowerShell event log for $($k.ProcessId)"
11001100 Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' -MaxEvents 400 -ErrorAction SilentlyContinue | Where-Object ProcessId -eq $k.ProcessId | Sort-Object TimeCreated | ForEach-Object {{ " $($_.TimeCreated.ToString('HH:mm:ss.fff')) $($_.Id) $(($_.Message -split ""`n"")[0])" }}
1101- $cdb = "${{env:ProgramFiles(x86)}}\Windows Kits\10\Debuggers\x64\cdb.exe"
1102- if (Test-Path $cdb) {{
1103- "== stacks of powershell $($k.ProcessId) (cdb)"
1104- & $cdb -pv -p $k.ProcessId -c '.loadby sos clr; ~*e !clrstack; ~*kc 40; qd' 2>&1 | Out-String -Width 300
1105- }} else {{ "== no cdb at $cdb" }}
11061101}}
11071102"== end of dump $(Get-Date -f o)"
11081103"#
@@ -1205,6 +1200,12 @@ foreach ($k in $kids) {{
12051200 "small+cpu" => add ( diag_small_env ( pidfile) , CPU ) ,
12061201 "small+all3" => add ( add ( add ( diag_small_env ( pidfile) , IDENT ) , DIRS ) , CPU ) ,
12071202 "full-ident" => drop ( full ( ) , IDENT ) ,
1203+ "small+ProgramFiles" => add ( diag_small_env ( pidfile) , & [ "ProgramFiles" ] ) ,
1204+ "small+psmp-pshome" => {
1205+ let mut e = diag_small_env ( pidfile) ;
1206+ e. push ( ( "PSModulePath" . into ( ) , system32 ( r"WindowsPowerShell\v1.0\Modules" ) . to_string_lossy ( ) . into_owned ( ) ) ) ;
1207+ e
1208+ }
12081209 other => panic ! ( "{other}" ) ,
12091210 }
12101211 }
@@ -1250,60 +1251,53 @@ foreach ($k in $kids) {{
12501251 assert ! ( gone( & pid) , "ping {pid} survived" ) ;
12511252 }
12521253
1254+ /// DIAG: how long PowerShell takes to find Start-Process, and where it looks.
1255+ #[ cfg( windows) ]
1256+ const FIND : & str = "'up'; \" psmp $env:PSModulePath\" ; $t = [Diagnostics.Stopwatch]::StartNew(); $c = Get-Command Start-Process; \
1257+ \" found in $($t.ElapsedMilliseconds) ms: $($c.Module.Path)\" ; \
1258+ Set-Content -LiteralPath $env:BIAB_PIDFILE -Value 1";
1259+
12531260 /// DIAG: the same PowerShell, launched with a given environment.
12541261 #[ cfg( windows) ]
1255- fn diag_launch ( kind : & str , script : & str ) -> String {
1262+ fn diag_launch ( kind : & str ) -> String {
12561263 let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
12571264 let pidfile = dir. path ( ) . join ( "pid" ) ;
12581265 let env = diag_env ( kind, & pidfile. to_string_lossy ( ) ) ;
12591266 let mut c = Command :: new ( powershell ( ) ) ;
1260- c. args ( [ "-NoProfile" , "-Command" , script ] ) . current_dir ( dir. path ( ) ) . stdin ( Stdio :: null ( ) ) ;
1267+ c. args ( [ "-NoProfile" , "-Command" , FIND ] ) . current_dir ( dir. path ( ) ) . stdin ( Stdio :: null ( ) ) ;
12611268 c. env_clear ( ) . envs ( env. iter ( ) . map ( |( k, v) | ( k. as_str ( ) , v. as_str ( ) ) ) ) ;
12621269 let t = Instant :: now ( ) ;
12631270 let ( mut child, rx) = start ( & mut c) . unwrap ( ) ;
1264- let cancel = AtomicBool :: new ( false ) ;
12651271 let mut said = Vec :: new ( ) ;
1266- let ( code, ( pid, at, dump) ) = thread:: scope ( |s| {
1267- let watcher = s. spawn ( || {
1268- let r = diag_wait ( & pidfile, kind) ;
1269- cancel. store ( true , Ordering :: SeqCst ) ;
1270- r
1271- } ) ;
1272- let code = supervise ( & mut child, & rx, Duration :: from_secs ( 200 ) , Some ( & cancel) , & mut |_, b| {
1273- said. push ( format ! ( "{:?} {}" , t. elapsed( ) , String :: from_utf8_lossy( & b) . trim_end( ) ) )
1274- } ) ;
1275- ( code, watcher. join ( ) . unwrap ( ) )
1276- } ) ;
1277- match pid {
1278- Some ( _) => format ! ( "ok {:.1}s said {said:?}\n {dump}" , at. as_secs_f64( ) ) ,
1279- None => format ! ( "HANG code {code:?} said {said:?}\n {dump}" ) ,
1280- }
1272+ let code = supervise ( & mut child, & rx, Duration :: from_secs ( 120 ) , None , & mut |_, b| said. push ( String :: from_utf8_lossy ( & b) . trim_end ( ) . to_string ( ) ) ) ;
1273+ let found = said. iter ( ) . find ( |l| l. starts_with ( "found" ) ) . cloned ( ) . unwrap_or_else ( || format ! ( "NOT FOUND {said:?}" ) ) ;
1274+ let psmp = said. iter ( ) . find ( |l| l. starts_with ( "psmp" ) ) . cloned ( ) . unwrap_or_default ( ) ;
1275+ format ! ( "{:.1}s code {code:?} {found} | {psmp}" , t. elapsed( ) . as_secs_f64( ) )
12811276 }
12821277
12831278 #[ cfg( windows) ]
12841279 #[ test]
12851280 #[ ignore]
12861281 fn diag_variants ( ) {
12871282 let rounds: usize = std:: env:: var ( "DIAG_ROUNDS" ) . ok ( ) . and_then ( |v| v. parse ( ) . ok ( ) ) . unwrap_or ( 3 ) ;
1288- let kinds = [ "small" , "full" , "full-pathsys32" , "small+ident" , "small+dirs" , "small+cpu" , "small+all3" , "full-ident" ] ;
1283+ let kinds = [
1284+ "small" , "full" , "full-pathsys32" , "small+ident" , "small+dirs" , "small+cpu" , "small+all3" , "full-ident" , "small+ProgramFiles" ,
1285+ "small+psmp-pshome" ,
1286+ ] ;
12891287 for round in 0 ..rounds {
12901288 let results: Vec < String > = thread:: scope ( |s| {
1291- let hs: Vec < _ > = kinds. iter ( ) . map ( |k| s. spawn ( move || diag_launch ( k, TREE ) ) ) . collect ( ) ;
1289+ let hs: Vec < _ > = kinds. iter ( ) . map ( |k| s. spawn ( move || diag_launch ( k) ) ) . collect ( ) ;
12921290 hs. into_iter ( ) . map ( |h| h. join ( ) . unwrap ( ) ) . collect ( )
12931291 } ) ;
12941292 for ( k, r) in kinds. iter ( ) . zip ( & results) {
1295- eprintln ! ( "round {round} {k} {}" , r. lines( ) . next( ) . unwrap_or( "" ) ) ;
1296- }
1297- if round == 0 {
1298- for ( k, r) in kinds. iter ( ) . zip ( & results) {
1299- eprintln ! ( "==== DIAG DETAIL {k}\n {r}" ) ;
1300- }
1293+ eprintln ! ( "round {round} {k}: {r}" ) ;
13011294 }
13021295 }
1303- // One at a time, as the cancel test alone.
1304- for k in kinds {
1305- let r = diag_launch ( k, TREE ) ;
1306- eprintln ! ( "alone {k} {}" , r. lines( ) . next( ) . unwrap_or( "" ) ) ;
1296+ // One at a time, twice over.
1297+ for pass in 0 ..2 {
1298+ for k in kinds {
1299+ eprintln ! ( "alone{pass} {k}: {}" , diag_launch( k) ) ;
1300+ }
13071301 }
13081302 }
13091303
0 commit comments