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

时间:2013-12-04 16:07:18

标签: c debugging gdb

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

# gdb --core core
# (gdb) 
# (gdb) symbol-file foo.symbol

如何加载第二个符号文件。或者有没有办法在gdb

中加载目录的所有文件

6 个答案:

答案 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)

Jaakko's answer中的

// 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 ...

请参阅http://www.delorie.com/gnu/docs/gdb/gdb_125.html