You don't need to be an 'investor' to invest in Singletrack: 6 days left: 95% of target - Find out more
Ok. We use an tool called iperf to measure network performance, running off a USB pendrive. I've waxed lyrical about this before: http://singletrackmag.com/forum/topic/linux-help-sil-vous-plait-installing-multiple-versions-of-packages As per the previous thread, I'm having to compile it from source to fix a [s]bug[/s] feature which messes up the testing.
I've now been asked to do the same to run on a Raspberry Pi. So far so froody, download the source, then:
./configure
make
checkinstall
And hey presto, one .deb file. Except, it doesn't work, it installs fine but then subsequently running iperf3 at the command line just spits out "Illegal instruction" and that's all she wrote. Googling suggests that this happens when it's compiled for the wrong architecture, but I've just built it on the device I'm trying to run it on!
Any ideas? I don't even know where to begin in troubleshooting this.
I'll watch this as I run into problems with bespoke bits of software on the office Macs. The various bulletin boards assume a level of knowledge I don't currently possess and it's a wonder we still have functioning IT here!
A good start would be:
filewhich iperf
And that'll tell you the arch it's built for.
EDIT: Forum killed the backtics. Run "file" on the iperf binary you end up with.
E.g. on a x86_64 machine:
file /bin/ls
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=eca98eeadafddff44caf37ae3d4b227132861218, stripped
Don't have an ARM box on to check that...
Oh, and "--pkgarch" on checkinstall sets the arch the package is built for, FWIW.
Well I have compiled from source on a RPi to get something for which there was only an older version available, so probably one step ahead of most people. Though I did ./configure; make; make install as it made a binary rather than a deb. Does yours just make the deb or is there also an executable you can try installing in that way?
...oh and the issues I can remember with that were simply around having to build some of the dependencies from source, though that resulted in errors at compile time so rather different to your issues.
Took me a minute to parse that. You're using which to find the directory it's installed into, then file on that directory, right?
# file /usr/local/bin/iperf3
/usr/local/bin/iperf3: ELF 32-bit LSB executable, ARM, EABI5 version 1
(SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for
GNU/Linux 2.6.32, uildID[sha1]=f4167a59fd81c3117258ff44b8fc2ea528754bc2,
stripped
[quote=IA ]Don't have an ARM box on to check that...
On a RPi:
[code]
/bin/ls: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=5e052e8de057d379ab51d4af510ad9318fe77b46, stripped
[/code]
edit: crossposting with Cougar, but that shows his iperf is compiled for the same architecture as /bin/ls
Looks about right, then.
BTW what tags are you using for your code boxes, Cougar?
Backtick. The [ code ] tags do similar I think.
Ok, so you're building for the right arch.
I'd be inclined to have a quick look with gdb and see if it illuminated any more:
gdb iperf3
then bt to see the stack when it bails out.
bt reports "No stack."
I found this:
https://www.raspberrypi.org/documentation/linux/kernel/building.md
Talking about cross-compiling. In lieu of any better ideas it might have a punt building it on a Lubuntu box, but I think that's a job for tomorrow.
Ah sorry you have to run first.
Though my current thinking is you somehow have a build for the wrong arm instruction set version, but I forget how to check/change that...
Interesting.
(gdb) run
Starting program: /usr/local/bin/iperf3
Program received signal SIGILL, Illegal instruction.
0xb6f85f0c in ?? () from /usr/lib/arm-linux-gnueabihf/libiperf.so.0
(gdb) bt
#0 0xb6f85f0c in ?? () from /usr/lib/arm-linux-gnueabihf/libiperf.so.0
#1 0xb6fdeffc in call_init (Cannot access memory at address 0x0
l=<optimized out>, argc=1, argv=0xbefff794,
env=0xbefff79c) at dl-init.c:78
#2 0xbefff794 in ?? ()
Cannot access memory at address 0x0
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb)
So, that's a problem in the library, not my build? (iperf3 requires a library, libiperf0, to be installed first).
I got the library precompiled - should I have a go at creating that from source too? Is it the same process or is there some quirks with libraries?
Yup. Where did you get libiperf from?
If it's a debian arm build rather than a specific raspi one, it'll be an armv7 build (or higher) but it needs to be armv6 or lower (different floating point capability).
Another thing to try would configure like this before you build it:
./configure --extra-cflags="-march=armv6"
(guessing here about what the configure script supports)
Same process to build the lib, no quirks.
Running file on the offending .so may (or may not) be revealing too.
Yup. Where did you get libiperf from?
That's a good question. I'm not sure. It might have been here:
https://iperf.fr/iperf-download.php
... which looking at it is a generic armhf build rather than pi-specific. I'll bin it and grab the one from the repository.
Hard float ABI problems if this is a RPi (ARMv6) rather than RPIv2 or RPiv3, at a guess.
Debian doesn't admit to the existence of the ABI used on the ARMv6, hence the original need for Raspbian.
... aaaand that's nailed it. \o/ Nice one, thank you.
However, the repository version is an older version (3.0.7 to our current 3.1.3) - how much of a difference that's going to make I don't know. I can't immediately find anywhere to snag a later version of the source.
hard float ABI problems if this is a RPi (ARMv6) rather than RPIv2 or RPiv3.
I don't really follow all of that, but this is a Pi2 not an original Pi (and I have a Pi3 here too).
Ha, so I actually nailed it with my first comment - should have made more of a point of that. If you're not installing it from the RPi repos using apt-get then you have to build from source, IME nothing precompiled from other sources works.
[quote=Cougar ]I can't immediately find anywhere to snag a later version of the source.
from the link you gave to your binaries?:
That's iperf itself, not libiperf0...
Quick skim of that source code and the makefiles it looks like it builds the lib too? Of course whether or not you're building them into your deb....
Try removing/purging the system libiperf you have, iperf, and reinstall your build deb.
Yeah, I was coming to that conclusion when scouring the Internet for the source. So, what, without the lib installed it uses its own, and if you install the lib then it uses that instead?
I've got a second one on the go at the mo, so will try again from scratch once it's completed. One of the reasons for creating a package rather than make install is that I want it portable to do multiple installs.
It builds both - I've just compiled on mine to check! I'm not sure how you get the .deb files as it's just made the binary and lib, but they're there in the src/.libs directory. If you do "make install" it installs the library in /usr/local/lib so you'd have to put that in your library path (it isn't by default, so doesn't find the library).
BTW my reported architecture above is from an original RPi, not an RPi2 or 3, which is what I've also just built on.
Nice one, cheers. I'm using checkinstall to make the package.
Built the deb now with checkinstall (had to rerun ./configure and make and run as root). It contains libiperf, however as mentioned above I suspect the issue when installing that is that as default libiperf installs to /usr/local/lib - that's the standard behaviour for user compiled libraries, however as default it's not included in the library search path, so it will use whatever else you've installed, or report an error if you haven't. At a basic level "export LD_LIBRARY_PATH=/usr/local/lib" will make that work, though there are better ways I can't quite remember right now, and I'd have to do the same research as you...
BTW it is normal for source code to also include source for dependent libraries, which is why I expected it to be there.
At a basic level "export LD_LIBRARY_PATH=/usr/local/lib" will make that work
What does that do? Is it likely to break anything else?
BTW it is normal for source code to also include source for dependent libraries, which is why I expected it to be there.
Right. Weird that they're separate download packages on that iperf.fr site then...?
LD_LIBRARY_PATH? It just sets the library search path. Not likely to break anything else unless you have other dodgy libraries in /usr/local/lib
It's also normal for a single lot of source to create multiple packages (I was almost expecting to see 2 .deb files created).
I mean, it's presumably pointing somewhere else to start with, so you're changing it rather than adding to the search list? Or does it not work like that?
And yeah, that works, though I'd to do ldconfig to refresh... something? Library cache or some such. (I read that earlier, can't remember exactly.)
Ah, ldconfig sounds like part of the proper way to do it.
Strictly speaking you should probably do:
[code]export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib[/code]
to preserve existing path, but LD_LIBRARY_PATH was empty on mine - it's just the user library path, the system path is separate. I'm not at all an expert on this, just what I've used which works!
There'll be a configure switch to set it to install the libs to the appropriate system path and avoid that faff.
I should probably have quoted what it says when you run make install or checkinstall in case Cougar didn't spot it:
[code]
----------------------------------------------------------------------
Libraries have been installed in:
/usr/local/lib
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the 'LD_RUN_PATH' environment variable
during linking
- use the '-Wl,-rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to '/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
[/code]
I either didn't spot it or bleeped over it. Thanks again.
Re:
- have your system administrator add LIBDIR to '/etc/ld.so.conf'
I've just looked at this file and it's just an include for all .conf files in /etc/ld.so.conf.d. There are four files here, one of which is libc.conf which has the /usr/local/lib path in it. How come this doesn't work? Is it just for that one program? Ie, the "correct" way would be to create an iperf3.conf file here with the library path in it?
Is it just you needed to run ldconfig as a post-install step? Though not sure why it wasn't automated in that case. I don't have the time to try building iperf here for a closer look though.
To test, do your install from deb, then ldconfig -p and see if it's listed (or something like ldconfig -p | grep iperf) if it's not, sudo ldconfig and test again.