Bug 400829

Summary: vex amd64->IR: unhandled instruction bytes: 0xF0 0x49 0xF 0xC7 0x4D 0x0 0x48
Product: [Developer tools] valgrind Reporter: Andrew Pennebaker <andrew.pennebaker>
Component: memcheckAssignee: Rhys Kidd <rhyskidd>
Status: REPORTED ---    
Severity: normal CC: jseward, pjfloyd, rhyskidd, tom
Priority: NOR    
Version: 3.14 SVN   
Target Milestone: ---   
Platform: Other   
OS: macOS   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Andrew Pennebaker 2018-11-08 01:10:23 UTC
I can valgrind my code in Debian, CentOS, and OpenWrt Linux. But when I try to valgrind the same code in macOS High Sierra, I get a strange error from Valgrind about "unhandled instruction bytes". My C code might not be the best, but I don't think I'm doing anything too crazy with it. Compiling with clang, CMAKE_C_FLAGS "-std=c11 -O2 -Wall -Wextra -Wmost -Weverything".

Source:

https://gist.github.com/mcandre/128dc1f9b8fa265e7ed3df5b0a8101e3

Trace:

{{{
$ valgrind --error-exitcode=1 --leak-check=full bin/fewer -h
==678== Memcheck, a memory error detector
==678== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==678== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==678== Command: bin/fewer -h
==678== 
--678-- run: /usr/bin/dsymutil "bin/fewer"
warning: no debug symbols in executable (-arch x86_64)
vex amd64->IR: unhandled instruction bytes: 0xF0 0x49 0xF 0xC7 0x4D 0x0 0x48 0x89 0x75 0xA8
vex amd64->IR:   REX=1 REX.W=1 REX.R=0 REX.X=0 REX.B=1
vex amd64->IR:   VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=0F
vex amd64->IR:   PFX.66=0 PFX.F2=0 PFX.F3=0
==678== valgrind: Unrecognised instruction at address 0x1005d46c5.
==678==    at 0x1005D46C5: _pthread_rwlock_lock_slow (in /usr/lib/system/libsystem_pthread.dylib)
==678==    by 0x1006C0605: rwlock_tt<false>::write() (in /usr/lib/libobjc.A.dylib)
==678==    by 0x1006D34D3: map_images (in /usr/lib/libobjc.A.dylib)
==678==    by 0x100007C64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==678==    by 0x100007E39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==678==    by 0x10022081D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==678==    by 0x1006C0073: _objc_init (in /usr/lib/libobjc.A.dylib)
==678==    by 0x1001AAACC: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==678==    by 0x1001AAAB3: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==678==    by 0x1000BA9C2: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==678==    by 0x100019A09: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==678==    by 0x100019C39: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==678== Your program just tried to execute an instruction that Valgrind
==678== did not recognise.  There are two possible reasons for this.
==678== 1. Your program has a bug and erroneously jumped to a non-code
==678==    location.  If you are running Memcheck and you just saw a
==678==    warning about a bad jump, it's probably your program's fault.
==678== 2. The instruction is legitimate but Valgrind doesn't handle it,
==678==    i.e. it's Valgrind's fault.  If you think this is the case or
==678==    you are not sure, please let us know and we'll try to fix it.
==678== Either way, Valgrind will now raise a SIGILL signal which will
==678== probably kill your program.
==678== 
==678== Process terminating with default action of signal 4 (SIGILL)
==678==  Illegal opcode at address 0x1005D46C5
==678==    at 0x1005D46C5: _pthread_rwlock_lock_slow (in /usr/lib/system/libsystem_pthread.dylib)
==678==    by 0x1006C0605: rwlock_tt<false>::write() (in /usr/lib/libobjc.A.dylib)
==678==    by 0x1006D34D3: map_images (in /usr/lib/libobjc.A.dylib)
==678==    by 0x100007C64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==678==    by 0x100007E39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==678==    by 0x10022081D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==678==    by 0x1006C0073: _objc_init (in /usr/lib/libobjc.A.dylib)
==678==    by 0x1001AAACC: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==678==    by 0x1001AAAB3: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==678==    by 0x1000BA9C2: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==678==    by 0x100019A09: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==678==    by 0x100019C39: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==678== 
==678== HEAP SUMMARY:
==678==     in use at exit: 0 bytes in 0 blocks
==678==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==678== 
==678== All heap blocks were freed -- no leaks are possible
==678== 
==678== For counts of detected and suppressed errors, rerun with: -v
==678== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
}}}
Comment 1 Julian Seward 2019-03-10 08:34:02 UTC
F0 49 is CMOVNS.  Which is definitely supported.  I'm not sure what's
going on here.
Comment 2 Rhys Kidd 2019-03-11 12:13:38 UTC
I'll try to take a look at this one on macOS.
Comment 3 Paul Floyd 2023-02-24 09:10:49 UTC
I'll see what this does with clang on FreeBSD (since it may be a clang issue).
Comment 4 Paul Floyd 2023-02-24 18:12:18 UTC
I get no errors.

objdump shows several cmovs including cmovns:

objdump -d bug400829 | grep -i cmov
  201b86:       48 0f 48 d0             cmovs  %rax,%rdx
  201b93:       48 0f 49 c1             cmovns %rcx,%rax
  201ba5:       4c 0f 43 e8             cmovae %rax,%r13
  201bf0:       48 0f 48 d0             cmovs  %rax,%rdx
  201bfd:       48 0f 49 c1             cmovns %rcx,%rax
  201c0f:       4c 0f 43 e8             cmovae %rax,%r13
  201c7d:       48 0f 48 cb             cmovs  %rbx,%rcx
  201c95:       48 0f 49 d8             cmovns %rax,%rbx
Comment 5 Paul Floyd 2023-02-24 20:45:37 UTC
And on macOS 13.2 I have no problem (out of repo version of Valgrind)