注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

请移步gmd20.github.com

// 编程和生活。不再使用,网易博客功能异常他们都没人维护了

 
 
 

日志

 
 

GDB指定和修改搜素源码文件的路径(set substitute-path)  

2013-04-24 13:26:51|  分类: 程序设计 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
今天用gdb查看core文件,发现找不到源文件。记录一下相关命令

在gdb里面查看源码,
list 一下提醒找不到相关文件,列出来的是绝对路径的完整文件名。
help files   看一下帮助,可以加载符号,源文件等,自己看一下。
dir 设置源码路径无效,show directories  看到设置成功,但是还是找不到文件。

应该是绝对路径的问题。
因为igcc 根据你编译的时候指定的是绝对路径还是  ../../XXX.cpp之类的相对路径,在生成debug_info的时候,也把这个路径保存为debug_info 里面的文件名字,就是最后 gdb list 里面找到的文件名字。
这个可以list  查看是不是绝对路径,然后可以用命令
 readelf -p .debug_str  exe_or_so_file 
看到里面保存是是完整的绝对路径。
gdb 的dir 命令添加的源码搜索路径只对相对路径的情况有效。

一个解决办法就是在gcc的时候,使用相对路径那么gdb里面你就可以使用 dir来设置了。像些CMake之类的,它喜欢使用绝对路径,有人可以写个脚本让它使用相对路径,参考 http://stackoverflow.com/questions/9607155/make-gcc-put-relative-filenames-in-debug-information

如果gcc里面-g  生成的debug_info 使用的绝对路径了,最简单的办法就是你把源码也放到相应的位置上去了。
但如果你不想使用这个绝对路径,那也还是有办法的。 
GDB还提供另外一个选择,可以让你修改源码搜索路径,把源码绝对路径里面的一个path映射到另一个path上去,这样即使你debug info了里面的是绝对路径,源码也可以放到另外的目录。
这就是命令
set substitute-path from_path  to_path
比如 list显示的源码是   /home/aaa/1.cpp
那么设置了 set substitute-path /home/aaa/   /home/bbb/
之后,即使你的源文件1.cpp 放在 /home/bbb下面也是可以找到的了。因为gdb帮你做了字符串替换。


相关的参考来自 

http://sourceware.org/gdb/onlinedocs/gdb/Source-Path.html


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 gdbwants 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, and our source path is /mnt/cross. The file is first looked up literally; if this fails, /mnt/cross/usr/src/foo-1.0/lib/foo.c is tried; if this fails,/mnt/cross/foo.c is opened; if this fails, an error message 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.cgdb 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; for instance, if the source path is /mnt/cross, and the source file is recorded as../lib/foo.cgdb would first try ../lib/foo.c, then /mnt/cross/../lib/foo.c, and after that—/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 tellgdb 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 thedirectory 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 gdbis 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.

You can use the string ‘$cdir’ to refer to the compilation directory (if one is recorded), and ‘$cwd’ to refer to the current working directory. ‘$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. 

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 /usr/src /mnt/cross

will tell gdb to replace ‘/usr/src’ with ‘/mnt/cross’, which will allow gdb to find the file baz.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:

  1. Use directory with no argument to reset the source path to its default value.
  2. Use directory with suitable arguments to reinstall the directories you want in the source path. You can add all the directories in one command.
  评论这张
 
阅读(4417)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018