Skip to content

fix(packaging): Windows relocated LoopEditor --quick-smoke - #532

Draft
mberrys wants to merge 34 commits into
devfrom
cursor/fix-windows-quick-smoke-39bd
Draft

fix(packaging): Windows relocated LoopEditor --quick-smoke#532
mberrys wants to merge 34 commits into
devfrom
cursor/fix-windows-quick-smoke-39bd

Conversation

@mberrys

@mberrys mberrys commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes Windows relocated-install smoke failures (0xC0000005) for PdfTool preflight and LoopEditor --quick-smoke during MSI packaging.

Root cause (preflight)

Windows CI stage markers showed PdfTool preflight crashing during PDFDocumentSession construction — after document read (after_read) but before session creation completed (after_session). The fault was in eager initializeRendering(), which creates font/CMS/renderer helpers that preflight does not need (evidence collection builds its own stack).

Fix

  • Lazy rendering init: PDFDocumentSession no longer calls initializeRendering() in its constructor. Rendering helpers are created on first access via getRenderer(), getFontCache(), getCMS(), getOptionalContentActivity(), or compilePage().
  • Prior branch work remains: packaged Qt path fixes, GUI-thread preflight, inspectPreflightFile() inside LoopLibCore, _Exit(0) teardown bypass, quick-smoke fixes, etc.

Verification

  • UnitTestsPreflightCorpus, UnitTestsPreflightEngine, UnitTestsPdfToolContract — pass
  • PdfTool preflight on bleed-adequate.pdf in isolated Qt env — full stage trace through end, exit 0
  • Windows CI pending on latest push (f188b9d6)

Follow-up

Remove temporary loop-pdftool preflight stage= markers from preflightclirun.cpp once Windows_MSI is fully green.

Open in Web Open in Cursor 

cursoragent and others added 12 commits September 4, 2026 16:24
setLibraryPaths() overrides windeployqt's qt.conf beside LoopEditor.exe.
Stop setting library paths on Windows, keep Linux AppImage probing, skip
Sentry on the --quick-smoke fast path, and log staged stderr markers plus
install-tree diagnostics when relocated Windows smoke fails.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Relocated smoke showed qt.conf without Plugins= and no stderr markers,
implicating QPA startup before Quick loads. Mirror PdfTool by copying
qoffscreen into usr/bin/platforms at install time, append Plugins=plugins
to qt.conf, drop attachConsole, and probe --help before --quick-smoke.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Stage markers show the relocated crash happens after QGuiApplication
but before runQuickSmoke returns, while --help exits earlier from the
parser. Route --quick-smoke through settings migration and translator
setup, try the software Quick backend first on Windows, and add logging
through EditorHost construction and QML module load.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Relocated Windows packaging smoke crashes in EditorHost construction
before Quick QML loads. Stage markers stop after QGuiApplication while
--help exits earlier from the parser. The offscreen platform can expose
a primaryScreen() that faults when DPI is queried; use 96dpi defaults
instead, matching headless smoke on Linux AppImage.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Windows packaging smoke still faults in EditorHost because the offscreen
guard only checked platformName(), which can differ from the requested
QT_QPA_PLATFORM value. Treat QT_QPA_PLATFORM=offscreen as headless and
add stage logging through parser, settings, translator, and EditorHost.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Windows relocated packaging smoke faults during EditorHost construction.
Always inject default viewport DPI on Windows instead of probing
primaryScreen(), and emit stderr markers through DocumentViewSession and
EditorHost construction to localize any remaining crash.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Adding usr/bin to QCoreApplication::libraryPaths() on Windows makes Qt treat
product DLLs as plugins and faults during DocumentViewSession construction.
Use packagedLibraryPaths on all platforms and log member-init stages to
localize any remaining relocated smoke crash.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Co-authored-by: michael berry <mberrys@users.noreply.github.com>
The context logging lambda returned PDFDocumentContext by value, which does
not compile because the type is non-copyable.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Windows relocated smoke faults after scheduler_end and before
facade_begin. Initialize CommandCatalog and PDFDocumentContext (with
proper QObject parents) before PDFJobScheduler worker threads start,
and add submitter/catalog/context stage markers for the next CI slice.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Comma-operator member init materialized temporary CommandCatalog and
PDFDocumentContext values and copy-constructed them, which MSVC rejects
as C2280. Keep catalog and context before PDFJobScheduler and log stages
with copy-free InitStage members.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
pwsh does not stop on a nonzero cmake --build, so a C2280 compile error
continued into cmake --install and looked like a missing loop-default.json
smoke failure. Check LASTEXITCODE after configure, build, install, and
surface verification, matching reusable-windows.yml.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
@cursor cursor Bot changed the title fix(packaging): let qt.conf own Windows plugin discovery for Quick smoke fix(packaging): Windows relocated LoopEditor --quick-smoke Sep 4, 2026
cursoragent and others added 17 commits September 5, 2026 00:23
Windows relocated smoke faults between context_begin and context_end when
PDFDocumentContext is parented during DocumentViewSession member init.
Construct the empty context without a parent, setParent in body_begin, and
lazily create the document session on first getSession() so session setup
runs after the view session shell exists.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Windows relocated smoke reaches facade_end then faults before body_begin
while scheduler worker threads are already running during Qt signal wiring.
Defer thread creation until the first submit() so DocumentViewSession member
initialization completes on the main thread without a background race.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Windows relocated smoke reaches body_begin and before surfaces, then faults
inside PageSurfaceCoordinator construction. Prime the empty snapshot after the
view session shell is wired, avoid eager PDFDocumentSession creation while
applying startup cache limits, and add surface-stage markers for the next CI
slice.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Windows relocated smoke reaches after surface_ctor then faults inside
setPageCacheBudget/refreshPageCacheBudget. Store the shared budget during
startup and refresh only after primeInitialSnapshot. Fix clang-format on
pdfjobscheduler.h for agent-fast.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Windows relocated --quick-smoke faulted in setTotal when LoopEditor and
LoopLibInteraction called header-inline mutex methods on a budget object
owned by LoopLibCore. Export the implementations from a single translation
unit like PDFResourceBudget.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Keep trim/rebuild deferred until primeInitialSnapshot while still updating
coordinator limits when a shared PDFPageCacheBudget is attached.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Windows relocated smoke regressed when setPageCacheBudget eagerly read
PDFPageCacheBudget totals from LoopLibInteraction during attach. Keep attach
pointer-only until primeInitialSnapshot, project limits from static partition
math during startup, and route DocumentViewSession cache wiring through
setCacheLimit instead of refreshPageCacheBudget.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Drop staged stderr markers and install-tree probes now that relocated
Windows_MSI smoke is green. Keep the packaging and initialization fixes.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Relocated Windows smoke still faults on native Quick before software on the
packaged tree. Keep software-first ordering as a packaging requirement, not
diagnostic scaffolding.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Windows relocated --quick-smoke still faulted in DocumentViewSession
setCacheLimit when LoopEditor and LoopLibInteraction called
PDFPageCacheBudget::setTotal across the LoopLibCore DLL boundary.

Publish totals via PDFDocumentContext::setPageCacheTotal, defer coordinator
budget writes until priming, and derive coordinator bounds from the local
cacheLimit authority instead of reading the shared budget from
LoopLibInteraction.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Copying std::shared_ptr<PDFPageCacheBudget> from LoopLibCore into
PageSurfaceCoordinator in LoopEditor can corrupt refcounts across the DLL
boundary and fault during relocated --quick-smoke startup.

Attach a non-owning PDFPageCacheBudget* instead and keep temporary stage
markers in quick-smoke until Windows_MSI is green.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Windows relocated smoke faulted inside DocumentViewSession::setCacheLimit
before EditorHost finished constructing. Seed DefaultCacheLimit in
PDFDocumentContext during member initialization and keep startup on projected
coordinator limits until primeInitialSnapshot instead of calling
setPageCacheTotal from the view session constructor.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
primeInitialSnapshot faulted in trimCacheToBudget when
PageSurfaceCoordinator called PDFPageCacheBudget::pageSurfacesLimit from
LoopLibInteraction. Derive surface-byte limits from projected cacheLimit and
bounds instead, and track resident usage from coordinator counters.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Windows relocated smoke reached scene_graph_initialized then faulted during
Qt/Loop DLL teardown. Use std::_Exit(0) after the startup probe succeeds and
install Liberation TTFs under usr/lib/fonts for packaged Qt text.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
PdfTool preflight crashed with 0xC0000005 on relocated Windows installs
because executableDirectory was prepended to libraryPaths(), making Qt treat
product DLLs as plugins during QPA startup. Use the same packagedLibraryPaths
pattern as LoopEditor.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Diagnostic fprintf scaffolding is no longer needed after Windows quick-smoke
passed in CI.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
cursoragent and others added 5 commits September 5, 2026 11:42
Relocated Windows smoke strips developer Qt env vars before PdfTool
preflight. Running PreflightEngine inside a PDFJobScheduler worker thread
faulted with 0xC0000005 before JSON output was emitted. Execute preflight
synchronously on the GUI thread, filter the default exe-dir plugin path on
Windows, install qoffscreen beside PdfTool, and fail fast on preflight in the
isolated-env smoke block.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Allocate PDFDocumentSession from LoopLibCore, leak it on Windows after
preflight completes, and exit with std::_Exit once the JSON envelope is
written so relocated smoke no longer faults during DLL teardown.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Preflight still AV'd on Windows after session teardown fixes because
readFromFile returned a PDFDocument by value into PdfTool.exe. Add heap
read/destroy helpers in LoopLibCore and route preflight through them.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Move file read, session creation, and PreflightEngine::run into
inspectPreflightFile so relocated Windows smoke never owns parsed PDF state
in PdfTool.exe. Add temporary stage markers for CI diagnosis and fix
clang-format drift in pdfdocumentreader.h.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Preflight constructs a PDFDocumentSession without needing font/CMS/renderer
helpers because evidence collection builds its own rendering stack. Eager
initializeRendering() in the constructor was crashing on Windows between the
after_read and after_session preflight markers. Lazy initialization keeps
session construction lightweight for CLI preflight while preserving existing
behavior for editor rendering paths.

Co-authored-by: michael berry <mberrys@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants