Bug 506453 - Unexpected behaviour with IR injection and vex-guest-chase=yes
Summary: Unexpected behaviour with IR injection and vex-guest-chase=yes
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (other bugs)
Version First Reported In: unspecified
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-07-01 18:58 UTC by Florian Krohm
Modified: 2025-10-07 12:40 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
tarball with reproducer and patch (10.00 KB, application/x-tar)
2025-07-01 18:58 UTC, Florian Krohm
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Florian Krohm 2025-07-01 18:58:43 UTC
Created attachment 182843 [details]
tarball with reproducer and patch

Attached is a tarball with a small reproducer and a patch condensed from a larger application 
(https://bugs.kde.org/show_bug.cgi?id=506211) that uses VEX IR injection.
It does not behave correctly when run under valgrind.

To reproduce:

1) Copy files.tar to the top of valgrind source tree;  tar xf files.tar
2) patch -p1 < IRI-patch  
3) Rebuild with    make -k
   memcheck/tests/vbit-test will no longer compile but that's OK as
   we don't need it.
4) Compile the reproducer:
   gcc -IVEX/pub -Iinclude reproducer.c
5) Run it:
   ./vg-in-place ./a.out

This is the output (both on s390 and x86-64):

IR_INJECT opnd1 = 0
test
IR_INJECT opnd1 = 0
IR_INJECT opnd1 = 0
test
IR_INJECT opnd1 = 1

Trivial inspection of the reproducer shows that this is obviously incorrect.
Expected output should be:

test
IR_INJECT opnd1 = 0
test
IR_INJECT opnd1 = 1

Turns out that --vex-guest-chase=no  makes valgrind behave correctly.
Scary stuff....
Comment 1 Florian Krohm 2025-10-07 12:40:20 UTC
Valgrind's behaviour is not incorrect as originally stated. It was just unexpected because I had 
falsely believed that chasing (which is enabled by default) would stop at conditional branches.
Chasing into VALGRIND_VEX_INJECT_IR causes vex_inject_ir to be invoked which will add IRStmt(s)
to the current super block. And we don't want that to happen speculatively.

The remedy would be to teach function chase_into_ok to not chase into VALGRIND_VEX_INJECT_IR.
But that is not so easy. We would have to recognise, on all platforms, the "special opcode preamble"
which, in general, is several bytes long. And we do not really know whether those bytes are all
accessible. Perhaps there is a way....

To me the effort seems not warranted because IR injection is currently only used for testing purposes.
Hence, not performance critical.
Therefore, the workaround is to use --vex-guest-chase=no on the command line when doing IR injection.

Fixed in 0329ab2021727242f31adfd665f602a8a6163aa8