Gdb/Source-Path
Next: Machine Code, Previous: Search, Up: Source [Contents][Index]
9.5 Specifying Source Directories
Executable programs sometimes do not record the directories of the source files from which they were compiled, just the names. Even when they do, the directories could be moved between the compilation and your debugging session. GDB has a list of directories to search for source files; this is called the source path. Each time GDB wants a source file, it tries all the directories in the list, in the order they are present in the list, until it finds a file with the desired name.
For example, suppose an executable references the file
/usr/src/foo-1.0/lib/foo.c
, does not record a compilation
directory, and the source path is /mnt/cross
.
GDB would look for the source file in the following
locations:
/usr/src/foo-1.0/lib/foo.c
/mnt/cross/usr/src/foo-1.0/lib/foo.c
/mnt/cross/foo.c
If the source file is not present at any of the above locations then
an error is printed. GDB does not look up the parts of the
source file name, such as /mnt/cross/src/foo-1.0/lib/foo.c
.
Likewise, the subdirectories of the source path are not searched: if
the source path is /mnt/cross
, and the binary refers to
foo.c
, GDB would not find it under
/mnt/cross/usr/src/foo-1.0/lib
.
Plain file names, relative file names with leading directories, file
names containing dots, etc. are all treated as described above,
except that non-absolute file names are not looked up literally. If
the source path is /mnt/cross
, the source file is
recorded as ../lib/foo.c
, and no compilation directory is
recorded, then GDB will search in the following locations:
/mnt/cross/../lib/foo.c
/mnt/cross/foo.c
The source path will always include two special entries
‘$cdir
’ and ‘$cwd
’, these refer to the compilation directory
(if one is recorded) and the current working directory respectively.
‘$cdir
’ causes GDB to search within the compilation
directory, if one is recorded in the debug information. If no
compilation directory is recorded in the debug information then
‘$cdir
’ is ignored.
‘$cwd
’ is not the same as ‘.
’—the former tracks the
current working directory as it changes during your GDB
session, while the latter is immediately expanded to the current
directory at the time you add an entry to the source path.
If a compilation directory is recorded in the debug information, and GDB has not found the source file after the first search using source path, then GDB will combine the compilation directory and the filename, and then search for the source file again using the source path.
For example, if the executable records the source file as
/usr/src/foo-1.0/lib/foo.c
, the compilation directory is
recorded as /project/build
, and the source path is
/mnt/cross:$cdir:$cwd
while the current working directory of
the GDB session is /home/user
, then GDB will
search for the source file in the following locations:
/usr/src/foo-1.0/lib/foo.c
/mnt/cross/usr/src/foo-1.0/lib/foo.c
/project/build/usr/src/foo-1.0/lib/foo.c
/home/user/usr/src/foo-1.0/lib/foo.c
/mnt/cross/project/build/usr/src/foo-1.0/lib/foo.c
/project/build/project/build/usr/src/foo-1.0/lib/foo.c
/home/user/project/build/usr/src/foo-1.0/lib/foo.c
/mnt/cross/foo.c
/project/build/foo.c
/home/user/foo.c
If the file name in the previous example had been recorded in the executable as a relative path rather than an absolute path, then the first look up would not have occurred, but all of the remaining steps would be similar.
When searching for source files on MS-DOS and MS-Windows, where
absolute paths start with a drive letter (e.g.
C:/project/foo.c
), GDB will remove the drive letter
from the file name before appending it to a search directory from
source path; for instance if the executable references the
source file C:/project/foo.c
and source path is set to
D:/mnt/cross
, then GDB will search in the following
locations for the source file:
C:/project/foo.c
D:/mnt/cross/project/foo.c
D:/mnt/cross/foo.c
Note that the executable search path is not used to locate the source files.
Whenever you reset or rearrange the source path, GDB clears out any information it has cached about where source files are found and where each line is in the file.
When you start GDB, its source path includes only ‘$cdir
’
and ‘$cwd
’, in that order.
To add other directories, use the directory
command.
The search path is used to find both program source files and GDB
script files (read using the ‘-command
’ option and ‘source
’ command).
In addition to the source path, GDB provides a set of commands
that manage a list of source path substitution rules. A substitution
rule specifies how to rewrite source directories stored in the program’s
debug information in case the sources were moved to a different
directory between compilation and debugging. A rule is made of
two strings, the first specifying what needs to be rewritten in
the path, and the second specifying how it should be rewritten.
In set substitute-path, we name these two parts from
and
to
respectively. GDB does a simple string replacement
of from
with to
at the start of the directory part of the
source file name, and uses that result instead of the original file
name to look up the sources.
Using the previous example, suppose the foo-1.0
tree has been
moved from /usr/src
to /mnt/cross
, then you can tell
GDB to replace /usr/src
in all source path names with
/mnt/cross
. The first lookup will then be
/mnt/cross/foo-1.0/lib/foo.c
in place of the original location
of /usr/src/foo-1.0/lib/foo.c
. To define a source path
substitution rule, use the set substitute-path
command
(see set substitute-path).
To avoid unexpected substitution results, a rule is applied only if the
from
part of the directory name ends at a directory separator.
For instance, a rule substituting /usr/source
into
/mnt/cross
will be applied to /usr/source/foo-1.0
but
not to /usr/sourceware/foo-2.0
. And because the substitution
is applied only at the beginning of the directory name, this rule will
not be applied to /root/usr/source/baz.c
either.
In many cases, you can achieve the same result using the directory
command. However, set substitute-path
can be more efficient in
the case where the sources are organized in a complex tree with multiple
subdirectories. With the directory
command, you need to add each
subdirectory of your project. If you moved the entire tree while
preserving its internal organization, then set substitute-path
allows you to direct the debugger to all the sources with one single
command.
set substitute-path
is also more than just a shortcut command.
The source path is only used if the file at the original location no
longer exists. On the other hand, set substitute-path
modifies
the debugger behavior to look at the rewritten location instead. So, if
for any reason a source file that is not relevant to your executable is
located at the original location, a substitution rule is the only
method available to point GDB at the new location.
You can configure a default source path substitution rule by
configuring GDB with the
‘--with-relocated-sources=dir
’ option. The dir
should be the name of a directory under GDB’s configured
prefix (set with ‘--prefix
’ or ‘--exec-prefix
’), and
directory names in debug information under dir
will be adjusted
automatically if the installed GDB is moved to a new
location. This is useful if GDB, libraries or executables
with debug information and corresponding source code are being moved
together.
directory dirname …
dir dirname …
Add directory
dirname
to the front of the source path. Several directory names may be given to this command, separated by ‘:
’ (‘;
’ on MS-DOS and MS-Windows, where ‘:
’ usually appears as part of absolute file names) or whitespace. You may specify a directory that is already in the source path; this moves it forward, so GDB searches it sooner.The special strings ‘
$cdir
’ (to refer to the compilation directory, if one is recorded), and ‘$cwd
’ (to refer to the current working directory) can also be included in the list of directoriesdirname
. Though these will already be in the source path they will be moved forward in the list so GDB searches them sooner.directory
Reset the source path to its default value (‘
$cdir:$cwd
’ on Unix systems). This requires confirmation.set directories path-list
Set the source path to
path-list
. ‘$cdir:$cwd
’ are added if missing.show directories
Print the source path: show which directories it contains.
set substitute-path from to
Define a source path substitution rule, and add it at the end of the current list of existing substitution rules. If a rule with the same
from
was already defined, then the old rule is also deleted.For example, if the file
/foo/bar/baz.c
was moved to/mnt/cross/baz.c
, then the command(gdb) set substitute-path /foo/bar /mnt/cross
will tell GDB to replace ‘
/foo/bar
’ with ‘/mnt/cross
’, which will allow GDB to find the filebaz.c
even though it was moved.In the case when more than one substitution rule have been defined, the rules are evaluated one by one in the order where they have been defined. The first one matching, if any, is selected to perform the substitution.
For instance, if we had entered the following commands:
(gdb) set substitute-path /usr/src/include /mnt/include (gdb) set substitute-path /usr/src /mnt/src
GDB would then rewrite
/usr/src/include/defs.h
into/mnt/include/defs.h
by using the first rule. However, it would use the second rule to rewrite/usr/src/lib/foo.c
into/mnt/src/lib/foo.c
.unset substitute-path [path]
If a path is specified, search the current list of substitution rules for a rule that would rewrite that path. Delete that rule if found. A warning is emitted by the debugger if no rule could be found.
If no path is specified, then all substitution rules are deleted.
show substitute-path [path]
If a path is specified, then print the source path substitution rule which would rewrite that path, if any.
If no path is specified, then print all existing source path substitution rules.
If your source path is cluttered with directories that are no longer of interest, GDB may sometimes cause confusion by finding the wrong versions of source. You can correct the situation as follows:
- Use
directory
with no argument to reset the source path to its default value. - Use
directory
with suitable arguments to reinstall the directories you want in the source path. You can add all the directories in one command.
Next: Machine Code, Previous: Search, Up: Source [Contents][Index]