Link to home
Start Free TrialLog in
Avatar of FarcoTech

asked on

gphoto2 cross compile for arm

I have cross-compiled libgphoto2 and gphoto2 to run on an arm processor. When I run:
$ strace gphoto2 -about
I get the following with a segmentation fault. Can anyone see a solution to this?
open("/mnt/flash/lib/libgphoto2/", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFDIR|0750, st_size=2048, ...}) = 0
fcntl64(3, F_GETFD)                     = 0x1 (flags FD_CLOEXEC)
getdents(3, /* 4 entries */, 4096)      = 72
getdents(3, /* 0 entries */, 4096)      = 0
close(3)                                = 0
access("/lib/dlopen.a", R_OK)           = 0
gettimeofday({1284090621, 931380}, NULL) = 0
open("/mnt/flash/lib/libgphoto2/", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0640, st_size=901, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40020000
read(3, "# - a libtool library fi"..., 4096) = 901
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x40020000, 4096)                = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
Segmentation fault

Open in new window

Avatar of Duncan Roe
Duncan Roe
Flag of Australia image

The segfault is not necessarily related to the preceding munmap or in fact to any system call. gdb would be a better tool than strace here - compile everything -g at least and -g3 -ggdb for best results. Then gdb gphoto2 -about will pinpoint the problem.
It is possible that compiling -g will make the problem go away - up to you what to do if that happens.
Also, reducing optimization level can sometimes get rid of problems like this - makes gdb easier to follow also.
Avatar of FarcoTech


Thanks Duncan,
The gphoto2 is being executed on the embedded platform with arm processor. Currently I do not have gdb for the board and source codes are also on the host not the board. Life is a lot easier on a desktop environment! A few years ago I had done remote debuging using gdbserver on the board and gdb on the desktop with source but this is going to take a while to setup and I do not have the time to do it.

Any other suggestion?
Turn off all optimizing in the build and see if that fixes it. If not, turn on -g and see if that fixes it (it did fix the last release of fvwm95, which I am still using).
How do you get software onto the embedded platform? I'm just wondering if there is any way to get a command prompt on the board. Even without the sources, gdb would give you the source file name and line number.
Embedded system runs linux and I ftp code into it and can telnet to it to get a command shell.
Build gdb for the board then telnet in and gdb gphoto2 -about. Much simpler than using gdbserver - and you could set up nfs to make the sources visible if you like.
Do you have simply copied your binary into the target?
If so, you should use a complete installation instead.
to do so, to an installation into a "fake" target directory, than targz the tree and un-targz-it into the target.

make DESTDIR="/tmp/target-gphoto" install
cd /tmp/target-gphoto
tar zcvf gphoto.tgz ./
scp gphoto.tgz root@

and into the target:

cd /
tar zxvf /tmp/gphoto.tgz

Which kind of build environment are you using?
The best way to install a program like gphoto is to build it from the build environment. If you do not want to reflash the firmware, you can do a nfs boot and work onto that nfs directory...

Hope that helps.
I meant gdb gphoto2; run -about
Sorry I have not been able to follow up this earlier(so many things are going on at the moment). Regarding building and installation in principal I have done what you have suggested (I have used ./configure --prefix=/tmp/target) and then ftped contents of the /tmp/target to the target board using a script.

One thing that could be helpful in figuring out the problem is that the strace output shows:
access("/lib/dlopen.a", R_OK)           = 0

the file /lib/dlopen.a did not exist in the target and I had to find in in my build PC and manually ftp it to the target (of cource ensuring that it is built for the target and not the PC). But it may not be an issue since it appears it has done what it was supposed to do based on the output of the strace??

The other clue is the following lines in the strace output:
munmap(0x40021000, 4096)                = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

The SIGSEGV is error when "Attempted write into a region mapped as read-only." Problem is that the output does not give a clue of what function or process is attempting to write into the read-only region. I am not sure if gdb can give any clue since all function calls are given by strace anyway.

Can you suggest/guess what could be causing the SIGSEV?

First, using --prefix in configure change the compilation and installation path from /usr to /tmp. This means that your program not only will be installed in /tmp/bin and libraries in /tmp/lib, but also all internal path will be /tmp. This is wrong, because this implies that you will install your program in /tmp in the target. But maybe you are copying your binary in /usr/bin or /usr/local/bin. This can make some problem (some program search his plugins or dynamic libraries into $(prefix)/share).
The correct procedure is to compile with --prefix=/destination_target and install by only change the DESTDIR variable with make install. This only copy the installation branch into DESTDIR.
Second. If dlopen does not exist, this means that you haven't installed it into the target device. This can be due to a wrong cross-compilation installation, or maybe not all necessary libraries are installed into the target.
Avatar of Duncan Roe
Duncan Roe
Flag of Australia image

Link to home
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I understand the issue that you have mentioned about the use of --prefix and and have made sure that all needed shared libraries by the program are found and loaded and shown by the output of strace. So I do not think there is any issue with the path to libraries in this instance.

Regarding dlopen, I have manually copied the dlopen.a into the target, since I could not find it on the target. I thought it would be part of libtool but obviously not (I built and ftped across libtool library and binaries but that did not include dlopen). I am not sure what installation of of dlopen involves other than copying the dlopen.a that I have done? Are there other components/libraries that need to be installed with dlopen other than the libtool which I have done?
gphoto2 seems to be well supported in the ARM platform, so I would exclude the "arm bug".
Strange errors and malfunction in the embedded world usually means bad behaving cross-compiler, bad installations and so on. But you never know, I would check if there are some unofficial patch set for gphoto2 for arm - from a quick check with google, I doesn't seems.
So take a cross compilation environment like openembedded or buildroot and check if there is some gphoto2 patches inside, or start from that version.
But I would check your installation, maybe you are mixing host and target libraries.
Second, it seems to me strange that it access dlopen.a file - it's a static library.
What kind of cross-compilation enviroment are you using?
Are the other target program working correctly?
The dlopen function is part of glibc. It's an entry point of /lib/ I had never heard of dlopen.a before and certainly don't have one in /lib (there is one in the build directory of graphviz-2.26.3 now I have looked).
What is the effect of temporarily removing or renaming /lib/dlopen.a from your x86 system?
/mnt/flash/lib/libgphoto2/ is an ld script. Please post them (i.e. from both systems)
Also notice that /lib/dlopen.a is not opened before the segfault, so its contents are irrelevant.
By the way, SIGSEGV is not necessarily "Attempted write into a region mapped as read-only." - it can also be any attempt to access a page of memory which is not mapped.
That's way I supposed a bad installation of gphoto or a broken toolchain.
In my experience, a strange crash of an application in a cross compiled environment 65% of the time is caused by a bad cross compiler (strange binutils + gcc + headers + glibc versions, kernel version and kernel header version incompatibility, strange options in glibc compilation, bad installation of the toolchain...), 25% a bad compilation or installation of the application, 5% a bug in software that only triggers with specific toolchain or kernel options and 5% a bug in software.
And this kind of problem seems related with the first or second case, in my opinion.
So I would start from a cross compiler environment that includes scripts for gphoto2 (like buildroot or openembedded), and if it does not work without modification, investigate with gdb or strace...

Unfortunately openEmbeded build environment does not work for me so I am not able to use "bitbake gphoto2" at the moment. Following is the contents of bitbake recipe for openEmbedded:

DESCRIPTION = "libgphoto2 allows you to access digital cameras"

SECTION = "libs"
DEPENDS = "libtool jpeg virtual/libusb0 libexif"

PR = "r0"

SRC_URI = "${SOURCEFORGE_MIRROR}/gphoto/libgphoto2-${PV}.tar.bz2"

inherit autotools pkgconfig lib_package


EXTRA_OECONF = " --with-drivers=all"

PACKAGES =+ "libgphotoport libgphoto2-camlibs"
FILES_libgphoto2-camlibs = "${libdir}/libgphoto2*/*/*.so*"
RDEPENDS_${PN} = "libgphoto2-camlibs"

FILES_libgphotoport = "${libdir}/*"

FILES_${PN} += "${libdir}/udev/*"
FILES_${PN}-dbg += "${libdir}/*/*/.debug"

SRC_URI[md5sum] = "a60154772635b693ff08b4f34dea7f61"
SRC_URI[sha256sum] = "0dc26b7a8568dee7634bebbaf9f7d3e3ab9460424e6297a595e41c4fddbbdb79"

I am using gcc-arm-linux toolchain version 4.3.2 to build. I have used it for other programs such as strace and openssl and it works fine.

As you have suggested it is most likely to do with some mixup in cross compilation or incorrect library etc, I wish I knew what!

I am attaching the build script that I have made up to build gphoto2 and all required libraries. I have also copied /mnt/flash/lib/libgphoto2/ script below:
# - a libtool library file
# Generated by - GNU libtool 1.5.26 (1.1220.2.492 2008/01/30 06:40:56)
# Please DO NOT delete this file!
# It is necessary for linking the library.

# The name that we can dlopen(3).

# Names of this library.

# The name of the static archive.

# Libraries that this one depends upon.
dependency_libs=' -L/mnt/flash/lib /mnt/flash/lib/ /mnt/flash/lib/ -lpthread /mnt/flash/lib/ -ldl -lm'

# Version information for ptp2.

# Is this an already installed library?

# Should we warn about portability when linking against -modules?

# Files to dlopen/dlpreopen

# Directory that this library needs to be installed in:

I have checked and ensured all the dependency_libs above are present in the target. I am still puzzled why a static library dlopen.a is being accessed?? (that's probably a hint of what the underlaying problem is)

Please let me know if you spot an obvious/potential error in any of the above. I will try the gdb suggestion as soon as I can get some time.
You should NOT copy the LD scripts, since they requires developer tools that aren't usually installed in the target environment.
The first thing I would check is to only build the command lines tools. Now you are configuring the software by letting the script to guess the dependencies, this could potentially expose to misconfiguration, since the script is usually not able to understand what are the host libraries (x86 target) and what to target libraries (arm). So maybe you are compiling the software with some mixed platform configuration. So, first disable all the software you are not required.
I also remove any configuration option you do not strictly need, I would start with only one tool (if it is possible) and check if it works. Use --without-xxx and --disable-xxx configure option to remove all the libraries. see if it works.
After that you can start configuring only what you requires, and check if it works.
I am not quite sure what you mean to "only build command line tools" since gphoto is indeed a command line tool. Also everything that I have included in the build script ( attachment in previous post) is really needed and is a minimal build for a working gphoto.

Also I am not quite sure what you mean by "configuring the software by letting the script to guess the dependencies". If you are referring to the script, all the libraries are needed for the libgphoto2 which is needed by gphoto2. I may have misunderstood what you mean though!
I meant to say that when you run the configure script, it analyze the current building environment to understand what libraries are available and configure the output tools and the configuration options. You can force these options with the --enable/disable-xxx and --with/without-xxx configuration options.
Sometime the configure script misunderstand the options available: for example when it found an header file in the host include dir instead of in the target include directory. This way a target/host mix library linking is highly probable.
What I say is: do not let the configure script guess what libraries are available, disable it with the --without and --disable flags.
I do not mean to say that this is the problem - maybe your script is ok - but in my experience sometime this problem happens.
I got source for gdb and compiled for arm and ran on target for gphoto2 and following is the trace I got after the  SIGSEGV segmentation fault. Looks like libltdl is involved and the problem is in the libgphoto2. You may recall that I had problem in the first place with compiling libgphoto2 for arm and that had something to do with libltdl, but that was sorted!? Anyway I will keep looking to see what I can sort out but in the meantime please let me know if you have a suggestion to solve this problem. Thanks

(gdb) backtrace
#0  0x0007878c in ?? ()
#1  0x4015383c in tryall_dlopen (phandle=0xbea42e7c,
    filename=0x794a8 "dlopen.a", padvise=0x0, vtable=0x0) at libltdl/ltdl.c:430
#2  0x40155e34 in try_dlopen (phandle=0xbea42ed0,
    filename=0x4015a718 "dlopen.a", ext=0x794be ".a", advise=0x0)
    at libltdl/ltdl.c:1430
#3  0x40156774 in lt_dlopenadvise (filename=0x4015a718 "dlopen.a", advise=0x0)
    at libltdl/ltdl.c:1607
#4  0x401565e8 in lt_dlopen (filename=0x4015a718 "dlopen.a")
    at libltdl/ltdl.c:1563
#5  0x4015232c in lt_dlpreload_open (originator=0x4015a1f0 "libltdl",
    func=0x40152ff8 <loader_init_callback>) at libltdl/loaders/preopen.c:353
#6  0x401532cc in lt_dlinit () at libltdl/ltdl.c:237
#7  0x40058b04 in gp_abilities_list_load_dir (list=0x79478,
    dir=0x4009a708 "/mnt/flash/lib/libgphoto2/", context=0x78108)
    at gphoto2-abilities-list.c:192
#8  0x40059310 in gp_abilities_list_load (list=0x79478, context=0x78108)
    at gphoto2-abilities-list.c:320
#9  0x00014ac0 in gp_params_abilities_list (p=0x75568) at gp-params.c:311
#10 0x0001b424 in main (argc=2, argv=0xbea4de34, envp=0xbea4de40)
    at main.c:2038
What is the output from file /lib/dlopen.a ? I would expect  current ar archive
Assuming that's what you see, it is a mistake to try to open it with dlopen() which opens shared ELF objects as you yourself mentioned earlier.
Did you try temporarily removing it on the x86 system?
I wonder if something went wrong at the configure stage of building libgphoto2, such that it believes it needs this file as a dynamic library. I think that's the error you need to find.
Now you  have gdb (well done for that), you could make some nfs mounts so it can see the source (use gdb's dir command to tell it where to look). Then by breakpointing and stepping, you might find out where it reads the name dlopen.a - or that might be heavy going.
Something else to try - remove /lib/dlopen.a on the build system (assuming that doesn't annoy libgphoto2, but it shouldn't). Do a fresh untar of libgphoto2 source, configure for arm and make. My thinking here is that the presence of /lib/dlopen.a may have confused configure. If you keep a record of the build, you can grep it for /lib/dlopen.a, or maybe even compare logs from configuring when it was present and when it was not.

(./configure configure args for arm && make) 2>&1 | tee hee will log everything to hee
Link to home
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks guys. Good suggestions. I will work through them and let you know.
I thought after I last posted - remove /lib/dlopen.and then rebuild libtool before trying to rebuild gphoto2 (for arm in both cases)
file dlopen.a indeed outputs  current ar archive. Removing dlopen.a and rebuilding libtool and gphoto2 made no difference (building libtool recreates dlopen.a)

I have attached the log of configure and make for libgphoto2 and I noticed there are a few warnings in it like:
*** Warning: Linking the shared library against the
*** static library /mnt/flash/lib/libexif.a is not portable!

I also tried some older version of libgphoto2 and gphoto2 (2.4.0 and 2.4.6 and 2.4.7) and that did not make any difference either. Following is output from gdb run (note /mnt/flash/lib/libgphoto2/2.4.7)

Program received signal SIGSEGV, Segmentation fault.
0x00076580 in ?? ()
(gdb) bt
#0  0x00076580 in ?? ()
#1  0x4015283c in tryall_dlopen (phandle=0xbe941e7c,
    filename=0x770b8 "dlopen.a", padvise=0x0, vtable=0x0) at libltdl/ltdl.c:430
#2  0x40154e34 in try_dlopen (phandle=0xbe941ed0,
    filename=0x40159718 "dlopen.a", ext=0x770ce ".a", advise=0x0)
    at libltdl/ltdl.c:1430
#3  0x40155774 in lt_dlopenadvise (filename=0x40159718 "dlopen.a", advise=0x0)
    at libltdl/ltdl.c:1607
#4  0x401555e8 in lt_dlopen (filename=0x40159718 "dlopen.a")
    at libltdl/ltdl.c:1563
#5  0x4015132c in lt_dlpreload_open (originator=0x401591f0 "libltdl",
    func=0x40151ff8 <loader_init_callback>) at libltdl/loaders/preopen.c:353
#6  0x401522cc in lt_dlinit () at libltdl/ltdl.c:237
#7  0x40077a7c in gp_abilities_list_load_dir (list=0x77088,
    dir=0x400b8e78 "/mnt/flash/lib/libgphoto2/2.4.7", context=0x76108)
    at gphoto2-abilities-list.c:192
#8  0x40078288 in gp_abilities_list_load (list=0x77088, context=0x76108)
    at gphoto2-abilities-list.c:320
#9  0x000144ac in gp_params_abilities_list (p=0x73d30) at gp-params.c:311
#10 0x0001a690 in main (argc=2, argv=0xbe94ce14, envp=0xbe94ce20) at main.c:1875

Back to the board again ....

I see:

checking dynamic linker characteristics... GNU/Linux
checking how to hardcode library paths into programs... immediate
checking ltdl.h usability... yes
checking ltdl.h presence... no
configure: WARNING: ltdl.h: accepted by the compiler, rejected by the preprocessor!
configure: WARNING: ltdl.h: proceeding with the compiler's result
checking for ltdl.h... yes
checking for lt_dlinit in -lltdl... yes
checking that we can compile and link with libltdl... yes

Check that warning: Maybe you have some problem with tld.
Try the test suite as I suggested here in comment #33734447

I also see:

checking libexif/exif-data.h usability... yes
checking libexif/exif-data.h presence... no
configure: WARNING: libexif/exif-data.h: accepted by the compiler, rejected by the preprocessor!
configure: WARNING: libexif/exif-data.h: proceeding with the compiler's result
checking for libexif/exif-data.h... yes
checking libexif library flags... "/mnt/flash/lib/libexif.a"
checking libexif cpp flags... "/mnt/flash/include"

You could try to build libexif with only shared library (--enable-shared and --disable-static).

But again, check if tld is working correctly.

Link to home
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial