gdbembeddeddynamic-linkingqnxshared-objects

Why is gdb refusing to load my shared objects and what is the validation operation


Main question:

In Ubuntu trying to debug an embedded application running in QNX, I am getting the following error message from gdb:

warning: Shared object "$SOLIB_PATH/libc.so.4" could not be validated and will be ignored.,

Q: What is the "validation" operation going on ?

After some research I found that the information reported by readelf -n libfoo.so contains a build-id and that this is compared against something and there could be a mismatch causing gdb to refuse to load the library. If that's the case what ELF file's build-id is the shared object's build-id compared against ? Can I find this information parsing the executable file ?

More context:

I have a .core file for this executable. I am using a version of gdb provided by QNX and making sure I use set sysroot and set solib-search-path to where I installed the QNX toolchain.

My full command to launch gdb in Ubuntu is :

$QNX_TOOLCHAIN_PATH/ntox86_64-gdb --init-eval-command 'set sysroot $SYSROOT_PATH' --init-eval-command 'set solib-search-path $SOLIB_PATH --init-eval-command 'python sys.path.append("/usr/share/gcc-8/python");' -c path-to-exe.core path-to-executable-bin

Gdb is complaining that it cannot load shared objects :

warning: Shared object "$SOLIB_PATH/libc.so.4" could not be validated and will be ignored.


Solution

  • The big thing here is to make sure you're using the exact same binary that is on the target (that the program runs over). This is often quite difficult with libc, especially because libc/ldqnx are sometimes "the same thing" and it confuses gdb.

    The easiest way to do this is to log your mkifs output (on the linux host):

    make 2>&1 | tee build-out.txt
    

    and read through that, search for libc.so.4, and copy the binary that's being pulled onto the target into . (wherever you're running gdb) so you don't need to mess with SOLIB paths (the lazy solution).

    Alternatively, scp/ftp a new libc (one that you want to use, and ideally one that you have associated symbols for) into /tmp and use LD_LIBRARY_PATH to pull that one (and DL_DEBUG=libs to confirm, if you need). Use that same libc to debug

    source: I work at QNX and even we struggle with gdb + libc sometimes