Repository navigation
fix(evinse): stop atom on timeout or when cdxgen is killed, and read every reachables chunk - #4433
Merged
Merged
Conversation
The atom dispatcher falls back to the jar package when the platform's native package is missing (optional dependencies skipped, a failed download), but cdxgen chose the provider kind from the platform alone. On such an install cdxgen passed -XX:MaxHeapSize as an atom argument and every slice failed with 'Unknown option -XX:MaxHeapSize'. The kind now follows what is installed where cdxgen can see it: the native binary, else the jar package, else the platform's kind. The sub-package lookup also covers pnpm's store layout.
cdxgen's spawn timeout killed only the atom dispatcher, so the runtime under it (the native binary or the JVM) kept running, re-parented, with its heap (#4419). cdxgen now: - passes ATOM_TIMEOUT, just inside its own spawn timeout, so the dispatcher stops the runtime itself; an explicit ATOM_TIMEOUT sets atom's limit independently of CDXGEN_TIMEOUT_MS; - passes ATOM_PARENT_PID, so atom 4's dispatcher and runtime stop when cdxgen is killed; - reports a run that hit a time limit as a timeout, instead of a silent failure or a generic non-zero exit; - removes the half-written atom a stopped run leaves, which the next slice of the same run would otherwise fail to load.
atom writes reachables at most 1000 flows per file (<base>.json, <base>_1.json, ...), but evinse and printReachables read only the base file, so every flow past the first thousand was dropped from the BOM. Chunks are now read until the first gap, a chunk older than the base file (left by an earlier run) ends the sequence, and stale chunks are removed before atom writes a new set.
- A status-1 exit past atom's time limit counts as the legacy dispatcher stopping atom only when atom's output shows no failure of its own (an exhausted heap, a JVM crash, an atom 'Failure:'); any other non-zero status is atom's own exit. - Slices files are read through readSlicesFile, which warns and skips a truncated or malformed file instead of throwing; a bad reachables chunk ends the sequence and keeps the flows read before it. - The chunk scan tolerates a chunk vanishing between the existence check and its stat, and states the assumption behind the mtime slack. - ENV.md: the SIGKILL follow-up is atom 4's, and cdxgen's last-resort kill comes 30 seconds after atom's limit or a quarter of the limit when shorter.
printReachables read .reachables off the result unguarded, so a truncated slices file, which readReachablesSlices now reports and skips, still ended the -p/--print path with a TypeError.
This was referenced Oct 1, 2026
A path containing %s or %o was read as a format specifier. Addresses CodeQL js/tainted-format-string (code scanning alert 945).
… and daemon getImage and exportImage handed their argument to `pull`, `save` and `inspect` (or the daemon API) as given. Inputs that reach exportImage without the isImageReference check, such as anything containing ":latest", could put an option such as `-o<file>` where the image argument goes. Both entry points now require the exact string to be an image reference. No shell is involved: the CLI is spawned with an argument array. Addresses CodeQL js/shell-command-constructed-from-input (code scanning alerts 947 and 948).
prabhu
force-pushed
the
fix/4419-atom-orphan-timeout
branch
from
October 1, 2026 14:29
9f959eb to
8951893
Compare
1.8.0 stops astgen, php-parse, rbastgen and scalasem, with the processes they started, once the process named by ATOM_PARENT_PID is gone.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4419: atom no longer survives cdxgen's timeout, and evinse stops dropping reachables flows.
Root cause. cdxgen spawns the atom dispatcher (
node index.js) on every platform, so the runtime is a grandchild for the native and jar providers alike. The spawn timeout SIGKILLed only the dispatcher, and the runtime was reparented to init.Changes
ATOM_TIMEOUT, just inside cdxgen's own spawn timeout, so the dispatcher stops atom itself. This already works with the pinned atom 3.1.1. An explicitATOM_TIMEOUTgives atom its own limit, independent ofCDXGEN_TIMEOUT_MS.ATOM_PARENT_PID, so atom 4's dispatcher and runtime stop when cdxgen is killed.<base>_N.json). Only the first 1000 flows used to reach the BOM.Unknown option -XX:MaxHeapSize.@appthreat/atom-parsetoolsto 1.8.0 (Stop a helper and its children when its supervisor is gone AppThreat/atom-parsetools#14), so the parsers atom starts stop with it.ENV.md,EVINSE.md,TROUBLESHOOTING.md.CodeQL alerts on master
js/tainted-format-string): thepackage.jsonpath is logged as an argument, not as part of the format string.js/shell-command-constructed-from-input):getImageandexportImagenow pass only well-formed image references topull,save,inspectand the daemon API. No shell was involved, but an option such as-o<file>could take the image argument's place.Related: AppThreat/atom#267, AppThreat/chen#189 (Python reachables hotspots and import resolution), AppThreat/atom-parsetools#14. The complete fix for a killed cdxgen arrives with the atom 4.0.0 bump.
Testing
atomUtils,displayanddockerpoku tests; the full poku suite passes (248 files).CDXGEN_TIMEOUT_MS=5000 evinse -l python --with-reachableson django-oscar, atom outlived cdxgen with PPID 1. After, nothing outlives a cdxgen timeout, on 3.1.1 or 4.0.0. With atom 4.0.0, nothing outlives a SIGKILLed cdxgen either.