如何在gdb
中加载多个符号文件。我有一个可执行文件foo.out并加载模块bar.so.我创建了两个符号文件foo.symbol和bar.symbol。如何将这两个文件加载到gdb中。
# gdb --core core
# (gdb)
# (gdb) symbol-file foo.symbol
如何加载第二个符号文件。或者有没有办法在gdb
答案 0 :(得分:16)
要设置包含符号文件的目录,请使用
set debug-file-directory <directory>
并使用
show debug-file-directory
显示当前设置为包含符号文件的目录。
如果符号文件的名称(没有路径)由二进制文件根据调试链接提供,则从该目录自动读取符号文件。
要添加附加符号,您可以使用add-symbol-file
。
(因为gdb onlinedocs似乎暂时不可用,我在这里引用它)
add-symbol-file filename address
add-symbol-file filename address [-readnow] [-mapped]
add-symbol-file filename -ssection address ...
add-symbol-file命令从文件filename中读取其他符号表信息。当文件名已经(通过其他方式)动态加载到正在运行的程序中时,您将使用此命令。 address应该是加载文件的内存地址; gdb无法解决这个问题。您还可以指定任意数量的`-ssection地址'对,为该部分提供明确的部分名称和基址。您可以将任何地址指定为表达式。
文件filename的符号表被添加到最初使用symbol-file命令读取的符号表中。您可以多次使用add-symbol-file命令;这样读取的新符号数据不断增加旧的符号数据。要丢弃所有旧的符号数据,请使用不带任何参数的symbol-file命令。
尽管filename通常是一个共享库文件,一个可执行文件或一个已完全重定位以加载到进程中的其他目标文件,但您也可以从可重定位的.o文件中加载符号信息,只要:
- 文件的符号信息仅指该文件中定义的链接符号,而不是其他目标文件定义的符号,
- 文件的符号信息所引用的每个部分实际上已经加载到下级,因为它出现在文件中,并且
- 您可以确定加载每个部分的地址,并将这些部分提供给add-symbol-file命令。
某些嵌入式操作系统,如Sun Chorus和VxWorks,可以将可重定位文件加载到已经运行的程序中;这样的系统通常使上述要求容易满足。但是,重要的是要认识到许多本机系统使用复杂的链接过程(例如,.linkonce section factoring和C ++构造函数表程序集),这使得需求难以满足。通常,不能假设使用add-symbol-file读取可重定位目标文件的符号信息将具有与以正常方式将可重定位目标文件链接到程序中相同的效果。
如果在使用后按下,则不会重复添加符号文件。
您可以像使用symbol-file命令一样使用
-mapped' and
- readnow'选项来更改gdb管理文件名的符号表信息的方式。
答案 1 :(得分:10)
除了答案及其评论之外,所询问的地址是.text
部分的地址。
您可以使用readelf
命令
这里有一个readelf
用于二进制文件The address where filename has been loaded is missing [GDB]
答案 2 :(得分:3)
// Afaik comparing the int is cheaper then getting Input
// You should do the cheaper checks first
if (Ammo.Ammocount <= Ammo.Maxammo && Ammo.Ammocount > 0 && Input.GetButtonDown("Fire1"))
{
muzzleflash.Play();
Shoot();
gunshot.Play(0);
}
依赖于写入外部文件。如果无法读取或写入文件,则可能导致问题。这是使用GDB command defined in Python提供相同功能的实现。将此添加到您的add-symbol-file-auto
:
.gdbinit
用法示例:
python
class AddSymbolFileAuto (gdb.Command):
def __init__(self):
super(AddSymbolFileAuto, self).__init__("add-symbol-file-auto", gdb.COMMAND_USER)
def invoke(self, solibpath, from_tty):
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
# Note: Replace "readelf" with path to binary if it is not in your PATH.
elfres = subprocess.check_output(["readelf", "-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?
AddSymbolFileAuto()
end
请注意,仅使用add-symbol-file
加载符号可以允许您设置断点,但这并不意味着您可以自动执行一些有用的操作,例如实际触发断点。使用info sharedlibrary
(或add-symbol-file-auto foo.symbol
)来验证符号是否确实与调试目标相关(可以选择显示特定结果而不显示全部结果的模式)。它应该看起来像这样:
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
当GDB根本无法加载该库(例如if GDB has a bug)时,将显示以下内容:
From To Syms Read Shared Object Library
0x0000abc0 0x0000def0 Yes (*) path/to/library
(*): Shared library is missing debugging information.
答案 3 :(得分:2)
其他符号可以通过以下方式加载到gdb
调试会话中:
add-symbol-file filename address
参数address
是.text
部分的地址。可以使用以下方式检索此地址:
readelf -WS path/to/file.elf | grep .text | awk '{ print "0x"$5 }'
可以通过在gdb
中添加以下条目来自动在~/.gdbinit
中进行操作:
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/1.elf
add symbol table from file "path/to/1.elf" at
.text_addr = 0x8010400
(gdb) add-symbol-file-auto path/to/2.elf
add symbol table from file "path/to/2.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)
答案 4 :(得分:1)
我没有尝试手动将符号加载到正确的位置,而是merge the symbols back to the stripped executables使用eu-unstrip
更方便,然后使用已存在的符号重现崩溃。
此方法不依赖于符合路径解析机制(调试链接和构建ID )所需的命名方案的符号文件,这些符号文件在设置{{{ 1}}。
答案 5 :(得分:0)
add-symbol-file filename address
add-symbol-file filename address [ -readnow ] [ -mapped ]
add-symbol-file filename -ssection address ...