Skip to content

Wire captureDenials to Windows Learning Mode runtime - #696

Open
richiemsft wants to merge 12 commits into
mainfrom
user/saulg/learning-mode-endtoend
Open

Wire captureDenials to Windows Learning Mode runtime#696
richiemsft wants to merge 12 commits into
mainfrom
user/saulg/learning-mode-endtoend

Conversation

@richiemsft

@richiemsft richiemsft commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

📖 Description

Wires the merged processContainer.captureDenials contract to the Windows Learning Mode runtime for the BaseContainer tier.

  • Maps mode: "block" to learningModeLogging and mode: "allow" to permissiveLearningMode after rejecting user-supplied reserved capability names.
  • Enforces one effective mode: allow removes deny-and-record before injecting permissive mode.
  • Loads the process security-environment and Learning Mode trace APIs, starts capture before the child launches, launches through CreateProcessAsUserInsideSecurityEnvironment, and seals the ETL after exit.
  • Uses the caller-provided outputPath or a managed per-run temporary ETL path.
  • Fails closed when the host APIs are unavailable or fallback would select classic AppContainer, which cannot honor captureDenials.

🔗 References

🔍 Validation

  • cargo check --workspace --all-targets
  • cargo clippy --workspace --all-targets -- -D warnings
  • Targeted wxc_common capture-denials and appcontainer_common tests
  • Schema/codegen/config validation gates
  • Feature-enabled Windows VM:
    • block: exit 0, 512-byte ETL
    • allow: exit 0, 2,036-byte ETL, always-visible permissive security warning

✅ Checklist

📋 Issue Type

  • Bug fix
  • Feature
  • Task

GitHub Actions runs the PR validation build automatically. The ADO pipeline
(MXC-PR-Build) is the Azure version of the PR pipeline, kept in parity with the GitHub
Actions build; it runs on merge to main, and Microsoft reviewers with write access can trigger it
on a PR with /azp run. See docs/pull-requests.md.

If the dependency-feed-check check fails on a new dependency, the crate must be added to
the feed before the PR can pass. See docs/pull-requests.md
for the steps.

Microsoft Reviewers: Open in CodeFlow

Copilot AI review requested due to automatic review settings July 28, 2026 20:29
@richiemsft
richiemsft requested a review from a team as a code owner July 28, 2026 20:29
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Connects captureDenials to Windows Learning Mode for BaseContainer execution.

Changes:

  • Injects mode-specific Learning Mode capabilities.
  • Adds ETL capture lifecycle around BaseContainer processes.
  • Rejects unsupported AppContainer fallback.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/core/wxc_common/src/config_parser.rs Maps capture modes to capabilities and adds tests.
src/Cargo.lock Records the Learning Mode dependency.
src/backends/appcontainer/common/src/base_container_runner.rs Implements capture launch and ETL teardown.
src/backends/appcontainer/common/src/appcontainer_runner.rs Rejects capture on fallback tiers.
src/backends/appcontainer/common/Cargo.toml Adds the Learning Mode crate dependency.

Comment thread src/backends/appcontainer/common/src/base_container_runner.rs Outdated
Comment thread src/backends/appcontainer/common/src/base_container_runner.rs Outdated
Comment thread src/core/wxc_common/src/config_parser.rs
Copilot AI review requested due to automatic review settings July 28, 2026 21:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (4)

src/backends/appcontainer/common/src/base_container_runner.rs:1089

  • Failures from this new call flow into the shared error block, which still reports Experimental_CreateProcessInSandbox failed in both the log and extended_error. That API was not invoked on this branch, so diagnostics point developers at the wrong operation. Track which launch API was used and report CreateProcessAsUserInsideSecurityEnvironment for this path.
            let ok = unsafe {
                launch(
                    HANDLE(ptr::null_mut()), // userToken: caller context
                    ptr::null(),             // applicationName (from command line)
                    cmd_wide.as_mut_ptr(),   // commandLine

src/backends/appcontainer/common/src/base_container_runner.rs:1062

  • A host can expose these symbols while the feature is disabled, in which case CaptureSession::begin returns ApiCall with ERROR_CALL_NOT_IMPLEMENTED/E_NOTIMPL. This path hardcodes LaunchFailed, unlike the existing processmodel launch path that classifies those codes as BackendUnavailable, so callers receive the wrong typed failure for an unsupported host. Preserve the API error code and apply the same unavailable classification here.
                    return Err(ScriptResponse {
                        exit_code: -1,
                        error_message: msg.clone(),
                        standard_err: msg,
                        failure_phase: FailurePhase::LaunchFailed,

src/backends/appcontainer/common/src/base_container_runner.rs:681

  • This availability check runs only during spawn_base, but ScriptRunner::run skips spawning for dry_run after calling BaseContainerRunner::validate. Consequently, --dry-run reports “validation passed” on a host where BaseContainer exists but these capture exports are unavailable, even though the same request immediately fails at runtime. Include the capture API availability check in backend validation (ideally through a shared helper to avoid drifting checks).

This issue also appears in the following locations of the same file:

  • line 1058
  • line 1085
        if capture_denials.is_some() {
            let _ = writeln!(logger, "{EMOJI_SECTION} SECTION: captureDenials");
            match (SecurityEnvironmentApi::load(), LearningModeApi::load()) {

src/core/wxc_common/src/config_parser.rs:834

  • This does not preserve mode: "block" after CLI processing. main.rs:1069 later applies --audit by removing learningModeLogging and injecting permissiveLearningMode, while capture_denials.mode remains Block; the capture therefore runs allow-all despite its deny-and-record mode. Reject the --audit + captureDenials combination or synchronize the capture mode during the post-parse CLI mutation.
                CaptureDenialsMode::Block => {
                    policy.capabilities.retain(|capability| {
                        !capability.eq_ignore_ascii_case("permissiveLearningMode")
                    });
                    "learningModeLogging"

@richiemsft

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@richiemsft richiemsft mentioned this pull request Jul 28, 2026
8 tasks
Copilot AI review requested due to automatic review settings July 28, 2026 23:25
@richiemsft
richiemsft force-pushed the user/saulg/learning-mode-endtoend branch from dccad10 to 0fcce52 Compare July 28, 2026 23:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/backends/appcontainer/common/src/base_container_runner.rs:1096

  • This branch launches with CreateProcessAsUserInsideSecurityEnvironment, but the shared failure path at line 1202 still reports Experimental_CreateProcessInSandbox failed. Any capture-specific launch failure is therefore attributed to the wrong API, obscuring diagnosis of the new path. Track which launch API was used and format the failure with its actual name.
            let ok = unsafe {
                launch(
                    HANDLE(ptr::null_mut()), // userToken: caller context
                    ptr::null(),             // applicationName (from command line)
                    cmd_wide.as_mut_ptr(),   // commandLine
                    current_creation_flags,  // creationFlags
                    current_env_ptr,         // environment
                    cwd_ptr,                 // currentDirectory
                    &si,                     // startupInfo
                    session.environment(),   // process security environment
                    &mut pi,                 // processInformation
                )

Comment thread src/core/wxc_common/src/config_parser.rs
@richiemsft richiemsft mentioned this pull request Jul 28, 2026
8 tasks
Copilot AI review requested due to automatic review settings July 28, 2026 23:37
@richiemsft
richiemsft force-pushed the user/saulg/learning-mode-endtoend branch from 0fcce52 to 45a8451 Compare July 28, 2026 23:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/backends/appcontainer/common/src/base_container_runner.rs:681

  • This availability check runs only inside spawn_base, but ScriptRunner::run returns success for dry_run immediately after validate_runner. Since BaseContainerRunner::validate checks only the one-shot BaseContainer API, dry-run incorrectly succeeds on hosts that have BaseContainer but lack these newer capture APIs. Include both Learning Mode API probes in runner validation when capture_denials is set, then reuse or reload them during spawn.
            match (SecurityEnvironmentApi::load(), LearningModeApi::load()) {

src/backends/appcontainer/common/src/base_container_runner.rs:1641

  • A trace-seal error returned here becomes the generic non-timeout wait error in sandbox_process.rs:434, which constructs ScriptResponse::error with the default FailurePhase::None. Consequently a post-launch capture failure is serialized and telemetered as having no failure phase. Preserve a typed post-launch error or update the runner mapping so this path reports FailurePhase::PostLaunchFailed.
        let teardown_result = self.run_teardown();
        combine_process_and_teardown_results(result, teardown_result)

src/backends/appcontainer/common/src/base_container_runner.rs:1086

  • Failures from this new launch call still enter the shared error block below, which labels the extended error as Experimental_CreateProcessInSandbox failed. For capture runs that API was never called, so diagnostics point developers at the wrong export. Track which launch function was used and report CreateProcessAsUserInsideSecurityEnvironment here.
                launch(

Copilot AI review requested due to automatic review settings July 29, 2026 16:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/backends/appcontainer/common/src/base_container_runner.rs:1516

  • A terminal try_wait() does not call this teardown path. Public streaming callers (Sandbox::try_wait and mxc_sandbox_try_wait) can therefore observe that the child exited while the ETL is still unsealed and the trace/security-environment remain live until a later wait() or handle drop. Finalize through the same tree-kill/reap/teardown path when try_wait observes WAIT_OBJECT_0, so completion means the requested output is ready.
        // Seal the learning-mode ETL trace now that the child has exited and
        // been reaped (both `wait` and `Drop` kill + reap before calling this).
        // `finish` stops the trace to the resolved output path, then closes the
        // security environment. The output-file path is surfaced on stderr so a
        // caller can locate the denials (the full NDJSON contract is finalized
        // in the output/consume stage).

src/backends/appcontainer/common/src/base_container_runner.rs:1077

  • If this new launch call returns FALSE, the shared failure branch still reports Experimental_CreateProcessInSandbox failed, even though that API was not called. Carry the selected launch API name into the failure path and report CreateProcessAsUserInsideSecurityEnvironment here; otherwise captureDenials failures point operators at the wrong API.
        // The launch yields (api_return_code, last_win32_error_on_failure).
        let (success, last_error) = if let (Some(session), Some(se_api)) =
            (capture_session.as_ref(), capture_se_api.as_ref())
        {
            // Single-attempt in-environment launch. The learning-mode security
            // environment only exists on builds that support the `environment`
            // parameter, so the CreateProcessInSandbox env-not-supported retry
            // does not apply here.
            pi = unsafe { std::mem::zeroed() };

src/backends/appcontainer/common/src/base_container_runner.rs:1065

  • This early return occurs after the tracking entry and Ctrl-C cleanup registration are installed, and possibly after the builtin proxy starts, but it does not undo any of them. CaptureSession::begin cleans its own partial environment, but the runner state remains registered/leaked in a long-lived streaming host. Mirror the later launch-failure cleanup before returning.
                Err(e) => {
                    let msg = format!("captureDenials: failed to start learning-mode capture: {e}");
                    let _ = writeln!(logger, "Error: {msg}");
                    return Err(ScriptResponse {
                        exit_code: -1,
                        error_message: msg.clone(),
                        standard_err: msg,
                        failure_phase: FailurePhase::LaunchFailed,
                        ..Default::default()

Comment thread src/backends/appcontainer/common/src/base_container_runner.rs
Copilot AI review requested due to automatic review settings July 29, 2026 18:36
@richiemsft
richiemsft force-pushed the user/saulg/learning-mode-endtoend branch from 7a7c8ef to 07da288 Compare July 29, 2026 18:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

src/backends/appcontainer/common/src/base_container_runner.rs:1602

  • try_wait() now tears down every BaseContainer run, even when captureDenials is not configured. Once the foreground process signals, terminate_and_reap() terminates the job and therefore kills background descendants; the AppContainer implementation still only reports the exit code, and callers may rely on the existing streaming/grace-window behavior. Restrict this eager teardown to capture sessions (or a previously cached capture result) so ordinary BaseContainer polling remains non-destructive.
                self.terminate_and_reap();
                let teardown_result = self.run_teardown();
                combine_process_and_teardown_results(Ok(code as i32), teardown_result).map(Some)

src/backends/appcontainer/common/src/base_container_runner.rs:681

  • The required security-environment and trace exports are checked only inside spawn_base(). ScriptRunner::run() returns success for a dry run immediately after BaseContainerRunner::validate(), so --dry-run reports “validation passed” on hosts where captureDenials will always fail as BackendUnavailable. Reuse this API availability check from validate() whenever capture is requested, while keeping the loaded handles for the real spawn path if desired.

This issue also appears on line 1600 of the same file.

        if capture_denials.is_some() {
            let _ = writeln!(logger, "{EMOJI_SECTION} SECTION: captureDenials");
            match (SecurityEnvironmentApi::load(), LearningModeApi::load()) {

Copilot AI review requested due to automatic review settings July 29, 2026 18:42
Copilot AI review requested due to automatic review settings July 29, 2026 21:57
@richiemsft
richiemsft force-pushed the user/saulg/learning-mode-endtoend branch from 9b27698 to c7a335c Compare July 29, 2026 21:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/backends/appcontainer/common/src/base_container_runner.rs:1546

  • CaptureSession::finish also returns errors from CloseProcessSecurityEnvironment. If stopping the trace succeeds but closing the environment fails, the ETL has been sealed, so this message incorrectly reports a sealing failure. Use teardown wording here (or distinguish stop and close failures) so callers know whether the output may be valid.
                Err(error) => Err(std::io::Error::other(format!(
                    "captureDenials failed to seal the denial trace: {error}"
                ))),

Remove unlaunched profiles and tracking after safe capture-init failures, retain deferred recovery state when environment or profile cleanup cannot be proven complete, and stop registered cleanup state.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
Copilot AI review requested due to automatic review settings July 29, 2026 22:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/backends/appcontainer/common/src/base_container_runner.rs:1055

  • The capture session stays alive on the new launch path until spawn_base returns. Both the launch-failure handler (lines 1215–1270) and job-setup failure handler (lines 1311–1351) call run_sandbox_cleanup before that drop, so profile deletion runs while the process security environment is still open. cleanup_sandbox then removes the tracking key even if profile deletion fails, leaving an orphan with no recovery record. Explicitly discard/close the capture session before profile cleanup, and retain/mark the tracking entry deferred if closing fails.
        // normal path. On any early return below, `capture_session` drops and its
        // Drop discards the trace and closes the environment (no broker leak).
        let mut capture_session: Option<CaptureSession> = None;

src/backends/appcontainer/common/src/base_container_runner.rs:1115

  • Capture launches still use the shared failure handler below, which hard-codes Experimental_CreateProcessInSandbox failed in extended_error. When this branch fails, the actual API was CreateProcessAsUserInsideSecurityEnvironment, so diagnostics identify the wrong failing operation. Track the selected launch API and use its name in the failure message.
        // The launch yields (api_return_code, last_win32_error_on_failure).
        let (success, last_error) = if let (Some(session), Some(se_api)) =
            (capture_session.as_ref(), capture_se_api.as_ref())

src/backends/appcontainer/common/src/appcontainer_runner.rs:1314

  • This rejection occurs in backend validation, but fallback selection has already run by then. select_backend_with_fallback applies Tier 2/3 DACL changes before ScriptRunner::run calls this method (and before streaming spawn calls it), so an unsupported captureDenials request with filesystem rules can mutate host ACLs before failing. Reject capture during tier selection before constructing/applying any fallback DACL manager.
        if request.policy.capture_denials.is_some() {
            let msg = "captureDenials requires the BaseContainer learning-mode APIs and is not \
                       supported by the AppContainer fallback tier";
            return Err(ScriptResponse {
                failure_phase: FailurePhase::BackendUnavailable,
                ..ScriptResponse::error(msg)
            });

Comment thread src/backends/appcontainer/common/src/appcontainer_runner.rs Outdated
Comment thread src/backends/appcontainer/common/src/sandbox_tracking.rs Outdated
Comment thread src/core/wxc/src/main.rs Outdated
Comment thread src/core/wxc_common/src/config_parser.rs
Comment thread src/backends/appcontainer/common/src/base_container_runner.rs Outdated
Comment thread src/backends/appcontainer/common/src/base_container_runner.rs Outdated
Comment thread src/backends/appcontainer/common/src/base_container_runner.rs Outdated
Comment thread src/backends/appcontainer/common/src/base_container_runner.rs Outdated
Comment thread src/backends/appcontainer/common/src/base_container_runner.rs Outdated
Select an unstamped AppContainer backend for unsupported captureDenials fallback so normal validation emits the structured backend-unavailable response without modifying host ACLs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
Copilot AI review requested due to automatic review settings July 30, 2026 01:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

src/backends/appcontainer/common/src/base_container_runner.rs:1097

  • CaptureSession::begin has not been given identity—the security-environment API receives only spec_bytes—so this failure path cannot have created an AppContainer profile with that name. cleanup_unlaunched_sandbox therefore attempts to delete a nonexistent profile and retains/marks the tracking entry deferred when deletion fails, leaving a stale registry entry after each capture-initialization failure. Remove the tracking entry directly here (or treat profile-not-found as successful cleanup) rather than requiring deletion of an unrelated named profile.
                            sandbox_tracking::cleanup_unlaunched_sandbox(
                                &identity,
                                &sid_string,
                                logger,
                            );

docs/learning-mode/capabilities.md:91

  • This now directs users to captureDenials.mode: "allow", but the runtime added by this PR rejects AppContainer fallback and requires feature-enabled BaseContainer security-environment/Learning Mode APIs. The user-facing docs still describe captureDenials only as “Windows-only,” so many Windows hosts will unexpectedly receive BackendUnavailable. Document this host/backend requirement alongside the recommendation.
   It is also mutually exclusive with `captureDenials`; use
   `captureDenials.mode: "allow"` for permissive application-driven capture.

Reuse diagnostic constants, clarify capture API naming and policy matching, extract the environment fallback launch loop, and document the explicit pre-launch cleanup lifecycle.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
Copilot AI review requested due to automatic review settings July 30, 2026 05:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

src/backends/appcontainer/common/src/base_container_runner.rs:282

  • This failure branch also receives an empty sid_string when SID derivation failed. mark_cleanup_deferred then opens TRACKING_BASE\\ and writes CleanupDeferred on the shared mappings key, not a per-sandbox entry. Skip the marker when no tracking SID exists.
            if learning_mode_cleanup_failed(error) {
                sandbox_tracking::mark_cleanup_deferred(
                    sid_string,
                    CAPTURE_SECURITY_ENVIRONMENT_CLEANUP_DEFERRED_REASON,
                    logger,
                );

src/backends/appcontainer/common/src/base_container_runner.rs:1229

  • When this new in-environment launch returns FALSE, the shared failure path still reports Experimental_CreateProcessInSandbox failed. That API was not called for capture requests—the failing call is CreateProcessAsUserInsideSecurityEnvironment—so diagnostics point operators at the wrong host surface. Carry the selected API name into the common error construction or emit a branch-specific extended error.
            if ok != 0 {
                (ok, None)
            } else {
                (0, Some(unsafe { GetLastError() }))

Comment thread src/backends/appcontainer/common/src/sandbox_tracking.rs Outdated
Copilot AI review requested due to automatic review settings July 30, 2026 05:23
Guard tracking operations without a SID, remove only safe pre-launch tracking state, report the actual capture launch API, and document the feature-enabled BaseContainer requirement.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
@richiemsft
richiemsft force-pushed the user/saulg/learning-mode-endtoend branch from 61aebbc to 28b4572 Compare July 30, 2026 05:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/backends/appcontainer/common/src/base_container_runner.rs:852

  • This changes the merged #663 contract and contradicts this PR’s description: outputPath was documented as the exact caller-controlled ETL destination, but it is now a JSON filename template whose actual path is rewritten. Existing callers waiting on the configured path will never find it and must instead parse stderr. Either preserve the exact-path contract or explicitly version/rename the new contract and update the PR description and validation notes.
            })
            .transpose()?;

        let _ = writeln!(logger, "{EMOJI_SECTION} SECTION: Load API");

        // 2. Dynamically load the API from processmodel.dll.
        let create_process_in_sandbox = match Self::load_api() {

Copilot AI review requested due to automatic review settings July 30, 2026 05:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/backends/appcontainer/common/src/base_container_runner.rs:1685

  • try_wait is documented as a non-blocking observation, but this call invokes kill_process_tree() through terminate_and_reap(). If the root has exited while a background descendant is still running, merely polling with try_wait now terminates that descendant whenever capture is enabled; the same API without capture only reports the root exit. Finalization needs to avoid adding a tree-kill side effect to try_wait (or the API contract must be redesigned explicitly).
                self.terminate_and_reap();

@richiemsft

Copy link
Copy Markdown
Contributor Author

Made a few mistakes with the stack tracking:
#709 is the old #699
#710 is the old #701

@richiemsft

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

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.

4 participants