MCPcopy Create free account
hub / github.com/PlotJuggler/PlotJuggler / TEST

Function TEST

pj_runtime/tests/payload_anchor_test.cpp:36–60  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

34} // namespace
35
36TEST(PayloadAnchorKeepalive, ReleaseRunsWhileDsoStillMapped) {
37 bool dso_mapped = true;
38 // The plugin DSO token: when its last copy drops, the ".so" unloads.
39 auto library_keepalive =
40 std::shared_ptr<void>(reinterpret_cast<void*>(0x1), [&dso_mapped](void*) { dso_mapped = false; });
41
42 AnchorProbe probe{&dso_mapped};
43 PJ_payload_anchor_t anchor{};
44 anchor.ctx = &probe;
45 anchor.release = &probeRelease;
46
47 PJ::sdk::BufferAnchor wrapped = PJ::detail::wrapPayloadAnchor(anchor, library_keepalive);
48
49 // The extension catalog tears down and drops its DSO token. The wrapped anchor
50 // must hold its OWN copy, so the ".so" stays mapped.
51 library_keepalive.reset();
52 EXPECT_TRUE(dso_mapped) << "wrapped anchor must keep the producing plugin DSO token alive";
53 EXPECT_FALSE(probe.release_ran);
54
55 // Destroying the anchor runs release — and it must run BEFORE the DSO unloads.
56 wrapped.reset();
57 EXPECT_TRUE(probe.release_ran);
58 EXPECT_FALSE(probe.released_after_unload) << "plugin release fn was called after the DSO unloaded (UAF)";
59 EXPECT_FALSE(dso_mapped) << "the captured keepalive drops once the anchor is destroyed";
60}
61
62TEST(PayloadAnchorKeepalive, NullReleaseYieldsEmptyAnchor) {
63 PJ_payload_anchor_t anchor{}; // release == nullptr → no ownership to track.

Callers

nothing calls this directly

Calls 2

wrapPayloadAnchorFunction · 0.85
resetMethod · 0.45

Tested by

no test coverage detected