[英]How to define offsetof() macro in GDB
為了方便起見,我想在GDB中定義一些輔助marcos,其中一個是offsetof()
宏。
我試過了
define offsetof
if $argc == 2
(int)(&((($arg0 *)0)->$arg1))
end
end
它不起作用,因為:
struct node
類的類型將被拆分為Struct
和node
,因此$arg0 = Struct
, $arg1 = node
。 任何人都可以幫我一把嗎?
我認為最好將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.