mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-08 10:33:24 +09:00
[MG_Remote] (P6/hs): the build stamp that was silently empty, and two asymmetries the handshake never checked
CONTRACT-P6 4.2 and 4.3. Three defects, all of them things the handshake
believed it was checking and was not.
1. THE BUILD STAMP WAS "" AND NOTHING SAID SO. CMakeLists took the git hash
through an execute_process with NO RESULT_VARIABLE, so a failed
`git rev-parse` yielded the empty string. Verified live rather than
inferred: this worktree's `.git` is a file holding a WINDOWS path, WSL's
git answers `fatal: not a git repository`, result 128 - and every WSL build
mixed "" into its ABI fingerprint. Two builds from different commits then
agreed exactly, which is the one thing the stamp exists to prevent. The
already-failing SessionHandshakeTest was reporting this the whole time.
The fix may NOT touch GIT_COMMIT_HASH_SHORT: it is baked into
glGetString(GL_VERSION), so redefining it changes an application-visible GL
string and the pull build's .rodata - a behaviour leak and a G1 break at
once. MGGitHash.h.in gains a SECOND pair instead, consumed only by the
fingerprint, plus -DMOBILEGL_BUILD_STAMP for trees git cannot read (CI has
${GITHUB_SHA} in hand). A stampless build is now a configure-time WARNING
naming the consequence, not silence.
MOBILEGL_BUILD_STAMP_PRESENT IS MIXED AS ITS OWN FIELD. "this build cannot
name its commit" and "this build's commit is the empty string" are different
claims, and collapsing them is how every stampless build in the world agreed
with every other. The test asserts the flag moves the fingerprint in EITHER
build state, and the `BuildStamp = ""` perturbation is now guarded - in a
stampless build production's value already IS "", so that assertion was
passing while proving nothing.
2. THE CLIENT NEVER READ abiMajor/abiMinor. Hello has carried them since P5
and the SERVER checks them; the client compared only the fingerprint. The
fingerprint mixes AbiVersion so a mismatch would fire anyway - but as
"struct shapes", which sends the reader looking for a layout change that is
not there. Under spawn the peer is a SEPARATE IMAGE the operator chose with
MOBILEGL_IPC_SERVER_PATH, so this is exactly the failure that needs its own
sentence. Both handshake sites call one helper; there are two sites, and
only one of them was reachable before `sm`, which is how the gap survived.
3. Hello::pid WAS 0 AND Welcome::serverPid ECHOED IT. So both were always 0 and
neither named anything, while §9.5's arm-proof gate wants exactly the child
pid. Both now carry real ids, and the pair is the cheapest arm proof in the
protocol: under spawn they MUST differ, and a same-process session cannot
produce two different values. The client keeps what the server STATED -
local launcher knowledge is a different fact from one that crossed the wire,
and only the second can be asserted from the server's own mouth.
R-16 both ways: revert serverPid to echoing hello->pid() and the new test reds
on both halves, naming 4.3. G1 re-measured after the CMake and header changes:
0 symbol diff, .text unchanged at 0xa52203.
Unit suite goes from two long-standing failures to one - the remaining
PipeCatalogue.FrontendNeverTakesAnApplierAddress is an environmental path
problem in this tree, unrelated. All six OpenRA arms still green.
This commit is contained in:
@@ -24,8 +24,27 @@
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
// CONTRACT-P6 4.3: the one value in the handshake that a same-process session cannot fake.
|
||||
#if defined(_WIN32)
|
||||
#include <process.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace MobileGL::MG_Remote::Server {
|
||||
|
||||
namespace {
|
||||
// File-local on purpose: two callers, both handshake facts. A process-id helper on a
|
||||
// public header invites uses that are not.
|
||||
std::uint32_t SelfProcessId() {
|
||||
#if defined(_WIN32)
|
||||
return static_cast<std::uint32_t>(::_getpid());
|
||||
#else
|
||||
return static_cast<std::uint32_t>(::getpid());
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// THE THREE FLAG-SPACE COLLISIONS, AS TRIPWIRES RATHER THAN AS A COMMENT.
|
||||
//
|
||||
// MGPipeCallFlags (MG_Pipe/MGPipe.h:42-54) and RingRecordFlags (Ring.h) are separate spaces
|
||||
@@ -531,7 +550,15 @@ namespace MobileGL::MG_Remote::Server {
|
||||
auto stamp = builder.CreateString(GIT_COMMIT_HASH_SHORT);
|
||||
auto welcome = ::MobileGL::Wire::CreateWelcome(
|
||||
builder, MOBILEGL_PROTOCOL_ABI_MAJOR, MOBILEGL_PROTOCOL_ABI_MINOR,
|
||||
static_cast<Uint32>(hello->pid()), cmd, stage, reply, event, stamp, ourFingerprint);
|
||||
// CONTRACT-P6 4.3: THE SERVER'S OWN PID, not an echo of the client's.
|
||||
//
|
||||
// This field echoed hello->pid() - which is itself hard-coded 0 - so serverPid
|
||||
// was ALWAYS 0 and named nothing. §9.5's arm-proof gate wants the child pid and
|
||||
// this is its natural carrier: under spawn it is the one value in the handshake
|
||||
// that a same-process session cannot produce, because there the two pids are
|
||||
// equal by construction.
|
||||
static_cast<Uint32>(SelfProcessId()),
|
||||
cmd, stage, reply, event, stamp, ourFingerprint);
|
||||
auto root = ::MobileGL::Wire::CreateCtrlEnvelope(
|
||||
builder, ::MobileGL::Wire::CtrlMsg::Welcome, welcome.Union());
|
||||
::MobileGL::Wire::FinishCtrlEnvelopeBuffer(builder, root);
|
||||
|
||||
Reference in New Issue
Block a user