Bug 322935

Summary: disInstr(arm): unhandled instruction: 0xF1010200, valgrind: Unrecognised instruction on Raspbian
Product: [Developer tools] valgrind Reporter: Sum <keansum>
Component: memcheckAssignee: Julian Seward <jseward>
Status: RESOLVED INTENTIONAL    
Severity: normal CC: alexander.ressler, mark, minfrin, mugnyte, noloader, noone.junkmail, peter.maydell, pjfloyd, sam, vasily.golubev, Werner.Frick
Priority: NOR    
Version: 3.7.0   
Target Milestone: ---   
Platform: Debian stable   
OS: Linux   
URL: http://stackoverflow.com/questions/17430731/valgrind-returning-an-unhandled-instruction-on-raspberry-pi
Latest Commit: Version Fixed In:
Attachments: std::cout << std::endl valgrind error
int redirected to std::cout valgrind error
test1.cpp objdump
test2.cpp objdump
Valgrind Trunk with patch make check failure
Valgrind Trunk with patch test1.cpp failure
Valgrind Trunk with patch test2.cpp failure
test1 binary
test2 binary
test1.cpp
test2.cpp
libcofi_rpi.so objdump
valgrind trunk configure step error

Description Sum 2013-07-29 07:33:12 UTC
Running Valgrind on Raspberry PI causes an "unhandled instruction" error on C++ insertion operator when given an int type or the endl function to std::cout such as these two cases:

1. cout << endl;

2. int my_int = 3;
cout << my_int;


I am not sure if this is because of missing debugging information from these two libraries:
/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
/lib/ld-linux-armhf.so.3

... or if it really is a bug. Therefore I am not sure if this is the correct place to ask or the mailing lists but here it is.

This is on the Raspberry PI using Raspbian

$ uname -a
Linux raspberrypi 3.6.11+ #371 PREEMPT Thu Feb 7 16:31:35 GMT 2013 armv6l GNU/Linux

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux 7.0 (wheezy)
Release:	7.0
Codename:	wheezy

$ valgrind --version
valgrind-3.7.0

$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.6/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.3-14+rpi1' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 4.6.3 (Debian 4.6.3-14+rpi1) 


Reproducible: Always

Steps to Reproduce:
1.  Save this as test1.cpp
  1 /* g++ -g -Wall -Wextra -pedantic test1.cpp -o test1
  2  */
  3 #include <iostream>
  4 
  5 using namespace std;
  6 
  7 int main(int argc, char *argv[]) {
  8 
  9   // The "<< endl" below will cause valgrind to crash
 10   cout << endl;
 11 
 12   return 0;
 13 }

2. Compile: 
$ g++ -g -Wall -Wextra -pedantic test1.cpp -o test1

3. Run with Valgrind:
valgrind -v --tool=memcheck --leak-check=yes --leak-check=full --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes --num-callers=50  --db-attach=yes ./test1
Actual Results:  
$ valgrind -v --tool=memcheck --leak-check=yes --leak-check=full --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes --num-callers=50  --db-attach=yes ./test1
==28577== Memcheck, a memory error detector
==28577== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==28577== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==28577== Command: ./test1
==28577== 
--28577-- Valgrind options:
--28577--    --suppressions=/usr/lib/valgrind/debian-libc6-dbg.supp
--28577--    -v
--28577--    --tool=memcheck
--28577--    --leak-check=yes
--28577--    --leak-check=full
--28577--    --show-reachable=yes
--28577--    --num-callers=20
--28577--    --track-fds=yes
--28577--    --track-origins=yes
--28577--    --num-callers=50
--28577--    --db-attach=yes
--28577-- Contents of /proc/version:
--28577--   Linux version 3.6.11+ (dc4@dc4-arm-01) (gcc version 4.7.2 20120731 (prerelease) (crosstool-NG linaro-1.13.1+bzr2458 - Linaro GCC 2012.08) ) #371 PREEMPT Thu Feb 7 16:31:35 GMT 2013
--28577-- Arch and hwcaps: ARM, ARMv6-vfp
--28577-- Page sizes: currently 4096, max supported 4096
--28577-- Valgrind library directory: /usr/lib/valgrind
--28577-- Reading syms from /home/pi/rpicpp/test1 (0x8000)
--28577-- Reading syms from /lib/arm-linux-gnueabihf/ld-2.13.so (0x4000000)
--28577--   Considering /lib/arm-linux-gnueabihf/ld-2.13.so ..
--28577--   .. CRC mismatch (computed d28c4ae0 wanted a6002182)
--28577--   Considering /usr/lib/debug/lib/arm-linux-gnueabihf/ld-2.13.so ..
--28577--   .. CRC is valid
--28577-- Reading syms from /usr/lib/valgrind/memcheck-arm-linux (0x38000000)
--28577--   Considering /usr/lib/valgrind/memcheck-arm-linux ..
--28577--   .. CRC mismatch (computed c39dcb39 wanted 708b2eee)
--28577--   Considering /usr/lib/debug/usr/lib/valgrind/memcheck-arm-linux ..
--28577--   .. CRC is valid
--28577--    object doesn't have a dynamic symbol table
--28577-- Reading suppressions file: /usr/lib/valgrind/debian-libc6-dbg.supp
--28577-- Reading suppressions file: /usr/lib/valgrind/default.supp
==28577== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-28577-by-pi-on-???
==28577== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-28577-by-pi-on-???
==28577== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-28577-by-pi-on-???
==28577== 
==28577== TO CONTROL THIS PROCESS USING vgdb (which you probably
==28577== don't want to do, unless you know exactly what you're doing,
==28577== or are doing some strange experiment):
==28577==   /usr/lib/valgrind/../../bin/vgdb --pid=28577 ...command...
==28577== 
==28577== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==28577==   /path/to/gdb ./test1
==28577== and then give GDB the following command
==28577==   target remote | /usr/lib/valgrind/../../bin/vgdb --pid=28577
==28577== --pid is optional if only one valgrind process is running
==28577== 
--28577-- Reading syms from /usr/lib/valgrind/vgpreload_core-arm-linux.so (0x4827000)
--28577--   Considering /usr/lib/valgrind/vgpreload_core-arm-linux.so ..
--28577--   .. CRC mismatch (computed af6eafeb wanted c297409c)
--28577--   Considering /usr/lib/debug/usr/lib/valgrind/vgpreload_core-arm-linux.so ..
--28577--   .. CRC is valid
--28577-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-arm-linux.so (0x4831000)
--28577--   Considering /usr/lib/valgrind/vgpreload_memcheck-arm-linux.so ..
--28577--   .. CRC mismatch (computed c3fec287 wanted 88dfc0e5)
--28577--   Considering /usr/lib/debug/usr/lib/valgrind/vgpreload_memcheck-arm-linux.so ..
--28577--   .. CRC is valid
--28577-- Reading syms from /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0x4843000)
--28577-- Reading syms from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.17 (0x485a000)
--28577--   Considering /usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.17 ..
--28577--   .. CRC mismatch (computed 06724194 wanted 685640b9)
--28577--   Considering /usr/lib/debug/usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.17 ..
--28577--   .. CRC is valid
--28577-- Reading syms from /lib/arm-linux-gnueabihf/libm-2.13.so (0x4927000)
--28577--   Considering /lib/arm-linux-gnueabihf/libm-2.13.so ..
--28577--   .. CRC mismatch (computed 7dca801c wanted 6139b20d)
--28577--   Considering /usr/lib/debug/lib/arm-linux-gnueabihf/libm-2.13.so ..
--28577--   .. CRC is valid
--28577-- Reading syms from /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x4998000)
--28577--   Considering /lib/arm-linux-gnueabihf/libgcc_s.so.1 ..
--28577--   .. CRC mismatch (computed 5a9f3b4e wanted 6ece80f1)
--28577--   Considering /usr/lib/debug/lib/arm-linux-gnueabihf/libgcc_s.so.1 ..
--28577--   .. CRC is valid
--28577-- Reading syms from /lib/arm-linux-gnueabihf/libc-2.13.so (0x49c0000)
--28577--   Considering /lib/arm-linux-gnueabihf/libc-2.13.so ..
--28577--   .. CRC mismatch (computed f6f9f814 wanted adc2dd22)
--28577--   Considering /usr/lib/debug/lib/arm-linux-gnueabihf/libc-2.13.so ..
--28577--   .. CRC is valid
--28577-- REDIR: 0x4a37c54 (rindex) redirected to 0x4835cdc (rindex)
--28577-- REDIR: 0x4a37830 (strlen) redirected to 0x4836464 (strlen)
--28577-- REDIR: 0x4a38ab0 (bcmp) redirected to 0x483845c (bcmp)
--28577-- REDIR: 0x4a37428 (strcmp) redirected to 0x4837104 (strcmp)
disInstr(arm): unhandled instruction: 0xF1010200
                 cond=15(0xF) 27:20=16(0x10) 4:4=0 3:0=0(0x0)
==28577== valgrind: Unrecognised instruction at address 0x4843588.
==28577==    at 0x4843588: ??? (in /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so)
==28577== Your program just tried to execute an instruction that Valgrind
==28577== did not recognise.  There are two possible reasons for this.
==28577== 1. Your program has a bug and erroneously jumped to a non-code
==28577==    location.  If you are running Memcheck and you just saw a
==28577==    warning about a bad jump, it's probably your program's fault.
==28577== 2. The instruction is legitimate but Valgrind doesn't handle it,
==28577==    i.e. it's Valgrind's fault.  If you think this is the case or
==28577==    you are not sure, please let us know and we'll try to fix it.
==28577== Either way, Valgrind will now raise a SIGILL signal which will
==28577== probably kill your program.
==28577== 
==28577== Process terminating with default action of signal 4 (SIGILL)
==28577==  Illegal opcode at address 0x4843588
==28577==    at 0x4843588: ??? (in /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so)
==28577== 
==28577== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- y
==28577== starting debugger with cmd: /usr/bin/gdb -nw /proc/28580/fd/1024 28580
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabihf".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /proc/28580/fd/1024...done.
Attaching to program: /proc/28580/fd/1024, process 28580
Reading symbols from /usr/lib/valgrind/vgpreload_core-arm-linux.so...Reading symbols from /usr/lib/debug/usr/lib/valgrind/vgpreload_core-arm-linux.so...done.
done.
Loaded symbols for /usr/lib/valgrind/vgpreload_core-arm-linux.so
Reading symbols from /usr/lib/valgrind/vgpreload_memcheck-arm-linux.so...Reading symbols from /usr/lib/debug/usr/lib/valgrind/vgpreload_memcheck-arm-linux.so...done.
done.
Loaded symbols for /usr/lib/valgrind/vgpreload_memcheck-arm-linux.so
Reading symbols from /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
Reading symbols from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6...Reading symbols from /usr/lib/debug/usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.17...done.
done.
Loaded symbols for /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
Reading symbols from /lib/arm-linux-gnueabihf/libm.so.6...Reading symbols from /usr/lib/debug/lib/arm-linux-gnueabihf/libm-2.13.so...done.
done.
Loaded symbols for /lib/arm-linux-gnueabihf/libm.so.6
Reading symbols from /lib/arm-linux-gnueabihf/libgcc_s.so.1...Reading symbols from /usr/lib/debug/lib/arm-linux-gnueabihf/libgcc_s.so.1...done.
done.
Loaded symbols for /lib/arm-linux-gnueabihf/libgcc_s.so.1
Reading symbols from /lib/arm-linux-gnueabihf/libc.so.6...Reading symbols from /usr/lib/debug/lib/arm-linux-gnueabihf/libc-2.13.so...done.
done.
Loaded symbols for /lib/arm-linux-gnueabihf/libc.so.6
Reading symbols from /lib/ld-linux-armhf.so.3...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux-armhf.so.3
0x04843588 in memcmp () from /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
Traceback (most recent call last):
  File "/usr/lib/debug/usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.17-gdb.py", line 62, in <module>
    from libstdcxx.v6.printers import register_libstdcxx_printers
ImportError: No module named libstdcxx.v6.printers
(gdb) backtrace
#0  0x04843588 in memcmp () from /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
#1  0x048b6930 in std::ctype<char>::_M_widen_init (this=0x4925f64) at ../../../../../src/libstdc++-v3/src/c++98/ctype.cc:99
#2  0x048dd05c in widen (__c=10 '\n', this=0x4925f64) at /gcc-4.7-4.7.2/build/arm-linux-gnueabihf/libstdc++-v3/include/bits/locale_facets.h:871
#3  widen (__c=10 '\n', this=<optimized out>) at /gcc-4.7-4.7.2/build/arm-linux-gnueabihf/libstdc++-v3/include/bits/basic_ios.h:442
#4  std::endl<char, std::char_traits<char> > (__os=..., __os@entry=<error reading variable: value has been optimized out>) at /gcc-4.7-4.7.2/build/arm-linux-gnueabihf/libstdc++-v3/include/ostream:563
#5  0x048dc62c in std::ostream::operator<< (this=<optimized out>, __pf=<optimized out>) at /gcc-4.7-4.7.2/build/arm-linux-gnueabihf/libstdc++-v3/include/ostream:111
#6  0x00008648 in main (argc=1, argv=0xbdae6714) at test1.cpp:10
(gdb) info sharedLibrary
From        To          Syms Read   Shared Object Library
0x0482741c  0x04827608  Yes         /usr/lib/valgrind/vgpreload_core-arm-linux.so
0x0483336c  0x0483973c  Yes         /usr/lib/valgrind/vgpreload_memcheck-arm-linux.so
0x048434b8  0x04844a10  Yes (*)     /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
0x048a5130  0x049066b0  Yes         /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
0x0492a1d0  0x04958af8  Yes         /lib/arm-linux-gnueabihf/libm.so.6
0x049a7460  0x049b75a4  Yes         /lib/arm-linux-gnueabihf/libgcc_s.so.1
0x049d54a0  0x04ac235c  Yes         /lib/arm-linux-gnueabihf/libc.so.6
0x040007c0  0x04019408  Yes (*)     /lib/ld-linux-armhf.so.3
(*): Shared library is missing debugging information.
(gdb) q
A debugging session is active.

	Inferior 1 [process 28580] will be detached.

Quit anyway? (y or n) y
Detaching from program: /proc/28580/fd/1024, process 28580
==28577== 
==28577== Debugger has detached.  Valgrind regains control.  We continue.
--28577-- REDIR: 0x4a33d70 (free) redirected to 0x483482c (free)
--28577-- REDIR: 0x4a39200 (memset) redirected to 0x483898c (memset)
==28577== 
==28577== FILE DESCRIPTORS: 3 open at exit.
==28577== Open file descriptor 2: /dev/pts/3
==28577==    <inherited from parent>
==28577== 
==28577== Open file descriptor 1: /dev/pts/3
==28577==    <inherited from parent>
==28577== 
==28577== Open file descriptor 0: /dev/pts/3
==28577==    <inherited from parent>
==28577== 
==28577== 
==28577== HEAP SUMMARY:
==28577==     in use at exit: 0 bytes in 0 blocks
==28577==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==28577== 
==28577== All heap blocks were freed -- no leaks are possible
==28577== 
==28577== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 19 from 6)
--28577-- 
--28577-- used_suppression:     19 U1004-ARM-_dl_relocate_object
==28577== 
==28577== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 19 from 6)
Illegal instruction

Expected Results:  
In the Valgrind output after gdb was attached, backtrace shows that it failed at test1.cpp:10 whichi is:
 10   cout << endl;
The expected result was that a newline be successfully printed to std::cout.

In the gdb prompt, using info sharedLibrary shows that the system is missing two library debugging information.

0x048434b8  0x04844a10  Yes (*)     /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so

0x040007c0  0x04019408  Yes (*)     /lib/ld-linux-armhf.so.3
(*): Shared library is missing debugging information.

I am not sure if these are the cause of the "unhandled instruction" or if this is really a Valgrind bug.

It also happens when an int type is redirected to std::cout:

  1 /* g++ -g -Wall -Wextra -pedantic test2.cpp -o test2
  2  */
  3 #include <iostream>
  4 
  5 using namespace std;
  6 
  7 int main(int argc, char *argv[]) {
  8 
  9   int my_int = 3;
 10 
 11   // The "<< my_int" below will cause valgrind to crash
 12   cout << my_int;
 13 
 14   return 0;
 15 }

additional URL:
http://sourceforge.net/mailarchive/forum.php?set=custom&viewmonth=&viewday=&forum_name=gphoto-devel&style=nested&max_rows=75&submit=Change+View

I only found two URLs related directly to this error from googling, this was the other one.
Comment 1 Sum 2013-07-29 07:38:14 UTC
Created attachment 81411 [details]
std::cout << std::endl valgrind error
Comment 2 Sum 2013-07-29 07:39:18 UTC
Created attachment 81412 [details]
int redirected to std::cout valgrind error
Comment 3 Vasily 2013-07-29 08:38:37 UTC
Can you provide the output of "objdump - d /path/to/your/compiled/binary"? It will be helpful to identify which instruction means 0xF1010200.
Comment 4 Vasily 2013-07-29 09:17:44 UTC
Unfortunately, I haven't device, so I can't compile your example directly. But it looks like this instruction is: f101 0200 	add.w	r2, r1, #0. For me it works OK with latest Valgrind. Can you test it with trunk version http://valgrind.org/downloads/repository.html ? In the case of error, please, attach compiled binary with example here.
Comment 5 Peter Maydell 2013-07-29 09:26:22 UTC
> disInstr(arm): unhandled instruction: 0xF1010200

This is "SETEND BE" (encoding A1), which means "switch to big-endian mode". So (a) this program is doing something pretty weird and (b) I'm not surprised valgrind isn't supporting it.

(Vasily: that is the Thumb decoding, and we're in ARM mode here.)

Looking at the backtrace I suspect this is the following memcmp-for-rpi implementation:
https://github.com/bavison/arm-mem/blob/master/memcmp.S#L214
(I'm a bit dubious that that is actually the fastest way to do memcmp on this CPU, since as far as i'm aware SETEND is a fairly slow instruction.)
Comment 6 Sum 2013-07-30 04:18:32 UTC
Created attachment 81434 [details]
test1.cpp objdump
Comment 7 Sum 2013-07-30 04:19:07 UTC
Created attachment 81435 [details]
test2.cpp objdump
Comment 8 Sum 2013-07-30 04:21:55 UTC
Hi Vasily, sure, please find the two objdumps of compiled form of test1.cpp and test2.cpp.
Comment 9 Sum 2013-07-30 06:09:42 UTC
(In reply to comment #4)
> Unfortunately, I haven't device, so I can't compile your example directly.
> But it looks like this instruction is: f101 0200 	add.w	r2, r1, #0. For me
> it works OK with latest Valgrind. Can you test it with trunk version
> http://valgrind.org/downloads/repository.html ? In the case of error,
> please, attach compiled binary with example here.

Hi when I do the configure step I get this error:

checking for a supported CPU... no (armv6l)
configure: error: Unsupported host architecture. Sorry

... now I will follow instructions to apply the patch:
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=66&t=7689
Comment 10 Sum 2013-07-30 07:34:17 UTC
Created attachment 81437 [details]
Valgrind Trunk with patch make check failure
Comment 11 Sum 2013-07-30 07:35:32 UTC
Created attachment 81438 [details]
Valgrind Trunk with patch test1.cpp failure
Comment 12 Sum 2013-07-30 07:35:52 UTC
Created attachment 81439 [details]
Valgrind Trunk with patch test2.cpp failure
Comment 13 Sum 2013-07-30 07:40:49 UTC
Created attachment 81440 [details]
test1 binary
Comment 14 Sum 2013-07-30 07:41:25 UTC
Created attachment 81441 [details]
test2 binary
Comment 15 Sum 2013-07-30 07:44:53 UTC
Created attachment 81442 [details]
test1.cpp
Comment 16 Sum 2013-07-30 07:45:20 UTC
Created attachment 81443 [details]
test2.cpp
Comment 17 Sum 2013-07-30 07:49:47 UTC
I was able to follow instructions from here successfully to apply the patch
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=66&t=7689

.... except for make check failiing (log: "Valgrind Trunk with patch make check failure").

Compiled binaries are also attached (test1 binary, test2 binary) along with the example C++ files (test1.cpp, test2.cpp).

The Valgrind checked out from svn version is:

$ valgrind --version
valgrind-3.7.0.SVN

I am not sure how to modify the patch so the latest version is used.

Thanks Vasily and Peter Maydell for all your help!
Comment 18 Vasily 2013-07-31 07:42:30 UTC
Hello, Mr. Sum.

Please, attach here also the output of objdump -d /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so.

And one question - why 3.7.0? Did you use the instruction from http://valgrind.org/downloads/repository.html ? Current trunk is valgrind-3.9.0.SVN.
Comment 19 Sum 2013-07-31 08:13:14 UTC
Created attachment 81474 [details]
libcofi_rpi.so objdump
Comment 20 Sum 2013-07-31 08:18:55 UTC
Created attachment 81475 [details]
valgrind trunk configure step error
Comment 21 Sum 2013-07-31 08:21:44 UTC
Hi Mr Vasily.
Thanks for your reply. Please find attached the output from (libcofi_rpi.so objdump):
objdump -d /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
... it's a tar.bz2 file as it is relatively large.

Yes I used the instructions from http://valgrind.org/downloads/repository.html. I got an error at the configure step:
./configure
checking for a supported CPU... no (armv6l)
configure: error: Unsupported host architecture. Sorry

I've attached the output from configure "valgrind trunk configure step error". As I was not able to run the configure command, that's when I tried the patch at
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=66&t=7689

I'll try again to see if I can compile it for the latest 3.9.0 tomorrow. Thanks.
Comment 22 Julian Seward 2013-09-12 14:01:31 UTC
(In reply to comment #5)
> > disInstr(arm): unhandled instruction: 0xF1010200
> 
> This is "SETEND BE" (encoding A1), which means "switch to big-endian mode".
> So (a) this program is doing something pretty weird and (b) I'm not
> surprised valgrind isn't supporting it.

Urk!  Can't we persuade the RPI people not to ship such a bizarre
hack?  I have exceedingly little enthusiasm to try and support this.
Comment 23 Peter Maydell 2013-09-12 14:09:28 UTC
(In reply to comment #22)
> Urk!  Can't we persuade the RPI people not to ship such a bizarre
> hack?  I have exceedingly little enthusiasm to try and support this.

Me neither :-) [it doesn't work in QEMU either]. I'm surprised that it's faster, given that as I understand it SETEND is a pretty slow instruction in hardware. I assume whoever implemented it benchmarked it though...
Comment 24 Julian Seward 2013-09-19 15:53:24 UTC
(In reply to comment #22)
> I have exceedingly little enthusiasm to try and support this.

On further consideration it's not merely a question of "little
enthusiasm", but more like "would require major rework of the
ARM-level JIT machinery to fix".  So I'm going to WONTFIX this.

Please, Raspbian people, take this horrible hack out of your libc.
Comment 25 Sum 2013-09-20 09:48:22 UTC
Hi Mr Julian, Mr Peter and Vasily, thanks for your time and the information.
Comment 26 mugnyte@yahoo.com 2013-11-07 05:08:40 UTC
Given the comments from the Raspbian folks on this:
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=66&t=60166

It seems the SETEND instruction is open for use, and a valid instruction.  It's still in v5.03 of their toolchain: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489e/Cjacabbf.html

So I'm guessing ARMv6/ARMv7 are not actually a supported platforms.  This doesn't completely jive with the supported platforms page or rankings (circa 2011):
http://valgrind.org/info/platforms.html

I would suggest reopening or clarifying on the Platforms page.  I appreciate your work folks, really.  But if this is WONTFIX, please don't advertise ARM is supported.   I would put in a kind word to consider it worthy of supporting, but you know your priorities best.
Comment 27 Julian Seward 2016-09-15 06:41:15 UTC
This keeps cropping up, for example most recently in bug 366464.  Maybe
I should explain more why this isn't supported.  It's because we don't have
a feasible way to do it.  Valgrind's JIT instruments code blocks as they are
first visited, and the endianness of the current blocks are "baked in" to the
instrumentation.  So there are two options:

(1) when a SETEND instruction is executed, throw away all the JITted code
    that Valgrind has created, and JIT new code blocks with the new endianness.

(2) JIT code blocks in an endian-agnostic way and have a runtime test
   for each memory access, to decide on whether to call a big or little
   endian instrumentation helper function.

(1) gives zero performance overhead for code that doesn't use SETEND but
  a gigantic (completely infeasible) hit for code that does.

(2) makes endian changes free, but penalises all memory traffic regardless of
  whether SETEND is actually used.

So I don't find either of those acceptable.  And I can't think of any other way to
implement it.

Truth be told, I don't believe this is really even necessary, either.  In the old days,
on x86 (32-bit) linux and ppc32-linux (note: 32-bit, little- and big-endian respectively)
glibc used platform-specific code -- sometimes in C, sometimes in assembly -- to
implement str* functions, and these normally process data in 32 bit chunks.  For
example strlen on x86 was done with 32 bit loads and some tricks to do with
carry bit propagation, by adding magic constants 0x80808080 and/or 0xFEFEFEFF
to the loaded values.

So I don't get why rpi has to be special about this.  Why can't it just follow existing
practice?
Comment 28 Julian Seward 2016-09-15 06:44:43 UTC
*** Bug 366464 has been marked as a duplicate of this bug. ***
Comment 29 Peter Maydell 2016-09-15 07:02:16 UTC
The way QEMU's JIT handles this kind of thing is that we track each translated code block by (start PC, cpu state flags), where the flags track the subset of the CPU's current state that we've baked into the translation. One of those state flags is "is CPSR.E set?", so when we later come to check whether we've already translated a code block we won't return one that was translated assuming the "wrong" endianness. (We also use this to be able to generate code that makes assumptions about the current setting of VFP vector length and stride, Thumb condexec bits, and some other stuff that only matters for kernel-mode code emulation.) This avoids the downsides of your options (1) and (2), though it does require that you're doing lookup of code blocks by something other than raw PC, which QEMU does anyway.

I agree that rpi's memset implementation is a bit weird, but on the hardware they use (ARM1176) SETEND is pretty nearly free and it turns out to be fastest. They're not going to change it now, it's more likely that the rpi1 will vanish into the mists of history first.
Comment 30 Julian Seward 2016-09-15 10:50:56 UTC
(In reply to Peter Maydell from comment #29)
> The way QEMU's JIT handles this kind of thing [..]

Thanks for the explanation.  I was indeed wondering how QEMU handled this.

Yes .. if I could redo the basic JIT architecture, I would indeed by very tempted
to add some facility for speculative and multiversioned block translations.  I
think that would be useful from a performance standpoint.
Comment 31 Peter Maydell 2016-09-15 11:14:14 UTC
If your JIT architecture doesn't permit a QEMU-style approach I would be tempted to go with "implement SETEND to throw away JITted code and print a warning about poor performance". At the moment people trying to valgrind code that uses it find valgrind doesn't run their code at all, which you could define as infinitely slow :-)

Alternatively, if valgrind could do a redirection of memcmp() in the offending .so file to its own implementation (the way it already does for a bunch of other functions) that would be a very raspi-specific hack but would cover 90%+ of the complaints I suspect (and you could combine this with the slow-SETEND implementation to handle the last 10%).

I don't have a raspi though so this is all just commentary from the peanut gallery.
Comment 32 Mark Wielaard 2016-09-15 17:19:56 UTC
(In reply to Peter Maydell from comment #31)
> Alternatively, if valgrind could do a redirection of memcmp() in the
> offending .so file to its own implementation (the way it already does for a
> bunch of other functions) that would be a very raspi-specific hack but would
> cover 90%+ of the complaints I suspect

valgrind should already intercept the memcmp from glibc. This one however is in a different library libcofi_rpi.so which looks like some kind of hack to interpose some standard libc functions. It seems this is actually preloaded somehow. So it might be as simple as removing the preload hack when running under valgrind?
Comment 33 Peter Maydell 2016-09-15 18:10:43 UTC
(In reply to Mark Wielaard from comment #32)
> valgrind should already intercept the memcmp from glibc. This one however is
> in a different library libcofi_rpi.so which looks like some kind of hack to
> interpose some standard libc functions. It seems this is actually preloaded
> somehow. So it might be as simple as removing the preload hack when running
> under valgrind?

The idea would be to do something which works out of the box; otherwise you won't stop the trickle of bug reports (and probably larger set of users who just decide valgrind doesn't work without reporting a bug).
Comment 34 Mark Wielaard 2016-09-15 18:20:19 UTC
(In reply to Peter Maydell from comment #33)
> (In reply to Mark Wielaard from comment #32)
> > valgrind should already intercept the memcmp from glibc. This one however is
> > in a different library libcofi_rpi.so which looks like some kind of hack to
> > interpose some standard libc functions. It seems this is actually preloaded
> > somehow. So it might be as simple as removing the preload hack when running
> > under valgrind?
> 
> The idea would be to do something which works out of the box; otherwise you
> won't stop the trickle of bug reports (and probably larger set of users who
> just decide valgrind doesn't work without reporting a bug).

Sure. But that requires someone with a raspi and knowledge of what this libcofi_rpi.so hackery really is.
Comment 35 Jeffrey Walton 2017-02-01 15:00:00 UTC
(In reply to Julian Seward from comment #27)
> This keeps cropping up, for example most recently in bug 366464.  Maybe
> I should explain more why this isn't supported....
>
> Truth be told, I don't believe this is really even necessary, either...

Here' another alternative that was not available in 2013: run a different distro on the RPI, like openSUSE or CentOS.

Here's a compelling reason to do so for some RPI devices, like the Raspberry Pi 3 (if the incompatibilities were not enough): performance. The RPI3 uses an ARM-32 armhf image and its under-performing on the ARMv8/Cortex-A53 processor it has. Also see https://stackoverflow.com/questions/41956400/thread-performance-issues-for-java-on-raspberry-pi?noredirect=1#comment71101862_41956400 .
Comment 36 Tom Hughes 2017-02-01 15:07:01 UTC
*** Bug 358620 has been marked as a duplicate of this bug. ***
Comment 37 WernerF 2017-02-01 18:09:36 UTC
Thanks for your explanation.
After all this history and comments like "This keeps cropping up..." why don't you put a comment on the valgrind download page saying that Raspian ist not supported. Everybody could benefit from it and save a lot of time.
Apart from that, I really do appreciate your work on valgrind. Great tool.
Comment 38 Graham Leggett 2017-05-20 22:41:38 UTC
Having smashed headlong into this issue yet again, I have raised the following issue in an effort to get the RPi people to fix this bug:

https://github.com/RPi-Distro/repo/issues/68
Comment 39 Graham Leggett 2017-05-22 23:40:16 UTC
For the record, moving /etc/ld.so.preload out of the way and in the process disabling the RPI's memcpy optimisations causes valgrind to run correctly on the RPi.
Comment 40 Paul Floyd 2024-01-24 08:24:22 UTC
This is also fixed in more recent Raspberry Pi OS versions of libarmmem. See

https://stackoverflow.com/questions/17430731/valgrind-returning-an-unhandled-instruction-on-raspberry-pi

and the contained link

https://github.com/bavison/arm-mem/pull/5