【问题标题】:How to load multiple symbol files in gdb如何在 gdb 中加载多个符号文件
【发布时间】: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中目录的所有文件

【问题讨论】:

    标签: c debugging gdb


    【解决方案1】:

    设置包含符号文件的目录使用

    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 管理文件名符号表信息的方式。

    【讨论】:

    • 我试过了,但它没有从所述目录加载符号文件
    • 您是否动态加载 bar.so?它是否包含调试链接?
    • 是 bar.so 是动态链接,不包含符号。我有 bar.symbol 的符号文件
    • gdb 无法计算出这个地址,我怎么知道这个地址?
    • 在我的例子中,gdb 不是在设置为 debug-file-directory 本身的目录中搜索,而是在一个子目录中搜索,这是原始文件 (bar.so) 的绝对路径。
    【解决方案2】:

    可以将其他符号加载到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)
    

    【讨论】:

    【解决方案3】:

    除了alk 的答案和它的cmets 之外,询问的地址是.text 部分的地址。 您可以使用readelf 命令找到它

    这里有一个 readelf 用于二进制文件 The address where filename has been loaded is missing [GDB] 的示例

    【讨论】:

      【解决方案4】:

      来自Jaakko's answeradd-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
      

      【讨论】:

      • +1,很高兴在这里有这个。我也不喜欢临时文件。我记得看过 Python,但我认为在特定 gdb 版本中使用 python 存在一些限制。
      • 我发现这个脚本非常有用,并对其进行了一些调整以匹配add-symbol-file,希望@rob-w 不介意:添加帮助,移至 gdb 文件(它将在下一个显示在 GDB 的帮助中添加符号文件),添加不重复,添加文件存在检查(对于原始文件,请参阅编辑)。注意:而不是添加到 .gdbinit 这也可以通过包含在 anyfile 然后 source anyfile 和/或可以移动到 anyfile.py 与 source anyfile.py - 在这种情况下第一行 python 和最后一行 @987654341 @ 被删除。
      【解决方案5】:

      我发现使用eu-unstripmerge the symbols back to the stripped executables 而不是尝试手动将符号加载到正确的位置更方便,然后在符号已经存在的情况下重现崩溃。

      此方法不依赖于与您设置 @987654323 时使用的路径解析机制(debug linkbuild id)所需的命名方案匹配的符号文件@。

      【讨论】:

        【解决方案6】:

        在调试核心文件时,我发现使用add-symbol-file命令时,使用readelf获取的地址(如此处其他答案所述)无法正确加载共享库的符号文件。

        我需要使用命令info sharedlibrary/info shared &lt;libname&gt;中显示的“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

        【讨论】:

          【解决方案7】:
          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

          【讨论】:

            猜你喜欢
            • 2023-03-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-08-09
            • 1970-01-01
            • 1970-01-01
            • 2019-12-22
            • 2014-10-26
            相关资源
            最近更新 更多