Valgrind не распознает инструкцию memcmp в малине Pi

Я тестирую свое приложение в Valgrind, и я не понимаю, почему он вызывает ошибку при непризнанной инструкции здесь:

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 выбрасывает это и выходит из моего приложения.

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 probably your program fault.
==7679== 2. The instruction is legitimate but Valgrind doesn't handle it,
==7679==    i.e. it Valgrind 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)

Обычно код работает нормально (однако я не знаю, не имеет ли утечки памяти).

Я точно знаю, что проблема - инструкция memcmp, но я не понимаю, что не так.

Раньше в коде у меня была другая инструкция, которая делала то же самое, но я мог просто прокомментировать ее перед проверкой:

  memcmp(ReadPtr,ToWritePtr,sizeof(struct termios)

Ответ 1

Похоже, что это известная проблема с Valgrind на Pi.

Чтобы обобщить версию memcmp в Raspbian, используется инструкция сборки, которую текущий Valgrind просто не может обработать. К сожалению, эта специальная инструкция, по-видимому, будет очень трудной для поддержки Valgrind, так что вряд ли это произойдет - bug был поднят в трекер Valgrind но был закрыт как WONTFIX.

Об единственном способе, с которым я могу работать, это заменить вашу собственную версию memcmp и надеяться, что она не скомпилируется, чтобы включить проблематичную инструкцию.

Ответ 2

У меня с вами такая же проблема.

Я проверяю репозиторий arm-mem и кажется, что он заменен memcmp в libc. Поэтому мое решение для использования valgrind временно удаляет arm-mem, а затем использует исходную реализацию в libc.

Попробуйте следующее:

$ 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

Теперь попробуйте повторно запустить valgrind...

Позже, верните его с помощью:

$ 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

Ответ 3

Вам нужно исправить libarmmem.so, чтобы работать только в режиме little-endian. Чтобы построить ответ на @nigelharper, Valgrind не поддерживает операцию в обратном endian, и поэтому ловушки в команде SETEND. Однако memcmp() может быть реализован без SETEND, как это делается здесь: https://github.com/rsaxvc/arm-mem/commit/b836e465c2fd0bb006b428abce99e31607072834

@user167752 также верен, что отключение libarmmem также будет работать, но это изменит все libarmmem, а не только memcmp()