I'm trying to gdb a program under Linux. It's a compiler of a language that uses some include files (this language include files, not C/C++ includes) that get properly loaded when running the app normally. When run under gdb, the app complains that it couldn't find these include files. I've checked gdb's internal pwd, and it is exactly the same as when run stand-alone. What could be the problem? How can I fix it?
Note that this compiler doesn't use any environment variables, it gets its includes from current directory, it seems.
you can set the source directories path in gdb..
go through the source path in gdb document.
https://sourceware.org/gdb/download/onlinedocs/gdb/Source-Path.html#Source-Path
Related
I encountered a build issue with visual studio's 'link.exe' tool, and at some point, which I would have normally investigated by passing my build command as an argument to linux's strace -efile tool to get a dump of all the files considered by the linker, which couldn't be found and which were selected. But of course, we're on Windows this time, and strace is not an option.
the problem was indeed the linker picking the wrong file when I said ntoskrnl.lib on the command line
the root cause was an invalid %LIB% contents that wasn't matching the include paths passed to cl.exe calls
Question: how could I force link.exe to reveal the full path of the files it is linking (including .lib) ? (and save myself this hassle next time)
So I am working on a project that is intended to run on a remote server. I develop the program on a local pc, compile it, then upload it to the remote server. Both the local pc and the remote server are run on CentOS 7.7.
The program is developed using the CLion IDE, configured with CMake. The program depends a few shared libraries, which are supposed to link to the executable according to what I wrote in CMake. At my local PC, I can compile and run the program perfectly. However, after I scp the whole directory of the project to the remote server, the executable fails to run. It cannot find any of the ".so" files, according to what ldd says.
This is my CMakeList.txt, with every path being relative path, instead of absolute path.
cmake_minimum_required(VERSION 3.15)
project(YS_Test)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_PATH_ src)
file(GLOB SOURCE_FILES_ ${SOURCE_PATH_}/*.*)
set(PROJECT_LIBS_ libTapQuoteAPI.so libTapTradeAPI.so libTapDataCollectAPI.so)
include_directories(api/include)
link_directories(api/lib/linux)
add_executable(YS_Test ${SOURCE_FILES_})
target_link_libraries(YS_Test ${PROJECT_LIBS_})
Please do not tell me to set LD_LIBRARY_PATH to fix my issue. The program worked fine on my local pc without LD_LIBRARY_PATH, so I expect it to run on the remote server without LD_LIBRARY_PATH. I would like to know what is really going on here, instead of a work around. Thanks!
If I understand your problem correctly, you want to ship your compiled YS_Test program along with some dependencies and have it run on a remote server. By default an executable will only look in the directories configured in /etc/ld.so, which will not include the deploy path.
Note: Typically you do not deploy your entire build directory but only the compiled artifacts and dependencies. For this answer I will assume you deploy the binary and its dependencies to the same directory.
You have two options:
Require users of your program to set LD_LIBRARY_PATH, either by themselves or by a wrapper script. This variable will instruct the dynamic linker to look in the specified directories as well. Even if you do not like this solution, it is by far the most common approach.
Add -Wl,-rpath='$ORIGIN' to your linker options. This will add a DT_RUNPATH attribute to the executable's dynamic section. As you are using CMake you can also set this using BUILD_RPATH and/or INSTALL_RPATH target properties.
The ld.so manpage describes this attribute as follows:
If a shared object dependency does not contain a slash, then it is
searched for in the following order:
...
Using the directories specified in the DT_RUNPATH dynamic section
attribute of the binary if present.
The $ORIGIN part expands to the directory containing the program or shared
object.
If you really insist on shipping your build directory (eg during development), you can take a look at the CMake BUILD_RPATH_USE_ORIGIN property (and its usual global counterpart CMAKE_BUILD_RPATH_USE_ORIGIN), this will embed relative paths into binaries instead of absolute paths.
As you don't want a workaround (#Botje has given you two already), I will try an explanation instead. In your development machine, if you use this command:
ldd YS_Test
You will see all the shared libraries used by your program, with their corresponding paths. The libTapQuoteAPI.so libTapTradeAPI.so libTapDataCollectAPI.so are found at your 'api/lib/linux' directory, but resolved with full absolute paths. If you do the same at your server, some shared objects can't be resolved because they aren't at the same location.
If you use one of these commands (not sure which are available in Centos):
chrpath --list YS_Test
or
patchelf --print-rpath YS_Test
You will see the RPATH or RUNPATH tags embedded in your program. This is the path used by the Linux linker to locate dependencies that are outside the standard ld locations. You may find extended explanations on Internet about this, like this one or the Wikipedia article.
Breaking my promise, I give you a third workaround: use patchelf or chrpath at your server after scp to change the embedded RPATH tag, pointing it relative to $ORIGIN (which represents the program location).
I am building an Eclipse plug-in that have to parse the result of an executable (Linux) to display informations to the user. The executable should be embedded in the plug-in, not installed apart.
I first made a small prototype, in which I've embedded a fake executable, then before launching the executable, I extract it into a temporary file, build my command line and then launch it. That worked ok for me.
I've just received the real executable, and then realised it was not a standalone executable, but a bunch of libraries, config files and such. It comes also with a script to execute in order to set env variables.
The only option I am seeing now is to extract the whole bunch to a temp directory, set the environment variables according to the script, and then call my executable.
Is my solution valid ? Do you think of a better way to do it ?
Don't package the plugin as a jar, instead just use a directory so you don't have to do any unpacking.
You specify this using
Eclipse-BundleShape: dir
in the plugin MANIFEST.MF.
Note: if you package your plugins in a feature then this setting is overridden by the unpack="true" attribute of the plugin element in the feature.xml file.
On a Linux system, I am trying to run a Fortran program that makes use of some shared libraries (netCDF libs, if that makes a difference). Before I run, I set LD_LIBRARY_PATH so that it points to the location of my libraries. Then I run the executable and I quickly get the error
../my_program: error while loading shared libraries: libnetcdff.so.5: cannot open shared object file: No such file or directory
Now, I double check the value of LD_LIBRARY_PATH, and then cd to it and find plain as day
$ ls *ff*
$ libnetcdff.a libnetcdff.la libnetcdff.so libnetcdff.so.0 libnetcdff.so.0.0.0
So the libnetcdff is absolutely present.
Could anyone point me to the problem?
The one thing that has occurred to me is that the executable seems to want to find libnetcdff.so.5, while the library that is present is actually libnetcdff.so.0. Is that the problem? If so, is there a way to convince the executable to not insist on "5"? Alternatively, would a link from libnetcdff.so.0 to libnetcdff.so.5 solve the problem? (I don't have permissions in the directory, BTW, which is why I haven't tried that yet.)
Environment info: CentOS machine, code compiled with gfortran. And yes, when I compiled, my -L flags were pointing to the same directory that LD_LIBRARY_PATH points to.
Thanks.
A library link should work. Since you mention that you do not have root/sudo access, what you can do is link in a file you do have access in:
ln -s /path/to/libnetcdff.so.0 /path/you/have/access/to/libnetcdff.so.5
And then add in the /path/you/have/access/to/ in your LD_LIBRARY_PATH.
So I have scons working with an alternate build location (build/ for my output files, src/ for my input files) and it works great. Except for one thing.
I'm using an IDE (TI Code Composer 4) to debug my program. I point the IDE at the output executable to run it, and what it uses for the source files for debugging is the build/ directory. I don't really care, except when I go to edit the file in the IDE, for example main.cpp, the file is really build/main.cpp which gets clobbered as soon as I run scons again. I have to remember to edit src/main.cpp instead. I am aware of this issue and yet I make the same mistake often.
Is there a way to have scons make the source files it copies into the build path read-only? (I'd ask how to get TI CCS4 to use the right source files when it is debugging an executable, but I doubt I'd get any answers.)
This page has information about wrapping InstallTargets with a chmod call.
FYI, the scons user list is quite active with many knowledgeable people and you can get answers pretty quickly.
You could always tell scons not to duplicate source files in the build directory:
SConscript('src/SConscript', variant_dir='build', duplicate=0)