簡體   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