1. <legend id='WbR4v'><style id='WbR4v'><dir id='WbR4v'><q id='WbR4v'></q></dir></style></legend>
        <tfoot id='WbR4v'></tfoot>

        <small id='WbR4v'></small><noframes id='WbR4v'>

        • <bdo id='WbR4v'></bdo><ul id='WbR4v'></ul>
        <i id='WbR4v'><tr id='WbR4v'><dt id='WbR4v'><q id='WbR4v'><span id='WbR4v'><b id='WbR4v'><form id='WbR4v'><ins id='WbR4v'></ins><ul id='WbR4v'></ul><sub id='WbR4v'></sub></form><legend id='WbR4v'></legend><bdo id='WbR4v'><pre id='WbR4v'><center id='WbR4v'></center></pre></bdo></b><th id='WbR4v'></th></span></q></dt></tr></i><div id='WbR4v'><tfoot id='WbR4v'></tfoot><dl id='WbR4v'><fieldset id='WbR4v'></fieldset></dl></div>

        gdb-python :解析结构的每个字段并以适当的值打印它们(如果存在)

        时间:2023-08-29
      2. <small id='ocJyj'></small><noframes id='ocJyj'>

            <bdo id='ocJyj'></bdo><ul id='ocJyj'></ul>

                <tbody id='ocJyj'></tbody>
                <legend id='ocJyj'><style id='ocJyj'><dir id='ocJyj'><q id='ocJyj'></q></dir></style></legend>

                <i id='ocJyj'><tr id='ocJyj'><dt id='ocJyj'><q id='ocJyj'><span id='ocJyj'><b id='ocJyj'><form id='ocJyj'><ins id='ocJyj'></ins><ul id='ocJyj'></ul><sub id='ocJyj'></sub></form><legend id='ocJyj'></legend><bdo id='ocJyj'><pre id='ocJyj'><center id='ocJyj'></center></pre></bdo></b><th id='ocJyj'></th></span></q></dt></tr></i><div id='ocJyj'><tfoot id='ocJyj'></tfoot><dl id='ocJyj'><fieldset id='ocJyj'></fieldset></dl></div>
              • <tfoot id='ocJyj'></tfoot>
                • 本文介绍了gdb-python :解析结构的每个字段并以适当的值打印它们(如果存在)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在编写一个 python 脚本来自动从 gdb 调试核心转储.我正在尝试打印包含内核数据结构和列表的数据结构(例如 struct list_head).例如结构是这样的:

                  I am writing a python script to automate debugging core dump from gdb. i am trying to print data structure which includes kernel data structures and lists(e.g. struct list_head). For example the structure is something like this:

                  struct my_struct {
                    struct my_hardware_context ahw;
                    struct net_device *netdev;
                    struct pci_dev *pdev;
                    struct list_head mac_list;
                    ....
                    ....
                  };
                  

                  我正在使用以下 API tp 打印此结构:

                  i am using following API tp print this structure:

                  gdb.execute('p (*(struct my_struct *)dev_base->priv)')

                  gdb.execute('p (*(struct my_struct *)dev_base->priv)')

                  所以我可以自动打印 'struct my_struct' 、 struct my_hardware_context ahw 的内容,但不能打印指针和列表的内容(例如 struct net_device *netdev、struct pci_dev *pdev、struct list_head mac_list)(只有地址是打印).那么如何使用gdb-python脚本打印*netdev、*pdev和mac_list的内容呢?

                  so i am able to print the content of 'struct my_struct' , struct my_hardware_context ahw, but not the content of pointers and list ( e.g. struct net_device *netdev, struct pci_dev *pdev, struct list_head mac_list) automatically (only address is printed). So how to print the content of *netdev, *pdev and mac_list using gdb-python script?

                  已让我的问题更清楚

                  我正在编写一个 python 脚本来自动从 gdb 调试核心转储.我正在尝试打印包含内核数据结构和列表的数据结构(例如 struct list_head).例如结构是这样的:

                  I am writing a python script to automate debugging core dump from gdb. i am trying to print data structure which includes kernel data structures and lists(e.g. struct list_head). For example the structure is something like this:

                  struct my_struct {
                     struct my_hardware_context ahw;
                     struct net_device *netdev;
                     struct pci_dev *pdev;
                     struct list_head mac_list;
                     ....
                     ....
                  };
                  

                  我正在使用以下 API 来打印此结构:(可以假设我有正确的核心转储并添加了正确的符号.

                  i am using following API to print this structure: (it can be assumed that i have right core dump and added proper symbols.

                  main_struct = gdb.execute('p (*(struct my_struct *)dev_base->priv)')

                  打印 main_struct

                  现在它将打印 struct my_struct 的所有成员的值,但最多打印一级,这意味着它将打印 struct my_hardware_context ahw 的全部内容,因为它是一个实例,但它不会打印 struct net_device *netdev, struct 的内容pci_dev *pdev, struct list_head mac_list 等,所以现在我需要手动执行如下操作:

                  Now it will print the values of all members of struct my_struct but upto one level , meaning it will print the whole content of struct my_hardware_context ahw because it is an instance but it will not print the content of struct net_device *netdev, struct pci_dev *pdev, struct list_head mac_list etc. so now manually i need to do it like below:

                  netdev = gdb.parse_and_eval('*(*(struct my_struct *)dev_base->next->priv).netdev')

                  打印网络开发

                  pdev = gdb.parse_and_eval('*(*(struct my_struct *)dev_base->next->priv).pdev')

                  打印 pdev

                  所以我想自动化这些步骤.是否有任何 gdb-python API 或方法可以迭代 struct my_struct 并自动打印指针、数组和列表值?

                  so i want to automate these steps. Is there any gdb-python API or way by which it can iterate the struct my_struct and print the pointers, arrays and lists values also automatically?

                  谢谢.

                  推荐答案

                  struct net_device, struct pci_dev 来自 Linux 的目的是供内核使用,而不是用户空间代码.它们甚至没有导出到您使用 make headers_install 获得的清理过的内核头文件中,以便与 libc 一起使用.

                  struct net_device, struct pci_dev from Linux are meant to be used by kernel and not userspace code. They're not even exported in the sanitized kernel headers you get with make headers_install for use with libc.

                  GDB 不能打印 struct net_device, struct pci_dev 因为它没有描述这些结构定义的调试信息.您的用户空间 struct my_struct 被声明为具有指向这些结构的不透明指针.我认为你一开始就不应该这样做.

                  GDB can't print struct net_device, struct pci_dev because it doesn't have debug info describing the definition of those structures. Your userspace struct my_struct is declared to have opaque pointers to those structures. I don't think you should be doing that in the first place.

                  诀窍是将调试信息从内核和驱动程序模块加载到 GDB:

                  The trick is loading debug info from both the kernel and your driver module into GDB:

                  • 使用调试信息 (CONFIG_DEBUG_INFO) 获取内核.例如对于 Centos,从 http://debuginfo 获取匹配的 kernel-debuginfo 包.centos.org/6/x86_64/.
                  • 通过检查 /sys/module/获取驱动程序模块的 .text.data.bss 加载地址MY-DRIVER/sections/{.text,.data,.bss} 来自在正常运行下运行驱动程序的系统.
                  • Grab a kernel with debuginfo (CONFIG_DEBUG_INFO). e.g. for Centos, get the matching kernel-debuginfo package from http://debuginfo.centos.org/6/x86_64/.
                  • Get the .text, .data and .bss load addresses of your driver module by inspecting /sys/module/MY-DRIVER/sections/{.text,.data,.bss} from a system running your driver under normal operation.

                  假设带有调试信息的内核位于 /usr/lib/debug/lib/modules/3.9.4-200.fc18.x86_64/vmlinux,运行:

                  Assuming the kernel with debug info is located at /usr/lib/debug/lib/modules/3.9.4-200.fc18.x86_64/vmlinux, run:

                  $ gdb /usr/lib/debug/lib/modules/3.9.4-200.fc18.x86_64/vmlinux vmcore
                  (gdb) add-symbol-file MY-DRIVER.ko TEXT-ADDR -s .data DATA-ADDR -s .bss BSS-ADDR
                  

                  同时将 TEXT-ADDRDATA-ADDRBSS-ADDR 替换为/sys/module/下文件中的地址我的司机/sections/.(我认为在这种情况下,只是撒谎并使用地址 0 可能会起作用)

                  while replacing TEXT-ADDR, DATA-ADDR and BSS-ADDR with the address from the files under /sys/module/MY-DRIVER/sections/. (I think just lying and using an address of 0 would probably work in this case)

                  验证 ptype struct net_deviceptype struct pci_devptype my_struct 是否有效.然后在获得 struct *my_struct 的地址之后,您应该能够打印其内容.

                  Verify that ptype struct net_device, ptype struct pci_dev, ptype my_struct work. Then after obtaining the address of a struct *my_struct the way you did before you should be able print its contents.

                  print-struct-follow-pointers.py

                  import gdb
                  
                  def is_container(v):
                      c = v.type.code
                      return (c == gdb.TYPE_CODE_STRUCT or c == gdb.TYPE_CODE_UNION)
                  
                  def is_pointer(v):
                      return (v.type.code == gdb.TYPE_CODE_PTR)
                  
                  def print_struct_follow_pointers(s, level_limit = 3, level = 0):
                      indent = ' ' * level
                  
                      if not is_container(s):
                          gdb.write('%s
                  ' % (s,))
                          return
                  
                      if level >= level_limit:
                          gdb.write('%s { ... },
                  ' % (s.type,))
                          return
                  
                      gdb.write('%s {
                  ' % (s.type,))
                      for k in s.type.keys():
                          v = s[k]
                          if is_pointer(v):
                              gdb.write('%s %s: %s' % (indent, k, v))
                              try:
                                  v1 = v.dereference()
                                  v1.fetch_lazy()
                              except gdb.error:
                                  gdb.write(',
                  ')
                                  continue
                              else:
                                  gdb.write(' -> ')
                              print_struct_follow_pointers(v1, level_limit, level + 1)
                          elif is_container(v):
                              gdb.write('%s %s: ' % (indent, k))
                              print_struct_follow_pointers(v, level_limit, level + 1)
                          else:
                              gdb.write('%s %s: %s,
                  ' % (indent, k, v))
                      gdb.write('%s},
                  ' % (indent,))
                  
                  class PrintStructFollowPointers(gdb.Command):
                      '''
                      print-struct-follow-pointers [/LEVEL_LIMIT] STRUCT-VALUE
                      '''
                      def __init__(self): 
                          super(PrintStructFollowPointers, self).__init__(
                              'print-struct-follow-pointers',
                              gdb.COMMAND_DATA, gdb.COMPLETE_SYMBOL, False)
                  
                      def invoke(self, arg, from_tty):
                          s = arg.find('/')
                          if s == -1:
                              (expr, limit) = (arg, 3)
                          else:
                              if arg[:s].strip():
                                  (expr, limit) = (arg, 3)
                              else:
                                  i = s + 1
                                  for (i, c) in enumerate(arg[s+1:], s + 1):
                                      if not c.isdigit():
                                          break
                                  end = i
                                  digits = arg[s+1:end]
                                  try:
                                      limit = int(digits)
                                  except ValueError:
                                      raise gdb.GdbError(PrintStructFollowPointers.__doc__)
                                  (expr, limit) = (arg[end:], limit)
                          try:
                              v = gdb.parse_and_eval(expr)
                          except gdb.error, e:
                              raise gdb.GdbError(e.message)
                  
                          print_struct_follow_pointers(v, limit)
                  
                  PrintStructFollowPointers()
                  

                  示例会话

                  (gdb) source print-struct-follow-pointers.py
                  (gdb) print-struct-follow-pointers *p
                  

                  您可以限制打印的嵌入结构的级别:

                  You can limit the levels of embedded structures printed:

                  (gdb) print-struct-follow-pointers/4 *p
                  

                  这篇关于gdb-python :解析结构的每个字段并以适当的值打印它们(如果存在)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:如何为 Windows 获取预构建的 *debug* 版本的 Python 库(例如 Python27_d.dll) 下一篇:如何在 Spyder 中更改 Python 的路径?

                  相关文章

                      <bdo id='eAmzr'></bdo><ul id='eAmzr'></ul>
                  1. <i id='eAmzr'><tr id='eAmzr'><dt id='eAmzr'><q id='eAmzr'><span id='eAmzr'><b id='eAmzr'><form id='eAmzr'><ins id='eAmzr'></ins><ul id='eAmzr'></ul><sub id='eAmzr'></sub></form><legend id='eAmzr'></legend><bdo id='eAmzr'><pre id='eAmzr'><center id='eAmzr'></center></pre></bdo></b><th id='eAmzr'></th></span></q></dt></tr></i><div id='eAmzr'><tfoot id='eAmzr'></tfoot><dl id='eAmzr'><fieldset id='eAmzr'></fieldset></dl></div>

                    <small id='eAmzr'></small><noframes id='eAmzr'>

                    <legend id='eAmzr'><style id='eAmzr'><dir id='eAmzr'><q id='eAmzr'></q></dir></style></legend>

                    <tfoot id='eAmzr'></tfoot>