繁体   English   中英

如何在GDB中定义offsetof()宏

[英]How to define offsetof() macro in GDB

为了方便起见,我想在GDB中定义一些辅助marcos,其中一个是offsetof()宏。

我试过了

define offsetof
    if $argc == 2
        (int)(&((($arg0 *)0)->$arg1))
    end
end

它不起作用,因为:

  1. 诸如struct node类的类型将被拆分为Structnode ,因此$arg0 = Struct$arg1 = node
  2. 我不确定gdb的命令是否可以返回值。

任何人都可以帮我一把吗?

我认为最好将offsetof定义为函数,而不是将offsetof定义为命令。 这样你就可以在表达式中使用它; 如果你只是想看到偏移,你总是可以使用print

有两种方法可以将offsetof定义为函数。

如果您正在调试C或C ++,您只需将其定义为宏:

(gdb) macro define offsetof(t, f) &((t *) 0)->f

所以给出:

struct x {
  int a;
  long b;
};

在我的机器上,我得到:

(gdb) p offsetof(struct x, a)
$1 = (int *) 0x0
(gdb) p offsetof(struct x, b)
$2 = (long *) 0x8

上面“C或C ++”限制的原因是其他语言不通过gdb的内置预处理器运行它们的表达式。

如果你想让它在其他语言中工作,那么答案是在Python中编写一个新的便利函数。 这涉及更多,但请参阅gdb文档中的gdb.Function

如果你使用python来定义offsetof ,你可以从这样的东西开始:

import gdb

class offsetof(gdb.Command):

    def invoke(self, args, from_tty):
        value, name = args.split()
        struct = gdb.parse_and_eval(value)
        fields = { field.name: field for field in struct.type.fields() }   
        gdb.write("{} offset: {} bits\n".format(name, fields[name].bitpos))

offsetof("offsetof", gdb.COMMAND_USER)

如果将其保存到文件中,并确保保存它的目录位于sys.path ,则可以将其导入。 例如,如果将其保存到主目录,则可以执行以下操作:

(gdb) pi
>>> import os
>>> sys.path.insert(0, os.getenv('HOME'))
>>> import offsetof
>>>
(gdb)

如果您的gdb没有pi命令,则可以在>>>提示符后面向每个命令添加python

如果gdb导入offsetof而没有任何抱怨,那么您应该能够将offsetof作为gdb命令调用。 如上所述,它需要两个参数(空格分隔),一个值和一个名称。 如果值是具有提供名称的字段的结构,则它将以位为单位报告偏移量(不是字节,因为底层python代码可以处理位域)。

这里的代码可以改进。 除了它从它调用的代码继承的内容之外,它没有真正的错误处理,并且如果编写它不处理指针。

该页面描述了该示例中使用的一些底层代码; 它提到的target方法可能提供处理指针的开始(或者你可以在你传入的值中取消引用指针,即你可以指定*this而不是this作为第一个参数)。 Type.fields()提到除了bitpos之外的其他属性,如果您想报告有关struct layout的其他详细信息,那么这些属性也可能会很有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM