mirror of
https://github.com/lucannez64/darling-lol.git
synced 2026-10-26 19:47:42 +00:00
Make the CFHost cancel probe wait for delivery and reject completed lookups
Wait up to 2 s for the cancellation callback instead of one 50 ms run-loop pass, count only callbacks without stored addresses so a completed lookup cannot pass as a cancellation, print the failing stage, and have the runner require the exact success line since Darling can exit zero after a trap. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
67626612ac
commit
72093a1b58
3 files changed
+27
-8
No files matched your search
+4
-2
@@ -406,7 +406,9 @@ python3 build/runtime/tools/run-riot-native-check.py riot-cfhost-cancel-check
|
||||
|
||||
Run against the installed CFNetwork override. Expect
|
||||
`CFHOST_CANCEL_CHECK cancel callback lifetime repeated pass=1`. The unpatched
|
||||
library traps in `CFRetain(NULL)`; the runner checks the success marker because
|
||||
library traps in `CFRetain(NULL)`; the runner requires the exact success line because
|
||||
Darling can return status zero even when the guest traps. The probe uses localhost
|
||||
and exercises 100 cancellations with both retained and early-released caller
|
||||
references, without launching or inspecting Riot.
|
||||
references, without launching or inspecting Riot. A failure prints
|
||||
`CFHOST_CANCEL_CHECK fail stage=...`; `unexpected-callback` means a completed
|
||||
lookup arrived instead of the cancellation.
|
||||
@@ -2,11 +2,22 @@
|
||||
#include <CFNetwork/CFHost.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static unsigned callbacks;
|
||||
static unsigned callbacks, unexpected;
|
||||
static void completed(CFHostRef host, CFHostInfoType type,
|
||||
const CFStreamError *error, void *info) {
|
||||
if (host && type == kCFHostAddresses && info == &callbacks)
|
||||
/* A cancellation stores no addresses; a completed lookup always does. */
|
||||
Boolean resolved = false;
|
||||
if (host) CFHostGetAddressing(host, &resolved);
|
||||
if (host && type == kCFHostAddresses && info == &callbacks && !resolved)
|
||||
++callbacks;
|
||||
else
|
||||
++unexpected;
|
||||
}
|
||||
|
||||
static int fail(const char *stage, unsigned i) {
|
||||
printf("CFHOST_CANCEL_CHECK fail stage=%s iteration=%u callbacks=%u unexpected=%u\n",
|
||||
stage, i, callbacks, unexpected);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
@@ -14,14 +25,17 @@ int main(void) {
|
||||
for (unsigned i = 0; i < 100; ++i) {
|
||||
CFHostRef host = CFHostCreateWithName(NULL, CFSTR("localhost"));
|
||||
CFStreamError error = {0};
|
||||
if (!host || !CFHostSetClient(host, completed, &context)) return 1;
|
||||
if (!host || !CFHostSetClient(host, completed, &context)) return fail("client", i);
|
||||
CFHostScheduleWithRunLoop(host, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
if (!CFHostStartInfoResolution(host, kCFHostAddresses, &error)) return 2;
|
||||
if (!CFHostStartInfoResolution(host, kCFHostAddresses, &error)) return fail("start", i);
|
||||
CFHostCancelInfoResolution(host, kCFHostAddresses);
|
||||
/* The cancel source must keep its host alive until delivery. */
|
||||
if (i % 2) CFRelease(host);
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.05, false);
|
||||
if (callbacks != i + 1) return 3;
|
||||
CFAbsoluteTime deadline = CFAbsoluteTimeGetCurrent() + 2.0;
|
||||
while (callbacks != i + 1 && !unexpected && CFAbsoluteTimeGetCurrent() < deadline)
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.05, true);
|
||||
if (unexpected) return fail("unexpected-callback", i);
|
||||
if (callbacks != i + 1) return fail("cancel-callback", i);
|
||||
if (!(i % 2)) CFRelease(host);
|
||||
}
|
||||
puts("CFHOST_CANCEL_CHECK cancel callback lifetime repeated pass=1");
|
||||
|
||||
@@ -88,6 +88,9 @@ with tempfile.TemporaryFile() as output:
|
||||
if (args.check == "riot-running-application-check" and
|
||||
line != "RUNNING_APP found=1 activated=1 missing=1"):
|
||||
result = 1
|
||||
if (args.check == "riot-cfhost-cancel-check" and
|
||||
line != "CFHOST_CANCEL_CHECK cancel callback lifetime repeated pass=1"):
|
||||
result = 1
|
||||
if (args.check == "riot-mach-exception-state-check" and
|
||||
line != "MACH_EXCEPTION_STATE state=1 identity=1 handled=2 server=1"):
|
||||
result = 1
|
||||
|
||||
Reference in new issue
Block a user