14

I'm testing my aplication in Valgrind an i can't understand why it throws error on unrecognised instruction in this here:

unsigned char *temp=SearchStartPtr;
unsigned char *NrStartPos=NULL;
unsigned char *Param=(unsigned char*)ParamName; //this is originally *char with "PAR#" inside

if(0==memcmp(temp,Param,4)) 
        {
        NrStartPos=temp;
        break;
        }       

Valgrind throws this and exits my application.

disInstr(arm): unhandled instruction: 0xF1010200
cond=15(0xF) 27:20=16(0x10) 4:4=0 3:0=0(0x0)
==7679== valgrind: Unrecognised instruction at address 0x4843588.
==7679==    at 0x4843588: ??? (in /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so)
Your program just tried to execute an instruction that Valgrind
==7679== did not recognise.  There are two possible reasons for this.
==7679== 1. Your program has a bug and erroneously jumped to a non-code
==7679==    location.  If you are running Memcheck and you just saw a
==7679==    warning about a bad jump, it's probably your program's fault.
==7679== 2. The instruction is legitimate but Valgrind doesn't handle it,
==7679==    i.e. it's Valgrind's fault.  If you think this is the case or
==7679==    you are not sure, please let us know and we'll try to fix it.
==7679== Either way, Valgrind will now raise a SIGILL signal which will
==7679== probably kill your program.
==7679== 
==7679== Process terminating with default action of signal 4 (SIGILL)
==7679==  Illegal opcode at address 0x4843588
==7679==    at 0x4843588: ??? (in /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so)

Normally the code works fine (however i don't know if it doesn't have some memory leaks).

I know for sure that the problem is memcmp instruction but i don't understand what is wrong.

Earlier in the code i have another instruction which did the same thing but i could just comment it away before checking:

  memcmp(ReadPtr,ToWritePtr,sizeof(struct termios)
Gregorek
  • 263
  • 4
  • 16
  • 1
    If you read the message more carefully it says that it found an illegal instruction (like, assembly instruction). `memcmp` is a function not an instruction. Also, Valgrind states that this illegal instruction was found in `/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so`, hardly the file you created I would venture. – Some programmer dude Nov 19 '13 at 08:09
  • Possible duplicate of https://stackoverflow.com/questions/17430731/valgrind-returning-an-unhandled-instruction-on-raspberry-pi/76258814 – rsaxvc May 17 '23 at 12:43

3 Answers3

16

It would appear that this is a known issue with Valgrind on the Pi.

To summarise the stock version of memcmp in Raspbian uses an assembly instruction which current Valgrind simply can't handle. Unfortunately this particular instruction would apparently be very difficult for Valgrind to support so it's unlikely it'll happen - a bug was raised in the Valgrind tracker but has been closed as WONTFIX.

About the only way I can see to work around this would be to substitute your own version of memcmp and hope it doesn't compile down to include the problematic instruction.

Nigel Harper
  • 1,270
  • 9
  • 13
  • 1
    excellent answer. as a possible fix to this issue try using strcmp [if you look at the valgrind trace under the bug link posted, it seems to be ok with strcmp replacing] – amdixon Nov 19 '13 at 09:07
  • The functions in /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so is coded in assembly, it's unlikely a C version would compile down to the SETEND assembly instruction - so one can probably create a C version of it and use LD_PRELOAD to override the troublesome memcmp – nos Nov 19 '13 at 09:34
  • 12
    And ok, it's easier than that. /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so is itself preloaded. So just edit /etc/ld.so.preload on the raspberry, and comment out the line, which should give you the memcmp from glibc instead – nos Nov 19 '13 at 09:41
  • 2
    Nigel you should add nos last comment to your answer as it provides a very simple workaround – Christian Rapp Feb 16 '14 at 15:38
  • 3
    I fixed the issue by simply removing the `raspi-copies-and-fills` package. – ayke Sep 25 '16 at 15:43
  • My fix was merged into arm-mem: https://github.com/bavison/arm-mem/commit/b836e465c2fd0bb006b428abce99e31607072834 – rsaxvc May 16 '23 at 01:04
3

I have the same problem with you.

I check the arm-mem repo and it seems it is replaced the memcmp in libc. So my solution for using the valgrind is remove arm-mem temporarily then use the original implementation in libc.

Try this:

$ sudo mv /usr/lib/arm-linux-gnueabihf/libarmmem.so /usr/lib/arm-linux-gnueabihf/libarmmem.so.orig
$ sudo ln -s  /lib/arm-linux-gnueabihf/libc.so.6  /usr/lib/arm-linux-gnueabihf/libarmmem.so
$ sudo ldconfig

Now try re-run valgrind...

Later, move it back with:

$ sudo rm /usr/lib/arm-linux-gnueabihf/libarmmem.so
$ sudo mv /usr/lib/arm-linux-gnueabihf/libarmmem.so.orig /usr/lib/arm-linux-gnueabihf/libarmmem.so
$ sudo ldconfig
Manfred Radlwimmer
  • 13,257
  • 13
  • 53
  • 62
user167752
  • 31
  • 1
1

libarmmem.so's memcmp() uses multi-byte load instructions while searching for a difference in the buffers with a technique called SWAR. However, it used the 'setend be' instruction to put the processor into big-endian mode so that it was easier to locate the difference once the registers mismatched, then after the difference was located, 'setend le' to restore the endianness mode before returning. This worked great on ARM11, but...

Valgrind doesn't implement setend emulation for Arm processors(possibly because it would make the normal case of native-endian accesses slower), so it triggered the 'unrecognized instruction'.

SWAR-vectorized memcmp() can be implemented without SETEND, and I did so, and it's merged upstream. The performance impact of the extra rev instructions is roughly negligible on large enought comparisons on the relevant cores.

@user167752 is also correct, that disabling libarmmem will also work, but this will change out all of libarmmem, not just memcmp(). To do so, uninstall the raspi-copies-and-fills package.

rsaxvc
  • 1,675
  • 13
  • 20