Coverage - #347
Merged
Merged
Conversation
|
An automated preview of the documentation is available at https://347.corosio.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-09-06 03:29:28 UTC |
|
GCOVR code coverage report https://347.corosio.prtest3.cppalliance.org/gcovr/index.html Build time: 2026-09-06 03:43:47 UTC |
Service shutdown closes impls one at a time, so a queued pipe write can execute against a reader the same shutdown already closed. The kernel raises thread-directed SIGPIPE at the next kernel entry, which kills any process that has not ignored the signal, even though the CQE already reports EPIPE. Block and consume the signal around the close and ring-teardown paths that can run such a write.
…aths Coverage analysis surfaced reactor paths no execution can reach: the per-descriptor cancel-pending flags nothing ever sets, the datagram connect EINPROGRESS parking a datagram connect never enters, and the private-queue drains -- along with the do_one check that guarded them -- that work_cleanup and task_cleanup make dead by splicing the private queue to the global queue after every handler and every reactor pass. The cleanup guards' own null-context branches are dead too: do_one is their only source of a context and always passes a live frame. Remove them rather than carry dead branches.
…arms A cpp_new arm makes the nth allocation on the armed thread report bad_alloc through replaced global allocation functions; no interposition is needed, so the entry is live on every platform. Covers the pool's spawn-allocation recovery, its refusal propagation through the file service, and select's registry-growth ENOMEM arm. The timer rearm and server launch-frame guards sit behind pooled or boundary allocations no deterministic ordinal reaches; their sweeps exercise robustness and the arms stay on the residual list.
pthread_create reports through its return value, so the shadow hands back the armed error directly and std::thread construction surfaces it as system_error. The pool's first post then reports the refusal through the operation, leaves no latched state, and the next post spawns the worker normally.
Shadow the OpenSSL entry points the TLS engine calls -- the credential BIOs, context and session allocation, session reset, hostname pinning, and input staging -- with opaque C signatures that need no OpenSSL headers. Arming each drives the engine's refusal arms: the credential decoder, the poisoned-cache stickiness, the reset and hostname-setup refusals, and the staging-full retry. The entries are gated to Linux, where the coverage badge is measured; elsewhere the RTLD_NEXT lookup has nothing to bind and hook_is_live reports them not live so the TLS fault suite skips.
Windows spawns its threads through _beginthreadex in the CRT, not pthread_create, so the POSIX thread entry never fires there. Patch the CRT's import thunk and expose the same fault, then cover the one place it surfaces cleanly under a bounded run: the wait reactor's first wait spawns its WSAPoll thread, and a spawn refusal must complete the wait with resource_unavailable_try_again rather than hang.
uring_sqe_full clamps at ring creation; uring_sq_fill exhausts a normally sized ring at a chosen moment instead. While armed, the next liburing call pushes the user-side tail to capacity — reversibly, with submit a no-op so nothing fake reaches the kernel — and the first call after the scope dies restores it. Covers ring construction tearing down and throwing when the wakeup poll cannot get an SQE, best-effort cancellation when the queue stays full through its flush-and-retry, the multishot arm failure path, the terminated-poll re-arms for the wakeup eventfd and the signal pipe (in a run and in the teardown drain), and the re-arm a terminated accept multishot posts. Composed arms taught the shadows to rewrite visible completions even while the fill holds the queue shut.
Each exclusion states why the arm cannot execute: callers pre-check, eager validation upstream, vtable completeness, a second net behind a layer that reports first, or an interface no path on the platform drives. An exclusion is a reviewed assertion of unreachability, not a waiver; deleting the arm was preferred wherever an interface or a platform twin did not require it to stay.
The engine's OpenSSL calls leave the corosio_openssl DLL through its import table; collect_modules already snapshots that satellite, so adding the OpenSSL entry points to the Windows hook table lets the patcher intercept them. Link the engine into the CMake Windows fault target (the coverage legs are CMake) and un-gate the TLS fault suite for Windows; a build without the engine loaded leaves the hooks unbound and the suite skips via hook_is_live.
The OpenSSL shadows were confined to Linux because the main-library rebinder could not reach them: the engine's calls leave through the libboost_corosio_openssl satellite dylib, not the main image. Give the satellite its own rebinding pass, keyed off its dyld image index, that resolves each real entry through dlsym and rewrites the matching import slots. The pass is fail-soft: an entry that cannot be resolved or rebound is left not live, so the TLS fault suite skips it rather than any suite in the binary dying. The main pass now skips the OpenSSL names and the satellite pass owns their census_live.
do_one, run_task, and the work_cleanup / task_cleanup guards all receive the running thread's context frame, which is never null: do_one is only ever entered with a live frame from run/run_one/poll. Typing it as a reference makes that invariant hold in the type system rather than by convention, so no caller can pass null and no guard needs a null check. The nullable lookup, reactor_find_context, keeps its pointer.
testReleaseDropsPreacceptedConnections re-binds the same acceptor to an ephemeral port and depends on it differing from the released one so the accept can tell the new listener from the old. SO_REUSEADDR lets the kernel hand the just-freed port straight back, so retry the ephemeral bind until it lands on a different port instead of asserting the first result is different.
The IPv6 leave-group option's level, name, size, and byte layout were only reachable through a live multicast join, which the coverage host cannot route, so those pure accessors went unmeasured. Drive them directly against the join-group option's matching traits.
The native stream-file and random-access-file awaitables carry the same resume-time stop check as the sockets, and the acceptors' accept()-> socket overload has its own; none were driven with a stopped token. Add a file resume-cancel case and exercise the socket-returning accept alongside the existing accept-into-peer arm.
sgerbino
force-pushed
the
pr/coverage-tier1
branch
from
September 6, 2026 03:24
bb06a0d to
94e5904
Compare
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.
No description provided.