collateral damage
kazcw opened this issue · comments
Patching functions smaller than JMP_SIZE overwrites whatever happens to follow them. On x86_64, this affects the the_ultimate_question
function in mod tests; patching it causes the next function defined, default
, to crash.
What triple is your machine?
Darn rust and allowing functions to be so small. 🗡
nightly-x86_64-unknown-linux-gnu
rustc 1.32.0-nightly (25a42b2ce 2018-11-07)
I was getting a SIGSEGV, but now the outcome is test_patch
spuriously failing.
Edit: I think the behavior switched when I rebased
The smallest possible function is RET (1 byte), so fixing this in general will be fun. INT 3 (0xCC) would work. The interrupt handler could consult a static hashmap from IP to destination.
With INT 3
wouldn't we interfere with debuggers?
We could reduce the assembled size to 2-3 bytes easily with relative jumps.
pub fn other_question() -> u8 {
10
}
Is 4 bytes on 32-bit and 64-bit systems.
pub fn nothing() { }
Is 1
byte, true but I feel that we could test for a ret
and if we find one at the beginning we just panic!
early with "target function too small to patch".
Yeah, relative jumps are simpler to implement and don't mess with debuggers, and panicking if the jump can't be made smaller than the target function is probably a reasonable limitation for mocking-type use cases
Self-debugging code would be so cool tho :)
Reduced assembled instruction size. I get spurious failures unless run with --test-threads=1
as patch
is definitely not thread-safe.