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.
Created attachment 81411 [details] std::cout << std::endl valgrind error
Created attachment 81412 [details] int redirected to std::cout valgrind error
Can you provide the output of "objdump - d /path/to/your/compiled/binary"? It will be helpful to identify which instruction means 0xF1010200.
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.
> 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.)
Created attachment 81434 [details] test1.cpp objdump
Created attachment 81435 [details] test2.cpp objdump
Hi Vasily, sure, please find the two objdumps of compiled form of test1.cpp and test2.cpp.
(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
Created attachment 81437 [details] Valgrind Trunk with patch make check failure
Created attachment 81438 [details] Valgrind Trunk with patch test1.cpp failure
Created attachment 81439 [details] Valgrind Trunk with patch test2.cpp failure
Created attachment 81440 [details] test1 binary
Created attachment 81441 [details] test2 binary
Created attachment 81442 [details] test1.cpp
Created attachment 81443 [details] test2.cpp
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!
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.
Created attachment 81474 [details] libcofi_rpi.so objdump
Created attachment 81475 [details] valgrind trunk configure step error
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.
(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.
(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...
(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.
Hi Mr Julian, Mr Peter and Vasily, thanks for your time and the information.
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.
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?
*** Bug 366464 has been marked as a duplicate of this bug. ***
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.
(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.
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.
(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?
(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).
(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.
(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 .
*** Bug 358620 has been marked as a duplicate of this bug. ***
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.
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
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.
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