Intel Arc, PC 2: the minidump job (refused unelevated by the Minidump folder), the retry shape b that copies the dump as chunks before the install, read-back d (the Arc mining on 6733, its kind reading discrete in the enclosure), tonight's order and the stop rule
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
366e55c887
commit
0507dbbfdc
3 changed files with 223 additions and 0 deletions
|
|
@ -130,6 +130,8 @@ Section 2.3's first gotcha (the sub-group size) is cleared (32 for a 32-item wor
|
|||
|
||||
Job `run-ia-pc2-intel-driver-20261007-c` (elevated, the app's own OpenCL worker mining on the Arc in the Razer Core X V2 at the time): download 102 s, sha512 equal to Intel's page, Authenticode valid (Intel Corporation), `-s` install started 16:26:44Z. The job's local `elevated-output.log` ends on that line. The System log: bugcheck **0x0000003B** (SYSTEM_SERVICE_EXCEPTION, c0000005 at fffff80518bdca26), minidump `C:\WINDOWS\Minidump\100726-22234-01.dmp`, Kernel-Power 41 "rebooted without cleanly shutting down", the OS back up at 16:27:56Z (about 70 s after the installer started). Nobody was signed in after the restart, so the per-user app did not start until the logon at 17:34:46Z: 67 minutes off the network (the 5090 at 122 and the 5060 Ti at 40 MH/s, not only the Arc). Driver store after the restart (`pnputil /enum-drivers`): one Intel display package, `oem41.inf` = 32.0.101.6733 (the inbox driver); 9034 is neither staged nor bound. The Arc is listed with Code 0, the Intel OpenCL platform answers, and the app has its OpenCL worker on the card (read-back `run-ia-pc2-intel-readback-20261007-c`, 17:35:49Z; freeze read `run-ia-pc2-freeze-events-20261007`, `tools/intel-arc/pc2-freeze-events.ps1`). The link reads CurrentLinkWidth 1, CurrentLinkSpeed 1 on the device's own PnP properties (the Thunderbolt-tunnelled view; the rate is unaffected, section above).
|
||||
|
||||
Read-back d (18:14:51Z, the app then on 0.3.21 for a few minutes): the Arc row **mining** on 6733 (pid 25168, 8 identities), and its kind read **discrete**, not external, in the Razer Core X V2 (no USB4 or Thunderbolt router in the device's parent chain on this board; the link still x1 gen1): the external-kind hold alone would have missed this card, so 0.3.22 holds every card of the vendor (branch driver-hold-22 f8ed911e). The minidump: the unelevated read is refused (`Access to the path 'C:\WINDOWS\Minidump' is denied`, run-ia-pc2-minidump-20261007, 18:14:55Z), so the copy rides the elevated retry (`tools/intel-arc/pc2-intel-driver-b.ps1`: the dump as base64 chunks in the job's folder before the installer starts, a collect job after; the Mac parser `triage.py` names the module). Order tonight (the shipper owns PC 2): the project lead's hand reinstall of 0.3.20, the 0.3.22 installer job and smoke, then the retry on the shipper's pass line with the project lead's one click. Stop rule (main): a second crash ends it; 6733 mines at 11 MH/s and the driver-check table then treats 6733 as acceptable for the B580.
|
||||
|
||||
What follows: the retry on PC 2 runs with the Arc idle (`--cards-off "intel:Intel(R) Arc(TM) B580 Graphics"`, the runner holds the worker through the install) and only on a go; the same rule is now the app's (driver-check branch 46cc41e9: a card the app reads as external has its worker stopped before the installer starts). The faulting module in the minidump is not read yet (no debugger on PC 2; a copy of the 2 MB minidump by a fetch-and-collect job is one line if wanted). Per tier: a home miner with one eGPU who clicks the install with the card mining risks this crash and an hour off the network if nobody is at the keyboard; with the hold the installer runs over an idle card, which is the shape PC 1 took at 15:xxZ (stop-miners, exit 14, 9034 bound after the restart).
|
||||
|
||||
## 8. What is not done here
|
||||
|
|
|
|||
168
tools/intel-arc/pc2-intel-driver-b.ps1
Normal file
168
tools/intel-arc/pc2-intel-driver-b.ps1
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
# Igneum run job (shape b: the minidump copy first, then the driver): the Intel Arc graphics driver on PC 2 (machine 1ccfe586), 7 October 2026 (branch intel-arc). the project lead's word:
|
||||
# "PC 2 needs Arc drivers"; the B580 sits in a Razer Core X V2 on PC 2. PC 1's recipe (pc1-intel-driver.ps1) plus one
|
||||
# step: when the installer answers 14 or 1014 (installed, restart required) this job RESTARTS the PC itself (main's word
|
||||
# for PC 2, not the project lead's desk), with a line before and after; the read-back job runs after the boot.
|
||||
# Published as a signed `run` job with --elevated and WITHOUT --stop-miners: the RUNNER raises the one elevation prompt
|
||||
# (Start-Process -Verb RunAs) at the script's start, the project lead clicks it at the desk, and everything below runs under it:
|
||||
# the download, the hash check and the installer, with no second prompt. The installed app, its node and its miners
|
||||
# are never quit, paused, resumed or switched (no api/* request in this script); the Intel installer touches only
|
||||
# the Intel display device, never the NVIDIA or AMD driver, and runs with -s (silent) and no -b, so it never reboots
|
||||
# on its own; exit 14 = "reboot required", reported and left to the project lead. Lines start with RESULT so
|
||||
# `node tools/jobs.mjs <job id>` shows them; a SUMMARY {json} line ends the job.
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$jobName = 'pc2-intel-driver'
|
||||
$started = Get-Date
|
||||
function Stamp { (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ') }
|
||||
function Summary([string] $status, [hashtable] $extra) {
|
||||
$o = [ordered]@{ job = $jobName; status = $status; duration_s = [int]((Get-Date) - $started).TotalSeconds; finished_at = (Stamp) }
|
||||
foreach ($k in $extra.Keys) { $o[$k] = $extra[$k] }
|
||||
'SUMMARY ' + ($o | ConvertTo-Json -Compress -Depth 4)
|
||||
}
|
||||
# Intel's download page 785597 (read 7 October 2026): version 32.0.101.9034, released 2 October 2026 (non-WHQL; 9033
|
||||
# is the WHQL one), file gfx_win_101.9034.exe, 889.4 MB, mirror folder 929959; the SHA512 is the string the page prints.
|
||||
$version = '32.0.101.9034'
|
||||
$url = 'https://downloadmirror.intel.com/929959/gfx_win_101.9034.exe'
|
||||
$expectedBytes = 932631144
|
||||
$expectedSha512 = '3fc6f9b4c8ef40bf066f1ad77f3c6aea55d47bae6dc8ab9575a7a9fe8eee84bf0c79333f81825cd7538ea1bb7ca78b6ddb0b75f96b321b4dcf524dec843cf3f0'
|
||||
$job = $env:IGNEUM_JOB_DIR; if (-not $job) { $job = Join-Path $env:TEMP 'igneum-intel-driver' }
|
||||
New-Item -ItemType Directory -Force -Path $job | Out-Null
|
||||
$exe = Join-Path $job 'gfx_win_101.9034.exe'
|
||||
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
$elevated = (New-Object Security.Principal.WindowsPrincipal($id)).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
"RESULT start $(Stamp) job=$jobName machine=$env:COMPUTERNAME app_version=$env:IGNEUM_APP_VERSION user=$($id.Name) elevated=$elevated version_wanted=$version"
|
||||
# (B), the shipper's and main's shape of 7 October 2026, 19:1x BST: the 16:27Z crash's kernel minidump rides this one
|
||||
# elevated run (the Minidump folder refuses the unelevated read: run-ia-pc2-minidump-20261007 at 18:14:55Z). It is copied
|
||||
# into the job's own folder as base64 chunks (the intake carries text, 256 KB a file) before the installer starts, so the
|
||||
# chunks survive whatever the install does; the collect job that follows uploads them and the Mac parses the triage dump.
|
||||
try {
|
||||
$mdDir = 'C:\WINDOWS\Minidump'
|
||||
$mdOut = $env:IGNEUM_JOB_DIR; if (-not $mdOut) { $mdOut = Join-Path $env:TEMP 'ia-minidump-20261007' }
|
||||
foreach ($f in @(Get-ChildItem -LiteralPath $mdDir -File -ErrorAction Stop | Sort-Object LastWriteTime)) { "RESULT minidump_dir file=`"$($f.Name)`" bytes=$($f.Length) written=$($f.LastWriteTime.ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ'))" }
|
||||
$mdSrc = Join-Path $mdDir '100726-22234-01.dmp'
|
||||
$mdBytes = [System.IO.File]::ReadAllBytes($mdSrc)
|
||||
$mdSha = (Get-FileHash -LiteralPath $mdSrc -Algorithm SHA256).Hash.ToLower()
|
||||
"RESULT dump file=`"$mdSrc`" bytes=$($mdBytes.Length) sha256=$mdSha"
|
||||
$mdCode = [BitConverter]::ToUInt32($mdBytes, 56); $mdP = @(0..3 | ForEach-Object { [BitConverter]::ToUInt64($mdBytes, 64 + 8 * $_) })
|
||||
"RESULT header signature=`"$([System.Text.Encoding]::ASCII.GetString($mdBytes, 0, 8))`" bugcheck=0x$($mdCode.ToString('x8')) p1=0x$($mdP[0].ToString('x')) p2=0x$($mdP[1].ToString('x')) p3=0x$($mdP[2].ToString('x')) p4=0x$($mdP[3].ToString('x')) dump_type=$([BitConverter]::ToUInt32($mdBytes, 0xf98))"
|
||||
New-Item -ItemType Directory -Force -Path $mdOut | Out-Null
|
||||
$mdChunk = 135000; $mdN = [math]::Ceiling($mdBytes.Length / $mdChunk)
|
||||
for ($mi = 0; $mi -lt $mdN; $mi++) {
|
||||
$mdLen = [math]::Min($mdChunk, $mdBytes.Length - $mi * $mdChunk)
|
||||
$mdB64 = [Convert]::ToBase64String($mdBytes, $mi * $mdChunk, $mdLen, [System.Base64FormattingOptions]::InsertLineBreaks)
|
||||
$mdName = Join-Path $mdOut ('dump-{0:d3}.b64' -f $mi)
|
||||
[System.IO.File]::WriteAllText($mdName, "CHUNK $mi of $mdN bytes=$mdLen`r`n$mdB64`r`nEND $mi`r`n", [System.Text.Encoding]::ASCII)
|
||||
"RESULT chunk i=$mi of=$mdN raw_bytes=$mdLen file_bytes=$((Get-Item -LiteralPath $mdName).Length) sha256=$((Get-FileHash -LiteralPath $mdName -Algorithm SHA256).Hash.ToLower())"
|
||||
}
|
||||
"RESULT minidump chunks=$mdN dir=`"$mdOut`""
|
||||
} catch { "RESULT minidump error=$($_.Exception.Message)" }
|
||||
if (-not $elevated) { "RESULT error not elevated: the installer needs administrator rights (publish with --elevated)"; Summary 'failed' @{ error = 'not elevated' }; exit 2 }
|
||||
|
||||
# ---- what Windows sees before: every display adapter, the Intel ones by PnP, the OpenCL platforms the worker lists ----
|
||||
function Adapters([string] $tag) {
|
||||
try {
|
||||
foreach ($a in @(Get-CimInstance Win32_VideoController -ErrorAction Stop)) {
|
||||
"RESULT adapter_$tag name=`"$($a.Name)`" driver=$($a.DriverVersion) date=$($a.DriverDate) status=$($a.Status) code=$($a.ConfigManagerErrorCode) pnp=$($a.PNPDeviceID) ram32=$($a.AdapterRAM)"
|
||||
}
|
||||
} catch { "RESULT adapter_$tag error=$($_.Exception.Message)" }
|
||||
# the 32-bit AdapterRAM field caps at 4 GB: the true size is the class key's qwMemorySize
|
||||
try {
|
||||
foreach ($k in @(Get-ChildItem 'HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}' -ErrorAction Stop | Where-Object { $_.PSChildName -match '^\d{4}$' })) {
|
||||
$p = Get-ItemProperty -Path $k.PSPath -ErrorAction SilentlyContinue
|
||||
if ($p -and $p.DriverDesc) { $mem = ''; if ($null -ne $p.'HardwareInformation.qwMemorySize') { $mem = [string]([math]::Round([double]$p.'HardwareInformation.qwMemorySize' / 1MB)) + ' MiB' }; "RESULT class_$tag key=$($k.PSChildName) desc=`"$($p.DriverDesc)`" driver=$($p.DriverVersion) provider=`"$($p.ProviderName)`" memory=$mem" }
|
||||
}
|
||||
} catch { "RESULT class_$tag error=$($_.Exception.Message)" }
|
||||
try {
|
||||
foreach ($d in @(Get-PnpDevice -Class Display -ErrorAction Stop)) { "RESULT pnp_$tag name=`"$($d.FriendlyName)`" status=$($d.Status) present=$($d.Present) id=$($d.InstanceId)" }
|
||||
} catch { "RESULT pnp_$tag error=$($_.Exception.Message)" }
|
||||
}
|
||||
$inst = @("$env:LOCALAPPDATA\Programs\Igneum Miner", "$env:ProgramFiles\Igneum Miner") | Where-Object { Test-Path (Join-Path $_ 'igneum-app.exe') } | Select-Object -First 1
|
||||
$worker = $null
|
||||
if ($inst -and (Test-Path (Join-Path $inst 'igneum-worker-opencl.exe'))) { $worker = Join-Path $inst 'igneum-worker-opencl.exe' }
|
||||
"RESULT app install=$inst worker=$worker"
|
||||
function OpenCLList([string] $tag) {
|
||||
if (-not $worker) { "RESULT opencl_$tag error=no installed igneum-worker-opencl.exe to list with"; return @() }
|
||||
$lines = @(& $worker --list 2>&1 | ForEach-Object { "$_" })
|
||||
foreach ($l in $lines) { "RESULT opencl_$tag $l" }
|
||||
return $lines
|
||||
}
|
||||
Adapters 'before'
|
||||
$clBefore = OpenCLList 'before'
|
||||
$intelBefore = @($clBefore | Where-Object { $_ -match 'Intel' }).Count
|
||||
"RESULT opencl_before intel_lines=$intelBefore"
|
||||
|
||||
# ---- the download: curl.exe (shipped with Windows 10 1803 and later), the size and the SHA512 Intel publishes ----
|
||||
$dl = $null
|
||||
if (Test-Path -LiteralPath $exe) {
|
||||
$len = (Get-Item -LiteralPath $exe).Length
|
||||
if ($len -eq $expectedBytes) { "RESULT download reuse $exe bytes=$len (already here)"; $dl = $true } else { Remove-Item -LiteralPath $exe -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
if (-not $dl) {
|
||||
$curl = Join-Path $env:SystemRoot 'System32\curl.exe'
|
||||
if (-not (Test-Path -LiteralPath $curl)) { "RESULT error no curl.exe at $curl"; Summary 'failed' @{ error = 'no curl' }; exit 2 }
|
||||
$t0 = Get-Date
|
||||
"RESULT download start $(Stamp) url=$url expected_bytes=$expectedBytes"
|
||||
$attempt = 0
|
||||
while ($attempt -lt 3) {
|
||||
$attempt++
|
||||
$out = @(& $curl -sS -L --retry 3 --retry-delay 5 --connect-timeout 30 --max-time 1500 -o $exe $url 2>&1 | ForEach-Object { "$_" })
|
||||
$rc = $LASTEXITCODE
|
||||
$len = 0; if (Test-Path -LiteralPath $exe) { $len = (Get-Item -LiteralPath $exe).Length }
|
||||
"RESULT download attempt=$attempt curl_exit=$rc bytes=$len wall_s=$([int]((Get-Date) - $t0).TotalSeconds) $($out -join ' ')"
|
||||
if ($rc -eq 0 -and $len -eq $expectedBytes) { $dl = $true; break }
|
||||
Start-Sleep -Seconds 10
|
||||
}
|
||||
if (-not $dl) { "RESULT error download did not reach $expectedBytes bytes in 3 attempts"; Summary 'failed' @{ error = 'download' }; exit 2 }
|
||||
}
|
||||
$sha = (Get-FileHash -Algorithm SHA512 -LiteralPath $exe).Hash.ToLower()
|
||||
$sha256 = (Get-FileHash -Algorithm SHA256 -LiteralPath $exe).Hash.ToLower()
|
||||
"RESULT file $exe bytes=$((Get-Item -LiteralPath $exe).Length) sha512=$sha sha256=$sha256"
|
||||
if ($sha -ne $expectedSha512) { "RESULT error sha512 mismatch: Intel publishes $expectedSha512; the installer is NOT run"; Summary 'failed' @{ error = 'sha512 mismatch'; sha512 = $sha }; exit 2 }
|
||||
"RESULT sha512 ok (equal to the string on Intel's page 785597)"
|
||||
try { $sig = Get-AuthenticodeSignature -LiteralPath $exe; "RESULT authenticode status=$($sig.Status) signer=`"$($sig.SignerCertificate.Subject)`"" } catch { "RESULT authenticode error=$($_.Exception.Message)" }
|
||||
|
||||
# ---- the installer: -s silent, no -b (no reboot by the installer); its exit code says what happened ----
|
||||
# Intel's codes (support article 000098195, read 7 October 2026): 0 success, 1 failed, 2 the installer rebooted the
|
||||
# system itself (-b only), 8 no driver for this device, 13 reboot required BEFORE setup, 14 reboot required after.
|
||||
$meaning = @{ 0 = 'installed, no reboot asked'; 1 = 'installer failed (general)'; 2 = 'the installer rebooted the system'; 5 = 'the OS or a device on this platform is not supported by the driver (no supported Intel GPU present?)'; 6 = 'the installer was closed before it finished'; 7 = 'unsupported command-line parameter'; 8 = 'no INF files found in the bundle'; 9 = 'driver files without an Intel signature'; 11 = 'no free space'; 13 = 'a reboot is required BEFORE this driver can install'; 14 = 'installed; a reboot is required to apply it (NOT taken: the project lead decides)'; 1007 = 'the bootstrapper wrapped an inner Installer.exe exit 7 (unsupported parameter)'; 1014 = 'installed; a reboot is required to apply it (the bootstrapper wrapping the inner 14; NOT taken: the project lead decides)' }
|
||||
# Run 1 (09:27Z): `-s -report <path>` made the inner Installer.exe exit 7 ("unsupported parameter") and the bootstrapper
|
||||
# answer 1007 before any device check (its log: C:\ProgramData\Intel\GFXInstaller\Bootstrapper\IntelGFX_Bootstrapper_*.log).
|
||||
# So: -s alone. The bootstrapper also installs the .NET Desktop Runtime it needs (it did on run 1, exit 0).
|
||||
$t1 = Get-Date
|
||||
"RESULT install start $(Stamp) args=-s (silent, no -b); the screen may blink while the Intel device resets; NVIDIA and AMD drivers are not touched"
|
||||
$p = $null
|
||||
try { $p = Start-Process -FilePath $exe -ArgumentList @('-s') -Wait -PassThru -WindowStyle Hidden -ErrorAction Stop } catch { "RESULT error installer launch: $($_.Exception.Message)"; Summary 'failed' @{ error = 'launch' }; exit 2 }
|
||||
$code = $p.ExitCode
|
||||
$word = if ($meaning.ContainsKey([int]$code)) { $meaning[[int]$code] } else { 'unknown code' }
|
||||
"RESULT install end $(Stamp) exit=$code meaning=`"$word`" wall_s=$([int]((Get-Date) - $t1).TotalSeconds)"
|
||||
# the installer's own logs: the bootstrapper's under GFXInstaller\Bootstrapper, the inner installer's beside it (read 7 October 2026)
|
||||
$logRoot = Join-Path $env:ProgramData 'Intel\GFXInstaller'
|
||||
if (Test-Path -LiteralPath $logRoot) {
|
||||
foreach ($lf in @(Get-ChildItem -LiteralPath $logRoot -Recurse -Filter '*.log' -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -gt $t1.AddMinutes(-1) } | Sort-Object LastWriteTime)) {
|
||||
"RESULT log $($lf.FullName) bytes=$($lf.Length)"
|
||||
Get-Content -LiteralPath $lf.FullName -ErrorAction SilentlyContinue | Where-Object { $_ -match 'exit|error|fail|device|not supported|reboot|restart|install' } | Select-Object -Last 25 | ForEach-Object { "RESULT log $_" }
|
||||
}
|
||||
} else { "RESULT log none under $logRoot" }
|
||||
|
||||
# ---- what Windows sees after: the Intel device by name and version, its memory, the OpenCL platform ----
|
||||
Start-Sleep -Seconds 10
|
||||
Adapters 'after'
|
||||
$clAfter = OpenCLList 'after'
|
||||
$intelAfter = @($clAfter | Where-Object { $_ -match 'Intel' })
|
||||
"RESULT opencl_after intel_lines=$($intelAfter.Count)"
|
||||
$found = @()
|
||||
try { $found = @(Get-CimInstance Win32_VideoController -ErrorAction Stop | Where-Object { $_.Name -match 'Intel' } | ForEach-Object { "$($_.Name) driver $($_.DriverVersion) status $($_.Status) code $($_.ConfigManagerErrorCode)" }) } catch { }
|
||||
foreach ($f in $found) { "RESULT intel_device $f" }
|
||||
$versionOk = @($found | Where-Object { $_ -match [regex]::Escape($version) }).Count -gt 0
|
||||
$clinfo = Get-Command clinfo -ErrorAction SilentlyContinue
|
||||
if ($clinfo) { & $clinfo.Source -l 2>&1 | ForEach-Object { "RESULT clinfo $_" } } else { "RESULT clinfo not installed (the worker's --list above is the enumeration)" }
|
||||
$reboot = ($code -eq 14 -or $code -eq 13 -or $code -eq 1014)
|
||||
$status = if ($code -eq 0 -or $code -eq 14 -or $code -eq 1014) { 'done' } else { 'failed' }
|
||||
if ($reboot) {
|
||||
"RESULT restart $(Stamp) the installer asked for a restart (exit $code): restarting PC 2 in 20 s on main's word for PC 2; the read-back job runs after the boot"
|
||||
& "$env:SystemRoot\System32\shutdown.exe" /r /t 20 /c "Igneum: restart to apply the Intel Arc driver 32.0.101.9034 (PC 2 driver job)" 2>&1 | ForEach-Object { "RESULT shutdown $_" }
|
||||
"RESULT restart requested $(Stamp) shutdown_exit=$LASTEXITCODE"
|
||||
}
|
||||
"RESULT end $(Stamp) version_installed=$versionOk reboot_required=$reboot intel_opencl_platform=$($intelAfter.Count -gt 0)"
|
||||
Summary $status @{ version = $version; installer_exit = $code; meaning = $word; reboot_required = $reboot; sha512 = $sha; sha256 = $sha256; intel_devices = $found; intel_opencl_lines = $intelAfter.Count; opencl_intel_before = $intelBefore }
|
||||
if ($status -eq 'failed') { exit 1 }
|
||||
exit 0
|
||||
53
tools/intel-arc/pc2-minidump.ps1
Normal file
53
tools/intel-arc/pc2-minidump.ps1
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# Igneum run job: the kernel minidump of PC 2's 16:27Z crash (7 October 2026, bugcheck 0x3B during the Intel Arc driver
|
||||
# install) out through the signed channel, read only, NOT elevated, beside the miners: no api/* request, nothing switched.
|
||||
# The log intake carries text (the last 256 KB of a file), so the 2 MB dump is copied into the app's jobs folder as
|
||||
# base64 chunks under 180,000 bytes each with a sha256 per chunk in the job's own folder; the collect job that follows uploads them by glob and
|
||||
# the Mac reassembles and parses the triage dump (bugcheck, exception record, driver list, the faulting module).
|
||||
# The header's own facts are printed here as well (DUMP_HEADER64: bugcheck code and parameters, TRIAGE_DUMP64 counts).
|
||||
$ErrorActionPreference = 'Continue'
|
||||
function Stamp { (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ') }
|
||||
"RESULT start $(Stamp) job=pc2-minidump machine=$env:COMPUTERNAME user=$env:USERNAME"
|
||||
$dir = 'C:\WINDOWS\Minidump'
|
||||
try { foreach ($f in @(Get-ChildItem -LiteralPath $dir -File -ErrorAction Stop | Sort-Object LastWriteTime)) { "RESULT minidump_dir file=`"$($f.Name)`" bytes=$($f.Length) written=$($f.LastWriteTime.ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ'))" } } catch { "RESULT minidump_dir error=$($_.Exception.Message)" }
|
||||
$src = Join-Path $dir '100726-22234-01.dmp'
|
||||
# the chunks land in the job's own folder (made by the app for this run), never in another job's kit
|
||||
$out = $env:IGNEUM_JOB_DIR; if (-not $out) { $out = Join-Path $env:TEMP 'ia-minidump-20261007' }
|
||||
try {
|
||||
$bytes = [System.IO.File]::ReadAllBytes($src)
|
||||
$sha = (Get-FileHash -LiteralPath $src -Algorithm SHA256).Hash.ToLower()
|
||||
"RESULT dump file=`"$src`" bytes=$($bytes.Length) sha256=$sha"
|
||||
# DUMP_HEADER64: Signature 'PAGE' ValidDump 'DU64'; BugCheckCode at 56, parameters at 64..95; the triage block at 0x2000
|
||||
$sig = [System.Text.Encoding]::ASCII.GetString($bytes, 0, 8)
|
||||
$code = [BitConverter]::ToUInt32($bytes, 56)
|
||||
$p = @(0..3 | ForEach-Object { [BitConverter]::ToUInt64($bytes, 64 + 8 * $_) })
|
||||
$machine = [BitConverter]::ToUInt32($bytes, 48); $cpus = [BitConverter]::ToUInt32($bytes, 52)
|
||||
$major = [BitConverter]::ToUInt32($bytes, 8); $minor = [BitConverter]::ToUInt32($bytes, 12)
|
||||
$dumpType = [BitConverter]::ToUInt32($bytes, 0xf98)
|
||||
"RESULT header signature=`"$sig`" version=$major.$minor machine=0x$($machine.ToString('x')) cpus=$cpus dump_type=$dumpType bugcheck=0x$($code.ToString('x8')) p1=0x$($p[0].ToString('x')) p2=0x$($p[1].ToString('x')) p3=0x$($p[2].ToString('x')) p4=0x$($p[3].ToString('x'))"
|
||||
if ($bytes.Length -gt 0x2000 + 80) {
|
||||
$t = 0x2000
|
||||
$names = 'ServicePackBuild', 'SizeOfDump', 'ValidOffset', 'ContextOffset', 'ExceptionOffset', 'MmOffset', 'UnloadedDriversOffset', 'PrcbOffset', 'ProcessOffset', 'ThreadOffset', 'CallStackOffset', 'SizeOfCallStack', 'DriverListOffset', 'DriverCount', 'StringPoolOffset', 'StringPoolSize', 'BrokenDriverOffset', 'TriageOptions'
|
||||
$line = @(); for ($i = 0; $i -lt $names.Count; $i++) { $line += "$($names[$i])=$([BitConverter]::ToUInt32($bytes, $t + 4 * $i))" }
|
||||
"RESULT triage $($line -join ' ') TopOfStack=0x$([BitConverter]::ToUInt64($bytes, $t + 72).ToString('x'))"
|
||||
}
|
||||
New-Item -ItemType Directory -Force -Path $out | Out-Null
|
||||
Get-ChildItem -LiteralPath $out -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue
|
||||
$chunk = 135000 # raw bytes per chunk: 180,000 base64 bytes, under the intake's 256 KB tail
|
||||
$n = [math]::Ceiling($bytes.Length / $chunk)
|
||||
for ($i = 0; $i -lt $n; $i++) {
|
||||
$len = [math]::Min($chunk, $bytes.Length - $i * $chunk)
|
||||
$b64 = [Convert]::ToBase64String($bytes, $i * $chunk, $len, [System.Base64FormattingOptions]::InsertLineBreaks)
|
||||
$name = Join-Path $out ('dump-{0:d3}.b64' -f $i)
|
||||
[System.IO.File]::WriteAllText($name, "CHUNK $i of $n bytes=$len`r`n$b64`r`nEND $i`r`n", [System.Text.Encoding]::ASCII)
|
||||
$h = (Get-FileHash -LiteralPath $name -Algorithm SHA256).Hash.ToLower()
|
||||
"RESULT chunk i=$i of=$n raw_bytes=$len file_bytes=$((Get-Item -LiteralPath $name).Length) sha256=$h"
|
||||
}
|
||||
"RESULT end $(Stamp) chunks=$n dir=`"$out`""
|
||||
'SUMMARY ' + ([ordered]@{ job = 'pc2-minidump'; status = 'done'; finished_at = (Stamp); bytes = $bytes.Length; sha256 = $sha; chunks = $n } | ConvertTo-Json -Compress)
|
||||
exit 0
|
||||
} catch {
|
||||
"RESULT dump error=$($_.Exception.Message)"
|
||||
"RESULT end $(Stamp) chunks=0"
|
||||
'SUMMARY ' + ([ordered]@{ job = 'pc2-minidump'; status = 'partial'; finished_at = (Stamp); error = $_.Exception.Message } | ConvertTo-Json -Compress)
|
||||
exit 0
|
||||
}
|
||||
Loading…
Reference in a new issue