# Behavior traces — microsoft/terminal

> Canonical page: https://codevetter.com/unpack/terminal/behavior-traces

# Behavior traces — microsoft/terminal

Scanned commit 7c92ecd037476f957809d0813b14d8bc44bb071a (2026-09-18). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Three load-bearing flows were traced end-to-end. (1) Process startup: wWinMain -> WindowEmperor::HandleCommandlineArgs does mutex-or-WM_COPYDATA handoff, loads settings via AppLogic::ReloadSettings -> CascadiaSettings::LoadAll, restores persisted windows, dispatches the command line into AppHost windows, then pumps a single message loop. (2) New tab: an action (keybinding/menu/CLI) reaches ShortcutActionDispatch::DoAction -> TerminalPage handlers -> _MakePane -> _CreateConnectionFromSettings (ConptyConnection) -> TermControl::_InitializeTerminal -> connection.Start() -> ConPTY + CreateProcessW -> _OutputThread -> TerminalOutput -> Terminal::Write. (3) Settings persistence: a wil::FolderChangeReader on the settings directory triggers ReloadSettingsThrottled -> _TryLoadSettings -> SettingsChanged event, which WindowEmperor and TerminalPage subscribe to for hot-reload of hotkeys, themes, and profiles.
- Startup step 1 (pre-XAML): wWinMain registers TraceLogging, calls SetConsoleCtrlHandler(NULL,FALSE) to unbreak inherited ^C state, EnsureNativeArchitecture() to refuse wrong-arch binaries, EnableMouseInPointer(true), then winrt::init_apartment(single_threaded) — explicitly load-bearing for UIAutomation correctness per the comment. — [src/cascadia/WindowsTerminal/main.cpp#L85-125](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/main.cpp#L85-L125)
- Startup step 2 (instance arbitration): WindowEmperor::HandleCommandlineArgs builds a branding+elevation+SID-scoped window class name, sets an AUMID for unpackaged runs (_setupAumid with deferred taskbar-pin stamping), then acquireMutexOrAttemptHandoff either wins the mutex or WM_COPYDATA's the serialized invocation to the running instance and TerminateProcess(0)s itself. — [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L472-545](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L472-L545)
- Startup step 3 (app + settings): the emperor creates winrt::TerminalApp::App, calls App.Logic().ReloadSettings() (AppLogic::_TryLoadSettings -> CascadiaSettings::LoadAll -> SettingsLoader pipeline), pre-warms FOLDERID_LocalAppData to avoid an Nvidia loader-lock stall (GH#20348), creates the hidden message window, registers global hotkeys and notification icon, and subscribes to SettingsChanged. — [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L547-574](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L547-L574) [src/cascadia/TerminalApp/AppLogic.cpp#L206-247](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/AppLogic.cpp#L206-L247)
- Startup step 4 (window materialization): persisted layouts are replayed as synthetic 'wt -w new -s <idx>' command lines; then the real argv is dispatched via _dispatchCommandlineCommon -> CreateNewWindow -> AppHost::Initialize; '-Embedding' mode instead arms a 5s handoff timeout; finally a single GetMessageW loop pumps all windows, then _finalizeSessionPersistence runs at exit. — [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L576-641](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L576-L641) [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L643-717](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L643-L717)
- New-tab step 1 (invocation): keybindings go AppKeyBindings -> ActionMap lookup -> ShortcutActionDispatch::DoAction raising the NewTab event; the same dispatch is reused for command-line startup actions, the new-tab flyout items (which embed NewTabArgs with a profile index), and command palette entries. — [src/cascadia/TerminalApp/AppKeyBindings.cpp#L19](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/AppKeyBindings.cpp#L19) [src/cascadia/TerminalApp/ShortcutActionDispatch.cpp#L31-78](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp#L31-L78) [src/cascadia/TerminalApp/TerminalPage.cpp#L1286-1355](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/TerminalPage.cpp#L1286-L1355)
- New-tab step 2 (pane + connection): the NewTab handler builds a pane via _MakePane -> _CreateConnectionFromSettings, which selects ConptyConnection or AzureConnection by profile.ConnectionType(), resolves StartingDirectory against the virtual CWD (for 'wt -w 0 -d .' correctness), packs a ValueSet (commandline, dirs, rows/cols, sessionId, textMeasurement, ambiguousIsWide, inheritCursor, environment) and calls connection.Initialize. — [src/cascadia/TerminalApp/TerminalPage.cpp#L1549-1657](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/TerminalPage.cpp#L1549-L1657)
- New-tab step 3 (terminal bring-up): TermControl::_InitializeTerminal waits for a nonzero SwapChainPanel size, calls ControlCore::Initialize (creates Terminal + AtlasEngine), then _core.Connection().Start() — or _restoreInBackground for restored buffer contents — followed by EnablePainting, scrollbar setup, appearance application, and raising Initialized. — [src/cascadia/TerminalControl/TermControl.cpp#L1376-1456](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalControl/TermControl.cpp#L1376-L1456)
- New-tab step 4 (process + IO): ConptyConnection::Start transitions to Connecting, creates overlapped pipes, ConptyCreatePseudoConsole, _LaunchAttachedClient (CreateProcessW with PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, WSLENV-augmented env, WT_SESSION/WT_PROFILE_ID), ConptyReleasePseudoConsole, then spawns _OutputThread and transitions to Connected; failures emit localized ProcessFailedToLaunch/BadPathText/ElevationRequired text as TerminalOutput and transition to Failed. — [src/cascadia/TerminalConnection/ConptyConnection.cpp#L32-193](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L32-L193) [src/cascadia/TerminalConnection/ConptyConnection.cpp#L400-511](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L400-L511)
- New-tab step 5 (steady state): _OutputThread pipe reads -> TerminalOutput event -> ControlCore::_connectionOutputHandler -> LockForWriting -> Terminal::Write -> StateMachine::ProcessString -> OutputStateMachineEngine Action* -> dispatch -> TextBuffer; scrollback/viewport changes invalidate the AtlasEngine for the next frame. — [src/cascadia/TerminalControl/ControlCore.cpp#L2286-2298](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalControl/ControlCore.cpp#L2286-L2298) [src/cascadia/TerminalCore/Terminal.cpp#L482-484](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalCore/Terminal.cpp#L482-L484) [src/terminal/parser/OutputStateMachineEngine.cpp#L140-166](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/terminal/parser/OutputStateMachineEngine.cpp#L140-L166)
- Settings-reload trace: AppLogic::_RegisterSettingsChange creates a wil::FolderChangeReader on the settings directory watching FileName+LastWriteTime; when settings.json changes, ReloadSettingsThrottled debounces 100ms then _TryLoadSettings -> CascadiaSettings::LoadAll; success raises SettingsChanged (WindowEmperor re-registers global hotkeys/notification icon/persistence; TerminalPage re-binds keybindings), failure keeps the old settings and surfaces _settingsLoadExceptionText. — [src/cascadia/TerminalApp/AppLogic.cpp#L137-160](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/AppLogic.cpp#L137-L160) [src/cascadia/TerminalApp/AppLogic.cpp#L277-417](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/AppLogic.cpp#L277-L417) [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L564-574](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L564-L574)
- First-run fixup trace: when settings.json is absent/empty, LoadAll resets ApplicationState, loads embedded IDR_USER_DEFAULTS, runs ApplyRuntimeInitialSettings + dynamic generators, and WriteSettingsToDisk persists the materialized file; Preview/Canary first try migrating the Release-channel settings.json instead. — [src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L1226-1317](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L1226-L1317)
- Teardown trace: ConptyConnection::Close sets state Closing, resets the HPCON (sends CTRL_CLOSE_EVENT to clients), then loops CancelIoEx + WaitForSingleObject(1000) until the output thread exits — required so TerminalOutput.raise can't hit a dead ControlCore (GH#13880); the code documents three termination 'EXIT POINT's that must not flap each other. — [src/cascadia/TerminalConnection/ConptyConnection.cpp#L17-26](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L17-L26) [src/cascadia/TerminalConnection/ConptyConnection.cpp#L657-700](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L657-L700)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
