commit 9dfe7c4c5de9c88f0c2c77bf3230f5b5804238eb
parent 6c739b82dac5cdf1c2e3b36151b41b4767f69db1
Author: Jared Tobin <jared@jtobin.io>
Date: Mon, 19 Oct 2026 14:05:40 +0400
diff: a dump in which nothing ran is refused
The plugin writes every instruction the guest executed, so a dump in
which none ran records no run: a recording that failed before the
plugin wrote anything, or a file left empty. readDump parsed it as a
run that did nothing, and two such dumps compared clean, with no
origins and nothing executed. It is now refused, and diff with it.
Diffstat:
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/lib/Vestigia/Diff.hs b/lib/Vestigia/Diff.hs
@@ -98,12 +98,17 @@ data Dump = Dump {
, dpTransfers :: !(M.Map Integer (M.Map Integer Integer))
} deriving (Eq, Show)
--- | Read a plugin dump.
+-- | Read a plugin dump. A dump in which no instruction ran records
+-- no run (the plugin writes every instruction the guest executed),
+-- and is refused rather than compared as one that did nothing.
readDump :: T.Text -> Either String Dump
readDump t = go (T.lines t) M.empty M.empty
where
go ls is es = case ls of
- [] -> pure (Dump is es)
+ []
+ | any ((> 0) . inCount) (M.elems is) -> pure (Dump is es)
+ | otherwise ->
+ Left "no instruction ran: the run was not recorded"
(l : rest) -> case T.words l of
[ "I", pc, n, a, fp, ord, obj, off ] -> do
i <- Insn <$> unhex pc <*> unhex n <*> unhex a <*> pure fp
diff --git a/test/Main.hs b/test/Main.hs
@@ -245,6 +245,11 @@ diffTests = testGroup "diff"
M.keys (dvExecuted (restrictTo [ "lib.so" ] dv))
@?= [ "/lib.so" ]
+ , testCase "a dump in which nothing ran is refused" $ do
+ isLeft (readDump "") @? "an empty dump accepted"
+ isLeft (readDump "I 10 0 0 aaaa 0 /lib.so 10\n")
+ @? "a dump of instructions never run accepted"
+
, testCase "an unreadable line is refused" $
isLeft (readDump "I 10 zz 0 f 0 /lib.so 0\n") @? "accepted"
]