rrt/docs/control-loop-atlas/crt-and-process-startup.md

6.3 KiB

CRT and Process Startup

  • Roots: entry at 0x005a313b, CRT helpers in the 0x005a2d..0x005ad4.. range, and app_bootstrap_main at 0x00484440.
  • Trigger/Cadence: single process startup path before shell or engine services exist.
  • Key Dispatchers: startup_init_tls_state, startup_init_file_handle_table, startup_run_init_callback_table, __setenvp, startup_build_argv, ___crtGetEnvironmentStringsA, then app_bootstrap_main.
  • State Anchors: CRT heap and file-handle tables; process environment and argv storage.
  • Subsystem Handoffs: exits the generic CRT path at app_bootstrap_main, which becomes the first RT3-owned coordinator.
  • Local CRT side seams are tighter now too: 0x005a2c30/0x005a2cb0/0x005a2cd8/0x005a2d10 own the global on-exit callback table at 0x00dbb8dc/0x00dbb8d8, 0x005a2d22 is the optional mscoree.dll!CorExitProcess bridge before the normal process-exit tail, 0x005a2dc9/0x005a2e9c/0x005a2ead/0x005a2ebe/0x005a2ecd are the shared exit-cleanup owner plus its four terminate-vs-return and cleanup-vs-skip variants, and 0x005a2d64 is now bounded as the higher init owner that walks fixed callback tables 0x005ed018..0x005ed034 and 0x005ed000..0x005ed014 before registering callback 0x005acaa1 into that dynamic on-exit table. The same startup-owned table path is now tighter internally too: 0x005acaa1 is the fixed callback-table walker over 0x005eab28.., 0x005ac9e7 is the capacity query helper that prefers the local CRT heap fast path over KERNEL32!HeapSize, and 0x005a6649 is the region-descriptor probe under that fast path. The surrounding early-init side is tighter now too: __heap_init 0x005a644d is the real HeapCreate + heap-mode + small-block-heap owner, and startup_run_init_callback_table 0x005aca5d is the fixed startup callback walker over the currently empty 0x005eab20.. band.
  • the adjacent CRT runtime-report seam is explicit now too: 0x005acdb0 is the shared runtime-error or math-error message emitter by code, selecting texts like R6002, R6024, DOMAIN error, SING error, and TLOSS error from 0x0062aac0, then emitting them through the GUI report path or the console WriteFile path. 0x005acf27 is the smaller banner-pair wrapper around that emitter, and 0x005acf60 is the registered floating-point exception dispatcher that translates Windows exception codes into the local runtime math codes before falling back to UnhandledExceptionFilter. The nearby unhandled-exception bridge is grounded now too: 0x005b1ddd is the top-level filter callback that first recognizes the VC++ exception signature before tailing into the previously installed filter, and 0x005b1e23/0x005b1e36 are its install and restore wrappers over SetUnhandledExceptionFilter. The neighboring fatal security-report owner 0x005b1c31 is now explicit too: it formats either the buffer-overrun or unknown-security-failure message, appends the current program path, emits that body through the same GUI runtime-report path, and then forces CRT termination. The nearby startup helper 0x005ad0c4 is the common command-line program-name-tail extractor used by the CRT argument path. The adjacent locale-startup strip is grounded now too: 0x005ad524/0x005ad88b/0x005ada1b build, release, and publish the primary 0xb8 locale text record, while 0x005adad9 and 0x005add7f rebuild the narrower active locale-text bands rooted at 0x0062acd4; those owners all materialize their individual fields through 0x005b1a42. The startup-side locale option path is tighter now too: it resolves the older locale selector through 0x005ae9d5, which chooses one LCID pair plus codepage from the incoming locale strings, validates them, and writes the resulting triple into 0x00dba060.
  • the adjacent startup argument and environment seam is explicit now too: 0x005ad1f4 is the shared two-pass command-line parser that counts and optionally copies argv pointers plus bytes while honoring quotes, backslashes, and the multibyte lead-byte table at 0x00dba541. startup_build_argv 0x005ad360 is the owner above it: it chooses either raw command line 0x00dbb8d0 or the cached module-path fallback in 0x00dba1e8, runs that parser once to size the allocation and once to materialize the final table, then stores argc-1 in 0x00dba024 and the argv root in 0x00dba028. On the environment side, ___crtGetEnvironmentStringsA 0x005ad402 materializes one CRT-owned multibyte copy of the Windows environment block using GetEnvironmentStringsW + WideCharToMultiByte when available and GetEnvironmentStringsA otherwise, and __setenvp 0x005ad12d then filters that block into the final envp table by skipping leading-= entries and cloning the admitted name=value strings into 0x00dba030.
  • the broader startup owners above those helpers are tighter now too: startup_init_tls_state 0x005abd49 is the real TlsAlloc + TlsSetValue + per-thread-block bootstrap. Beneath it, startup_init_multithread_lock_table 0x005a649e seeds the fixed CRT lock table from the static lock-storage band at 0x00dba078, startup_release_tls_slot_and_multithread_lock_table 0x005abcba is the shared failure cleanup owner, and the adjacent 0x005a653c/0x005a6551/0x005a65d0 strip now reads cleanly as the generic unlock, lazy-init, and lock-acquire helpers for those CRT multithread slots. The neighboring crt_get_or_create_current_thread_data_preserving_last_error 0x005abcd8 is also grounded now as the older CRT per-thread data getter that allocates a zeroed 0x88-byte record on first use while preserving GetLastError. startup_init_file_handle_table 0x005abf1b is the concrete CRT handle-table owner that seeds the 0x00dba780 descriptor pages, imports inherited handles from STARTUPINFO, grows the table in 0x20-entry chunks, and finally backfills the three standard streams from GetStdHandle plus GetFileType.
  • Evidence: artifacts/exports/rt3-1.06/startup-call-chain.md, artifacts/exports/rt3-1.06/function-map.csv.
  • Current Boundary: the current startup boundary is now carried at app_bootstrap_main. The CRT shims ahead of it still read as compiler-owned bring-up and import plumbing, and the local static pass does not expose any earlier nontrivial game-owned callback that seeds globals before that handoff.