【发布时间】:2013-12-21 05:24:08
【问题描述】:
如何在gdb 中加载多个符号文件。我有一个可执行的 foo.out 并加载了一个模块 bar.so。我创建了两个符号文件 foo.symbol 和 bar.symbol。如何将这两个文件加载到 gdb 中。
# gdb --core core
# (gdb)
# (gdb) symbol-file foo.symbol
如何加载第二个符号文件。或者有什么办法可以加载gdb中目录的所有文件
【问题讨论】:
如何在gdb 中加载多个符号文件。我有一个可执行的 foo.out 并加载了一个模块 bar.so。我创建了两个符号文件 foo.symbol 和 bar.symbol。如何将这两个文件加载到 gdb 中。
# gdb --core core
# (gdb)
# (gdb) symbol-file foo.symbol
如何加载第二个符号文件。或者有什么办法可以加载gdb中目录的所有文件
【问题讨论】:
设置包含符号文件的目录使用
set debug-file-directory <directory>
并使用
show debug-file-directory
显示当前设置为包含符号文件的目录。
如果二进制文件以调试链接的形式提供了符号文件的名称(无路径),则会自动从此目录读取符号文件。
要添加其他符号,您可以使用 add-symbol-file。
(因为gdb onlinedocs 在我在这里引用的那一刻似乎不可用)
添加符号文件文件名地址
add-symbol-file 文件名地址 [ -readnow ] [ -mapped ]
添加-符号-文件文件名-ssection地址...
add-symbol-file 命令从文件文件名中读取附加的符号表信息。当文件名已被动态加载(通过其他方式)到正在运行的程序中时,您将使用此命令。 address 应该是加载文件的内存地址; gdb 无法自己解决这个问题。您还可以指定任意数量的 `-ssection address' 对,为该部分提供明确的部分名称和基地址。您可以将任何地址指定为表达式。
文件filename的符号表被添加到最初用symbol-file命令读取的符号表中。您可以多次使用 add-symbol-file 命令;这样读取的新符号数据不断添加到旧符号数据中。要丢弃所有旧符号数据,请使用不带任何参数的符号文件命令。
虽然文件名通常是共享库文件、可执行文件或其他已完全重定位以加载到进程中的目标文件,但您也可以从可重定位的 .o 文件加载符号信息,只要:
- 文件的符号信息仅指该文件中定义的链接器符号,而不是其他目标文件定义的符号,
- 文件的符号信息所指的每个部分实际上都已加载到下级中,因为它出现在文件中,并且
- 您可以确定每个部分的加载地址,并将这些地址提供给 add-symbol-file 命令。
一些嵌入式操作系统,如 Sun Chorus 和 VxWorks,可以将可重定位文件加载到已经运行的程序中;此类系统通常使上述要求易于满足。但是,重要的是要认识到许多本机系统使用复杂的链接过程(例如,.linkonce 部分分解和 C++ 构造函数表组装),这使得要求难以满足。一般情况下,不能假设使用 add-symbol-file 读取可重定位目标文件的符号信息与将可重定位目标文件以正常方式链接到程序中具有相同的效果。
add-symbol-file 使用后按不重复。
您可以像使用符号文件命令一样使用
-mapped' and-readnow' 选项来更改gdb 管理文件名符号表信息的方式。
【讨论】:
可以将其他符号加载到gdb 调试会话中:
add-symbol-file filename address
参数address 是.text 部分的地址。可以通过以下方式检索此地址:
readelf -WS path/to/file.elf | grep .text | awk '{ print "0x"$5 }'
这可以通过在~/.gdbinit 中添加以下条目在gdb 中实现自动化:
define add-symbol-file-auto
# Parse .text address to temp file
shell echo set \$text_address=$(readelf -WS $arg0 | grep .text | awk '{ print "0x"$5 }') >/tmp/temp_gdb_text_address.txt
# Source .text address
source /tmp/temp_gdb_text_address.txt
# Clean tempfile
shell rm -f /tmp/temp_gdb_text_address.txt
# Load symbol table
add-symbol-file $arg0 $text_address
end
以上函数定义add-symbol-file-auto后可以使用加载附加符号:
(gdb) add-symbol-file-auto path/to/bootloader.elf
add symbol table from file "path/to/bootloader.elf" at
.text_addr = 0x8010400
(gdb) add-symbol-file-auto path/to/application.elf
add symbol table from file "path/to/application.elf" at
.text_addr = 0x8000000
(gdb) break main
Breakpoint 1 at 0x8006cb0: main. (2 locations)
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y <MULTIPLE>
1.1 y 0x08006cb0 in main() at ./source/main.cpp:114
1.2 y 0x080106a6 in main() at ./main.cpp:10
(gdb)
【讨论】:
add-symbol-file-auto 版本:stackoverflow.com/questions/20380204/…
除了alk 的答案和它的cmets 之外,询问的地址是.text 部分的地址。
您可以使用readelf 命令找到它
这里有一个 readelf 用于二进制文件 The address where filename has been loaded is missing [GDB] 的示例
【讨论】:
来自Jaakko's answer 的add-symbol-file-auto 依赖于写入外部文件。如果无法读取或写入文件,这可能会导致问题。这是一个使用GDB command defined in Python 提供相同功能的实现。将此添加到您的.gdbinit:
python
# Note: Replace "readelf" with path to binary if it is not in your PATH.
READELF_BINARY = 'readelf'
class AddSymbolFileAuto (gdb.Command):
"""Load symbols from FILE, assuming FILE has been dynamically loaded (auto-address).
Usage: add-symbol-file-auto FILE [-readnow | -readnever]
The necessary starting address of the file's text is resolved by 'readelf'."""
def __init__(self):
super(AddSymbolFileAuto, self).__init__("add-symbol-file-auto", gdb.COMMAND_FILES)
def invoke(self, solibpath, from_tty):
from os import path
self.dont_repeat()
if os.path.exists(solibpath) == False:
print ("{0}: No such file or directory." .format(solibpath))
return
offset = self.get_text_offset(solibpath)
gdb_cmd = "add-symbol-file %s %s" % (solibpath, offset)
gdb.execute(gdb_cmd, from_tty)
def get_text_offset(self, solibpath):
import subprocess
elfres = subprocess.check_output([READELF_BINARY, "-WS", solibpath])
for line in elfres.splitlines():
if "] .text " in line:
return "0x" + line.split()[4]
return "" # TODO: Raise error when offset is not found?
def complete(self, text, word):
return gdb.COMPLETE_FILENAME
AddSymbolFileAuto()
end
使用示例:
add-symbol-file-auto foo.symbol
请注意,仅使用 add-symbol-file 加载符号可以让您设置断点,但这并不意味着您可以用它做一些有用的事情,例如实际触发断点。使用info sharedlibrary(或info shared)来验证这些符号是否确实与调试目标相关(可选地使用一个模式来显示特定结果而不是全部)。它应该是这样的:
(gdb) gdb-symbol-file-auto path/to/library.symbols
(gdb) info shared symbol-file
From To Syms Read Shared Object Library
0x0000abc0 0x0000def0 Yes path/to/library
不使用加载的符号时显示如下:
From To Syms Read Shared Object Library
0x0000abc0 0x0000def0 Yes (*) path/to/library
(*): Shared library is missing debugging information.
当 GDB 根本无法加载库时显示以下内容(例如if GDB has a bug):
From To Syms Read Shared Object Library
0x0000abc0 0x0000def0 No path/to/library
【讨论】:
add-symbol-file,希望@rob-w 不介意:添加帮助,移至 gdb 文件(它将在下一个显示在 GDB 的帮助中添加符号文件),添加不重复,添加文件存在检查(对于原始文件,请参阅编辑)。注意:而不是添加到 .gdbinit 这也可以通过包含在 anyfile 然后 source anyfile 和/或可以移动到 anyfile.py 与 source anyfile.py - 在这种情况下第一行 python 和最后一行 @987654341 @ 被删除。
我发现使用eu-unstrip 和merge the symbols back to the stripped executables 而不是尝试手动将符号加载到正确的位置更方便,然后在符号已经存在的情况下重现崩溃。
此方法不依赖于与您设置 @987654323 时使用的路径解析机制(debug link 和 build id)所需的命名方案匹配的符号文件@。
【讨论】:
在调试核心文件时,我发现使用add-symbol-file命令时,使用readelf获取的地址(如此处其他答案所述)无法正确加载共享库的符号文件。
我需要使用命令info sharedlibrary/info shared <libname>中显示的“From”地址:
(gdb) info shared libcore
From To Syms Read Shared Object Library
0x0f24caa0 0x0f41c280 Yes (*) /lib/libcore.so
使用此地址并加载符号文件后,我能够正确获取行号。
(gdb) add-symbol-file libcore.so.debug 0x0f24caa0
add symbol table from file "libcore.so.debug" at
.text_addr = 0xf24caa0
(y or n) y
Reading symbols from libcore.so.debug...
我在阅读此页面后找到了这个解决方案:Creating and using debug symbol tables with CMake and GDB
【讨论】:
add-symbol-file filename address
add-symbol-file filename address [ -readnow ] [ -mapped ]
add-symbol-file filename -ssection address ...
【讨论】: