mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-16 06:23:23 +09:00
[MG_Pipe, MG_Backend, MG_Remote, MG_Test, scripts] (P7): the Magma wire fatals and the two Staged aborts go through Session::Fail
Five deaths in the split server image raised their own std::abort(). Three of them are funnels - MagmaWireFatal (Renderer/WireFramebuffer.inc), WireDescriptorFatal (Renderer/UniformManager.cpp) and WireBufferLegacyFatal (Renderer/WireDraw.inc) - and the fifteen `@P7` refusals on the tree (8 in UniformManager.cpp, 4 in WireFramebuffer.inc, 2 in WireDraw.inc, 1 in VulkanRenderer.cpp; plan section 1.3's count confirmed) all die through two of them. Every one of those deaths published NO SessionFault frame, so the peer read a bare EOF; bumped NO SessionFaultCount(), so exit gate S8 could neither confirm nor falsify it; and carried a hand-typed family word with no path to FatalFamilies.def's projection. MG_Backend may not name an MG_Remote symbol on its own account, so the route is a seam in MG_Pipe with MGP_TRIP_WIRE_REPORT's shape (PipeApply.cpp:66, and the new code sits beside it): MG_Pipe/PipeSessionFail.h declares MGPipeSessionFail, PipeApply.cpp defines it inside `#if MOBILEGL_BUILD_DISAGGREGATED`, the DEFAULT behaviour is byte-identical to what the three funnels did on their own, and MG_Remote::InstallPipeSessionFailHook() points it at SessionFail. The install is in InitServerRoleCommon (MG_Backend/Init.cpp), step 0, because that is the one function BOTH server roles run - the inproc role and the spawn/TCP session child - so there is no per-transport install to get wrong. MGPipeFatalFamily is a two-value boundary enum, NOT MGFatalFamily cast to an integer: the .def's enumerators are positional and a row inserted in its middle would silently re-point every hook call at a different family. FatalFunnel.cpp's adapter is the one place the two vocabularies meet, as a switch with a named default. The family word stays UnmigratedVerb rather than becoming a new MagmaWireRefusal. Three reasons: the message strings are required to stay byte-identical (5.2), and the retrace refusal censuses recorded since P5b count these deaths by that word - a rename invalidates every `@P7` measurement taken against them; `Magma:` in the detail already separates the Magma arm from the GLES UnmigratedVerb deaths, so a new word adds no discrimination a grep does not have; and its wire projection would be ProtocolCorruption, exactly UnmigratedVerb's. Recorded for the integrator. Ph slice (2) in the same commit: Server/StagedShadow.h's RequireCovered and Server/StagedTextureStore.h's RequireLevelBytes were MGLOG_F + bare abort. Both are inside MG_Remote already, so they call SessionFail directly, message verbatim; check_include_closure.py's four probes do not reach either header and the gate is green. Census: 83 abort sites -> 79 over 20 files (five sites retired, one gained for the seam's no-hook default, which is argued into FUNNEL_SITES), baseline rewritten in this commit - the downward ratchet's notice is what asked for it. Two gate bugs the widening exposed and this commit fixes: the SessionFail call regex also matched `MGPipeSessionFail(` (a lookbehind now), and a funnel's anchor needed a wider window than a marker's (kFunnelAnchorWindow). Red-once, three ways. Pointing MagmaWireFatal back at its own abort reds the census naming WireFramebuffer.inc 0 -> 1. Making the seam skip the hook reds both new death cases - `TheMagmaWireVerbDeathReachesSessionFailAndBumpsTheFaultCount` on the exit code, because it reads SessionFaultCount() out of a SIGABRT handler and gets 0 instead of 1, and `TheSeamHandsTheInstalledHookItsFamilyAndItsLineVerbatim` on the line the hook echoed.
This commit is contained in:
@@ -124,6 +124,10 @@ FUNNEL_SITES = {
|
||||
("#define MGP_TRIP_WIRE_REPORT",
|
||||
"the poison/verify trip-wire funnel: its 30-odd callers each pass MGP_TRIP_WIRE_TAG(name), "
|
||||
"which IS the `Fatal{name}` marker, so the death is named by the caller"),
|
||||
("void MGPipeSessionFail(",
|
||||
"the no-hook default of the backend session-fail seam (MG_Pipe/PipeSessionFail.h): the "
|
||||
"line it logs is the CALLER's, family word and all, and with MG_Remote's hook installed "
|
||||
"this abort is never reached at all"),
|
||||
),
|
||||
"MobileGL/MG_Pipe/generated/PipeWire.inc": (
|
||||
("MGPipeWireProtocolFatal",
|
||||
@@ -138,6 +142,13 @@ FUNNEL_SITES = {
|
||||
# abort it has nothing to do with.
|
||||
kMarkerWindow = 12
|
||||
|
||||
# A FUNNEL'S ANCHOR GETS A WIDER WINDOW THAN A MARKER DOES, and for the opposite reason. A marker
|
||||
# window has to be tight because any `Fatal{` in it silences the abort below; an anchor window can
|
||||
# be loose because the anchor is a specific line of code, argued for by name in the table above,
|
||||
# and the only thing a wider window can reach is the same funnel's own body. Forty covers a funnel
|
||||
# whose signature and abort are separated by its formatting and its explanation.
|
||||
kFunnelAnchorWindow = 40
|
||||
|
||||
MARKER = re.compile(r"Fatal\{([A-Za-z][A-Za-z0-9]*)")
|
||||
REFUSAL = re.compile(r"Refuse\{([A-Za-z][A-Za-z0-9]*)")
|
||||
ABORT = re.compile(r"\bstd::abort\(\)")
|
||||
@@ -145,7 +156,11 @@ WIRE_LOG_FATAL_CALL = re.compile(r"WireLogFatal\s*\(")
|
||||
# P6 dl: a SessionFail call must carry a Fatal{ word in its string, the same rule
|
||||
# WireLogFatal has - the enum and the string both name the family, and a call whose string
|
||||
# forgot it would let the two disagree. Checked everywhere SessionFail is called.
|
||||
SESSION_FAIL_CALL = re.compile(r"SessionFail\s*\(")
|
||||
#
|
||||
# The lookbehind is not decoration: without it this pattern also matches `MGPipeSessionFail(`,
|
||||
# and it reported MG_Pipe's own seam - whose callers carry the word exactly as SessionFail's do -
|
||||
# for being a SessionFail call with no word in its DECLARATION.
|
||||
SESSION_FAIL_CALL = re.compile(r"(?<![A-Za-z0-9_])SessionFail\s*\(")
|
||||
FAMILY_ROW = re.compile(r"^\s*X\(([A-Za-z][A-Za-z0-9]*)\s*,", re.MULTILINE)
|
||||
REFUSE_ENUM = re.compile(r"enum\s+RefuseCode\s*:[^{]*\{(.*?)\}", re.DOTALL)
|
||||
ENUM_VALUE = re.compile(r"^\s*([A-Za-z][A-Za-z0-9]*)\s*=", re.MULTILINE)
|
||||
@@ -245,11 +260,11 @@ def declared_refusals():
|
||||
return set(ENUM_VALUE.findall(block.group(1)))
|
||||
|
||||
|
||||
def sanctioned(rel, window):
|
||||
def sanctioned(rel, anchor_window):
|
||||
"""Is this unmarked abort inside a funnel the tables above sanction?"""
|
||||
if rel in FUNNEL_FILES:
|
||||
return True
|
||||
return any(anchor in window for anchor, _reason in FUNNEL_SITES.get(rel, ()))
|
||||
return any(anchor in anchor_window for anchor, _reason in FUNNEL_SITES.get(rel, ()))
|
||||
|
||||
|
||||
def census():
|
||||
@@ -287,7 +302,8 @@ def census():
|
||||
continue
|
||||
sites.append({"file": rel, "line": index + 1})
|
||||
window = "\n".join(lines[max(0, index - kMarkerWindow):index + 1])
|
||||
if sanctioned(rel, window):
|
||||
anchors = "\n".join(lines[max(0, index - kFunnelAnchorWindow):index + 1])
|
||||
if sanctioned(rel, anchors):
|
||||
continue # rule 2, or an argued funnel entry, covers it
|
||||
if not MARKER.search(window):
|
||||
unmarked.append({"file": rel, "line": index + 1, "text": line.strip()})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"abort_sites": 83,
|
||||
"abort_sites": 79,
|
||||
"abort_sites_by_file": {
|
||||
"MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp": 15,
|
||||
"MobileGL/MG_Backend/DirectGLES/Managers.cpp": 12,
|
||||
@@ -7,22 +7,17 @@
|
||||
"MobileGL/MG_Backend/DirectGLES/Utils.cpp": 1,
|
||||
"MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp": 2,
|
||||
"MobileGL/MG_Backend/DirectVulkan/Renderer/MagmaPipeArms.h": 1,
|
||||
"MobileGL/MG_Backend/DirectVulkan/Renderer/UniformManager.cpp": 1,
|
||||
"MobileGL/MG_Backend/DirectVulkan/Renderer/VkBufferManager.cpp": 11,
|
||||
"MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.inc": 1,
|
||||
"MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.inc": 1,
|
||||
"MobileGL/MG_Backend/Init.cpp": 2,
|
||||
"MobileGL/MG_Backend/MGPipe/PipeInputs.cpp": 3,
|
||||
"MobileGL/MG_Impl/Pipe/PipeFill.cpp": 5,
|
||||
"MobileGL/MG_Impl/Pipe/ResourceTracker.h": 5,
|
||||
"MobileGL/MG_Impl/Pipe/SlotAllocator.cpp": 2,
|
||||
"MobileGL/MG_Pipe/PipeApply.cpp": 3,
|
||||
"MobileGL/MG_Pipe/PipeApply.cpp": 4,
|
||||
"MobileGL/MG_Pipe/PipeRoute.cpp": 7,
|
||||
"MobileGL/MG_Pipe/generated/PipeFilled.inc": 1,
|
||||
"MobileGL/MG_Pipe/generated/PipeWire.inc": 1,
|
||||
"MobileGL/MG_Remote/FatalFunnel.cpp": 1,
|
||||
"MobileGL/MG_Remote/Server/StagedShadow.h": 1,
|
||||
"MobileGL/MG_Remote/Server/StagedTextureStore.h": 1,
|
||||
"MobileGL/MG_Remote/Transport/WireLog.cpp": 1,
|
||||
"MobileGL/MG_State/GLState/BufferState/BufferObject.cpp": 2,
|
||||
"MobileGL/MG_State/GLState/TextureState/MipmapStorage.cpp": 1
|
||||
|
||||
Reference in New Issue
Block a user