如何在gdb中加载多个符号文件

Ibr*_*med 28 c debugging gdb

如何加载多个符号文件gdb.我有一个可执行文件foo.out并加载模块bar.so. 我创建了两个符号文件foo.symbol和bar.symbol.如何将这两个文件加载到gdb中.

# gdb --core core
# (gdb) 
# (gdb) symbol-file foo.symbol
Run Code Online (Sandbox Code Playgroud)

如何加载第二个符号文件.或者有没有办法加载目录中的所有文件gdb

alk*_*alk 18

设置包含符号文件的目录

set debug-file-directory <directory>
Run Code Online (Sandbox Code Playgroud)

并使用

show debug-file-directory
Run Code Online (Sandbox Code Playgroud)

显示当前设置为包含符号文件的目录.

如果符号文件的名称(无路径)由二进制文件根据调试链接提供,则从该目录自动读取符号文件.


要添加您可能使用的附加符号add-symbol-file.

(因为gdb onlinedocs目前似乎不可用,我在这里引用它)

add-symbol-file文件名地址

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来读取可重定位目标文件的符号信息将具有与以正常方式将可重定位目标文件链接到程序中相同的效果.

如果在使用后按下,则不会重复添加符号文件.

您可以-mapped' and像使用symbol-file命令一样使用-readnow'选项来更改gdb管理filename的符号表信息的方式.

  • gdb无法弄清楚这个地址,我怎么知道地址? (6认同)

Oli*_*ier 10

除了alk的答案及其评论之外,所要求的地址是该.text部分的地址.您可以使用该readelf命令找到它

这里有一个readelf用于二进制文件的示例缺少文件名的地址[GDB]


Jaa*_*kko 9

可以使用以下命令将其他符号加载到gdb调试会话:

add-symbol-file filename address
Run Code Online (Sandbox Code Playgroud)

参数address是段的地址.text。可以使用以下方式检索此地址:

readelf -WS path/to/file.elf | grep .text | awk '{ print "0x"$5 }'
Run Code Online (Sandbox Code Playgroud)

可以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
Run Code Online (Sandbox Code Playgroud)

在上面的函数定义之后,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)
Run Code Online (Sandbox Code Playgroud)


Rob*_*b W 5

add-symbol-file-auto来自Jaakko 的回答依赖于写入外部文件。如果无法读取或写入文件,这可能会导致问题。这是一个使用Python 中定义GDB 命令提供相同功能的实现。将此添加到您的.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
Run Code Online (Sandbox Code Playgroud)

用法示例:

add-symbol-file-auto foo.symbol
Run Code Online (Sandbox Code Playgroud)

请注意,仅加载符号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
Run Code Online (Sandbox Code Playgroud)

未使用加载的符号时显示以下内容:

From        To          Syms Read   Shared Object Library
0x0000abc0  0x0000def0  Yes (*)     path/to/library
(*): Shared library is missing debugging information.
Run Code Online (Sandbox Code Playgroud)

当 GDB 根本无法加载库时(例如,如果 GDB 有错误),将显示以下内容:

From        To          Syms Read   Shared Object Library
0x0000abc0  0x0000def0  No          path/to/library
Run Code Online (Sandbox Code Playgroud)