When I use gdb on a coredump it reports some .so it cannot find in a certain path. For example:
Symbol file not found for /root/a/xx.so
I do not have administrator rights to create a directory in root, but I do have the xx.so, and in dbx, I can use pathmap to change the path where I can continue the debug. But in gdb I cannot find the same command.
In addition, I do not have the rights to change the compiler command. That is to say, I can't change the linker path to re-compile.
It sounds like you want set solib-search-path, which takes a colon-delimited list of directory names to search for shared libraries when searching in sysroot fails.
A related command, set sysroot (a.k.a set solib-absolute-prefix), allows you to set any directory as the root used for loading libraries with absolute path names, but you would need to insure that the libraries are laid out in the proper directory structure under the new root, and it sounds like you don't want to do this.
You can try dir command to change to the location of the file.
The command you are looking for is
set substitute-path <from> <to>
Related
When running scripts in bash, I have to write ./ in the beginning:
$ ./manage.py syncdb
If I don't, I get an error message:
$ manage.py syncdb
-bash: manage.py: command not found
What is the reason for this? I thought . is an alias for current folder, and therefore these two calls should be equivalent.
I also don't understand why I don't need ./ when running applications, such as:
user:/home/user$ cd /usr/bin
user:/usr/bin$ git
(which runs without ./)
Because on Unix, usually, the current directory is not in $PATH.
When you type a command the shell looks up a list of directories, as specified by the PATH variable. The current directory is not in that list.
The reason for not having the current directory on that list is security.
Let's say you're root and go into another user's directory and type sl instead of ls. If the current directory is in PATH, the shell will try to execute the sl program in that directory (since there is no other sl program). That sl program might be malicious.
It works with ./ because POSIX specifies that a command name that contain a / will be used as a filename directly, suppressing a search in $PATH. You could have used full path for the exact same effect, but ./ is shorter and easier to write.
EDIT
That sl part was just an example. The directories in PATH are searched sequentially and when a match is made that program is executed. So, depending on how PATH looks, typing a normal command may or may not be enough to run the program in the current directory.
When bash interprets the command line, it looks for commands in locations described in the environment variable $PATH. To see it type:
echo $PATH
You will have some paths separated by colons. As you will see the current path . is usually not in $PATH. So Bash cannot find your command if it is in the current directory. You can change it by having:
PATH=$PATH:.
This line adds the current directory in $PATH so you can do:
manage.py syncdb
It is not recommended as it has security issue, plus you can have weird behaviours, as . varies upon the directory you are in :)
Avoid:
PATH=.:$PATH
As you can “mask” some standard command and open the door to security breach :)
Just my two cents.
Your script, when in your home directory will not be found when the shell looks at the $PATH environment variable to find your script.
The ./ says 'look in the current directory for my script rather than looking at all the directories specified in $PATH'.
When you include the '.' you are essentially giving the "full path" to the executable bash script, so your shell does not need to check your PATH variable. Without the '.' your shell will look in your PATH variable (which you can see by running echo $PATH to see if the command you typed lives in any of the folders on your PATH. If it doesn't (as is the case with manage.py) it says it can't find the file. It is considered bad practice to include the current directory on your PATH, which is explained reasonably well here: http://www.faqs.org/faqs/unix-faq/faq/part2/section-13.html
On *nix, unlike Windows, the current directory is usually not in your $PATH variable. So the current directory is not searched when executing commands. You don't need ./ for running applications because these applications are in your $PATH; most likely they are in /bin or /usr/bin.
This question already has some awesome answers, but I wanted to add that, if your executable is on the PATH, and you get very different outputs when you run
./executable
to the ones you get if you run
executable
(let's say you run into error messages with the one and not the other), then the problem could be that you have two different versions of the executable on your machine: one on the path, and the other not.
Check this by running
which executable
and
whereis executable
It fixed my issues...I had three versions of the executable, only one of which was compiled correctly for the environment.
Rationale for the / POSIX PATH rule
The rule was mentioned at: Why do you need ./ (dot-slash) before executable or script name to run it in bash? but I would like to explain why I think that is a good design in more detail.
First, an explicit full version of the rule is:
if the path contains / (e.g. ./someprog, /bin/someprog, ./bin/someprog): CWD is used and PATH isn't
if the path does not contain / (e.g. someprog): PATH is used and CWD isn't
Now, suppose that running:
someprog
would search:
relative to CWD first
relative to PATH after
Then, if you wanted to run /bin/someprog from your distro, and you did:
someprog
it would sometimes work, but others it would fail, because you might be in a directory that contains another unrelated someprog program.
Therefore, you would soon learn that this is not reliable, and you would end up always using absolute paths when you want to use PATH, therefore defeating the purpose of PATH.
This is also why having relative paths in your PATH is a really bad idea. I'm looking at you, node_modules/bin.
Conversely, suppose that running:
./someprog
Would search:
relative to PATH first
relative to CWD after
Then, if you just downloaded a script someprog from a git repository and wanted to run it from CWD, you would never be sure that this is the actual program that would run, because maybe your distro has a:
/bin/someprog
which is in you PATH from some package you installed after drinking too much after Christmas last year.
Therefore, once again, you would be forced to always run local scripts relative to CWD with full paths to know what you are running:
"$(pwd)/someprog"
which would be extremely annoying as well.
Another rule that you might be tempted to come up with would be:
relative paths use only PATH, absolute paths only CWD
but once again this forces users to always use absolute paths for non-PATH scripts with "$(pwd)/someprog".
The / path search rule offers a simple to remember solution to the about problem:
slash: don't use PATH
no slash: only use PATH
which makes it super easy to always know what you are running, by relying on the fact that files in the current directory can be expressed either as ./somefile or somefile, and so it gives special meaning to one of them.
Sometimes, is slightly annoying that you cannot search for some/prog relative to PATH, but I don't see a saner solution to this.
When the script is not in the Path its required to do so. For more info read http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_01.html
All has great answer on the question, and yes this is only applicable when running it on the current directory not unless you include the absolute path. See my samples below.
Also, the (dot-slash) made sense to me when I've the command on the child folder tmp2 (/tmp/tmp2) and it uses (double dot-slash).
SAMPLE:
[fifiip-172-31-17-12 tmp]$ ./StackO.sh
Hello Stack Overflow
[fifi#ip-172-31-17-12 tmp]$ /tmp/StackO.sh
Hello Stack Overflow
[fifi#ip-172-31-17-12 tmp]$ mkdir tmp2
[fifi#ip-172-31-17-12 tmp]$ cd tmp2/
[fifi#ip-172-31-17-12 tmp2]$ ../StackO.sh
Hello Stack Overflow
When I build, it succeeds with no errors. However, when I run from the IDE, I get an error (my image fails to load because it cannot find the directory).
However, if I go into the folder and run the program(.exe) it finds the image directory perfectly.
mTextures.Load(Textures::Background, "../GFX/Background.png");
^the line of code giving the directory.
I assume this is a problem with a setting I didn't enter correctly in my compiler?
I am using Code::Blocks on Windows.
Your debugger's current directory (i.e. the current directory used when you execute the application from within codeblock) is probably incorrect. Check your project settings, and fix the current directory to your target directory (the one which contains the executable itself).
Specific instructions are here.
It's because you're using a relative path in your file name:
"../GFX/Background.png"
the .. is saying "go up one directory form the current directory". If you want to be able to run your program anywhere, use an absolute path, something like:
"/home/me/GFX/Background.png"
Add the full path where the image exist with double slash.
mTextures.Load(Textures::Background, "C:\\Program Files\\..\\..\\GFX\\Background.png");
While running the application developed by other person, getting the following error
./appln: error while loading shared libraries: libxerces-c.so.28: cannot open shared object file: No such file or directory
And if I run ldd command:
# ldd appln
linux-gate.so.1 => (0x00e20000)
libdl.so.2 => /lib/libdl.so.2 (0x00a61000)
libxerces-c.so.28 => not found
I already have that libxerces-c.so.28 file in current folder. Please help me how to resolve that error
You need to put libxerces-c.so somewhere in the library path. Probably current folder is not searched for libraries. Try putting it in /usr/local/lib
Evidently "the current folder" isn't in the run time search path used by your executable. I'm assuming that you are on linux (linux-gate.so.1).
You need to ensure that "the current" directory is under the search path. You can do this at link time by using the -rpath option to the linker (-R is also accepted) or -Wl,-rpath,<dir> if you are invoking the linker through the compiler front end. This embeds a search path to be used at run time into your program.
Consider how you want the program to be installed, though. There's no point in adding a path that is specific to your development environment. You might want to consider using $ORIGIN or a $ORIGIN relative path which tells the run time linker to look for shared objects in the location containing (or relative to) the executable. You should always avoid adding . to the run time search path; your program shouldn't behave differently depending on the current directory of the process which invokes it.
As a temporary measure you can set the environment variable LD_LIBRARY_PATH to override the embedded and system search paths but it is normally a bad idea to rely on LD_LIBRARY_PATH overrides for a final installation.
By default .so files are NOT being searched in the current folder (they should be in /usr/lib, etc).
To add the current directory for .so lookup use:
LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH ./appln
When adding new "local system" libraries (e.g. in /usr/local/lib/) you better add that directory (/usr/local/lib/) once in your /etc/ld.so.conf and you should run ldconfig to update the linker cache (every time you add something inside /usr/local/lib/)
See ldconfig(8), ld.so(8), ldd(1), dlopen(3)
If you want your own libraries, set LD_LIBRARY_PATH to a directory containing them (e.g. $HOME/lib/ and to standard directories, e.g.
export LD_LIBRARY_PATH=$HOME/lib:/usr/lib:/usr/local/lib
in your ~/.bashrc (but I dislike that confusing practice, and prefer to manage my /usr/local/lib/).
You could also use some -Wl,-rpath argument but I really dislike that also.
Read also Program Library HowTo and Drepper's paper: How To Write Shared Libraries
I have a program which requires liblog4cpp installed to run.
Now, I want the program to run on another machine without liblog4cpp. So I just find the log4cpp.so and move it to the same directory of my program. But at running error reported:
error while loading shared libraries: liblog4cpp.so.4: cannot open
shared object file: No such file or directory
Am I doing it right? How can I tell the program to find the SO file just beside it?
In addition to what others are suggesting, consider adding the file to the dynamic linker's cache. You can do it like this:
ldconfig -l /path/to/lib/liblog4.so.4
To add it to the loader's cache use the following command: ldconfig
Then in order to verify that it was correctly added, run this:
ldconfig -v | grep liblog
Check your LD_LIBRARY_PATH environment variable... One of the directories on the path should point to the location of your log4cpp.so file; also the linux command ldd is handy for determining which shared object libraries are being used in your executable. The syntax is ldd <executable>.
assuming that the path where the .so file/s is available is /path you can also avoid to export an environment variable and just use
LD_LIBRARY_PATH=/path ./myProgram
beware the fact that if you do:
export LD_LIBRARY_PATH=/path
you are resetting LD_LIBRARY_PATH to a single value /path and losing anything you added before to this environment variable. If you want to add a value without losing the previous ones
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path
export LD_LIBRARY_PATH to the path of the library. This env variable works much like the PATH variable. It can contain multiple paths separated by :.
In the rc script from where you are launching your program, you should set the LD_LIBRARAY_PATH before launching the application. Remember, the .so are the shared libraries, it is required at the run time to link. Thus, it should be available in the standard path like /usr/lib before launching.
In case it is not copied in the standard path like /usr/lib then specify the path by using the following.
export LD_LIBRARY_PATH=<new_path_of_so>:$(LD_LIBRARY_PATH)
Ideally, I would have placed this .so in the standard path like /usr/lib. If it is installed in the standard path, then there is no need to set the above path. Remember, to make your program better, put the new path in ldconfig.conf.
You can debug such errors by using the following.
$strace <binary_name>
to know the so dependencies
$ldd <binary_name>
For further, check the below link.
http://www.tune2wizard.com/sharedobject-crash/
After adding shared objects (or shared libraries lib*.so*, or such symbolic links) to system directories like /usr/lib or /lib known to the dynamic linker ld-linux.so(8) (or ld.so) you need to run ldconfig(8)
You could also add them to /usr/local/lib/ but then be sure that /etc/ld.so.conf (or some file /etc/ld.so.conf.d/*.conf) .mentions that directory (and run ldconfig after changing it)
I'm developing a C++ program under Linux. I want to put some stuff (to be specific, LLVM bitcode files, but that's not important) in libraries, so I want the following directory structure:
/somewhere/bin/myBin
/somewhere/lib/myLib.bc
How do I find the lib directory? I tried to compute a relative part from argv[0], but if /somewhere is in my PATH, argv[0] will just contain myBin. Is there some way to get this path? Or do I have to set it at compile time?
How do GNU autotools deal with this? What happens exactly if I supply the --prefix option to ./configure?
Edit: The word library is a bit misleading in my case. My library consist of LLVM bitcode, so it's not an actual (shared) object file, just a file I want to open from my program. You can think of it as an image or text file.
maybe what you want is :
/usr/lib
unix directory reference: http://www.comptechdoc.org/os/linux/usersguide/linux_ugfilestruct.html
Assume your lib directory is "../lib" relative to executable
First you need to identify where myBin located, You can get it by reading /proc/self/exe
Then concat your binary file path with "../lib" will give you the lib directory.
You will have to use a compiler flag to tell the program. For example, if you have a plugin dir:
# Makefile.am
AM_CPPFLAGS = -DPLUGIN_DIR=\"${pkglibdir}\"
bin_PROGRAMS = awesome_prog
pkglib_LTLIBRARIES = someplugin.la
The list of directories to be searched is stored in the file /etc/ld.so.conf.
In Linux, the environment variable LD_LIBRARY_PATH is a colon-separated set of directories where libraries should be searched for first, before the standard set of directories; this is useful when debugging a new library or using a nonstandard library for special purposes.
LD_LIBRARY_PATH is handy for development and testing:
$ export LD_LIBRARY_PATH=/path/to/mylib.so
$ ./myprogram
[read more]
Addressing only the portion of the question "how to GNU autotools deal with this?"...
When you assign a --prefix to configure, basically two things happen: 1) it instructs the build system that everything is to be installed in ${prefix}, and 2) it looks in ${prefix}/share/config.site for any additional information about how the system is set up (it is common for that file not to exist.) It does absolutely nothing to help find libraries, but depends on the user having set up the tool chain properly. If you want to use a library in /foo/lib, you must have your toolchain set up to look there (eg, by putting /foo/lib in /etc/ld.so.conf, or by putting -L/foo/lib in LDFLAGS and "/foo/lib" in LD_LIBRARY_PATH)
The configure script relies on you to have the environment set up. It does not help you set up that environment, but does help by alerting you that you have not done so.
You could use the readlink system call on /proc/self/exe to get the path of your executable. You might then use realpath etc.