Skip to content

Flush already closed frames at plugin exit even at the cost of having no post-state for the final frame - #47

Merged
Rot127 merged 1 commit into
BinaryAnalysisPlatform:trace-10.0from
moste00:fix/flush_at_exit
Jul 26, 2026
Merged

Flush already closed frames at plugin exit even at the cost of having no post-state for the final frame#47
Rot127 merged 1 commit into
BinaryAnalysisPlatform:trace-10.0from
moste00:fix/flush_at_exit

Conversation

@moste00

@moste00 moste00 commented Jul 19, 2026

Copy link
Copy Markdown

** Problem **

QEMU plugin API provides no direct way to run a callback at the retiring of every instruction. This is necessary for us because we record post-state for each instruction.

The way the plugin deals with it is by treating the pre-execution boundary of an instruction as the post-excecution boundary of the previous instruction.

But this becomes a problem at the very end of execution, since the final instruction has no next instruction, so we have to capture its post-state at plugin exit, but this is impossible because there is no VCPU in the plugin exit callback.

** Previous State **

This was previously "solved" by just flushing a threshold (64) of frames periodically and accepting that the final batch of less-than-threshold frames will not be flushed.

** Solution **

The piqi format allows a frame with no-post state, so instead of sacrificing the entire residual array of frames at plugin exit, we can just sacrifice only the final frame and close it with no post-state, but flush the rest of the frames that were already closed.

@moste00
moste00 force-pushed the fix/flush_at_exit branch from ca44203 to 7458dba Compare July 19, 2026 18:46
@Rot127

Rot127 commented Jul 20, 2026

Copy link
Copy Markdown

with no post-state

Have you tried if this goes well with rz-tracetest?

@moste00

moste00 commented Jul 25, 2026

Copy link
Copy Markdown
Author

with no post-state

Have you tried if this goes well with rz-tracetest?

I don't remember running it, but a GPT 5.5 review found that most non-important usages (printing, etc...) will work just fine, as they're just loops over a frame's state so for empty states they're naturally no-ops. The only bad case would be in counting mismatches, an empty post-state for a frame would count as violations (probably, I didn't run).

I will fix this by adding a new category next to misexecuted and unlifted and such, it would be called missing or unrecorded or something like that, and it would be a failure category different than misexecuted and not lifted.

But I plan to merge this first.

@Rot127

Rot127 commented Jul 25, 2026

Copy link
Copy Markdown

Can you please try to run the trace from that branch?
Because if it turns out to be super annoying to refactor and we never do it in rz-tracetest, we end up with a broken interaction and have to revert again

If you still want to merge early, then please document the behavior.

Actually, please do the test. Otherwise we don't know if it maybe broke something in the normal loop.

@moste00

moste00 commented Jul 25, 2026

Copy link
Copy Markdown
Author

@Rot127 Did it just now, doesn't crash, it outputs a few mismatches, perhaps not all of them true mismatches (one of them is due to a missing post-state, probably).

But no crash happens, the crash happens with the 0 frame case by the way. (Discovered this accidentally, when the flush problem outputted a trace with 0 frames.)

@Rot127
Rot127 merged commit 0e265a2 into BinaryAnalysisPlatform:trace-10.0 Jul 26, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants