在Trace32中显示Linux链接列表

时间:2015-11-03 10:31:24

标签: linux linux-kernel embedded-linux trace32 lauterbach

我尝试在用户友好的方式在Trace32中打印Linux链表。

1。是否已有任何已知方法?

如果没有,那么让我展示modules列表的示例。

我有全局变量

static struct list_head modules;

其中

struct list_head {
        struct list_head *next, *prev;
};

所以,在T32中我只看到了v.v modules时的下一个和上一个指针的列表,实际上没有有用的信息。但是,模块列表的每个节点都是容器类型的一部分。在这种情况下struct module

struct module {
         ...
         struct list_head list;
         ...
}

通常,要提取容器指针,Linux使用container_of宏。

/**
  * container_of - cast a member of a structure out to the containing structure
  * @ptr:        the pointer to the member.
  * @type:       the type of the container struct this is embedded in.
  * @member:     the name of the member within the struct.
  *
  */
 #define container_of(ptr, type, member) ({                      \
         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
         (type *)( (char *)__mptr - offsetof(type,member) );})

在我们的示例中,我们知道指向struct list_head list成员struct module成员的指针,然后我们应该调用container_of(modules->next, struct module, list)来获取指向容器的指针。

为了能够在T32中存档,我需要计算容器类型中list成员的偏移量。

任何人都知道如何实现这一目标?

2 个答案:

答案 0 :(得分:4)

嗯,听起来你有两个问题:

  1. 如何显示链接列表?
  2. 如何获取结构中成员的字节偏移量?
  3. 对于显示链接列表,我建议使用命令Var.CHAIN或VAR.FixedCHAIN。这两个命令都有两个必需参数:结构的变量名和下一个元素的名称。 (您可以在TRACE32 manual中查找所有可选参数和格式选项。)

    所以,用

    查看你的第一个简单案例
    Var.CHAIN modules modules.next   
    

    将打开一个窗口,其中会有一个表格,显示完整列表,直到下一个'指向NULL。

    注意 :如下面评论中Wrymarki所述,答案的第一部分实际上是错误的。 Var.CHAIN适用于普通的链接列表,但不适用于" Linux链接列表"。 " Linux链接列表的解决方案" (由Wrymarki编写)是编写一个PRACTICE脚本,它循环遍历列表,并使用container_of()宏将列表条目与Var.AddWatch一起添加到监视窗口(见下文)。

    对于获取结构中成员的偏移,我建议像在源代码中一样声明预处理器宏。或者几乎在您的源代码中,因为TRACE32不知道GCC特定的扩展名,如typeof()或statement expressions

    无论如何,我们可以用

    获取offsetof()宏
    sYmbol.NEW.MACRO offsetof(type,member) ((int)(&((type*)0)->member))
    

    预处理器宏可以在TRACE32中的每个HLL表达式中使用(包含所有Var。*命令和函数)。 E.g:

    Var.AddWatch offsetof(struct module,list)
    

    注意:sYmbol.NEW.MACRO不接受宏名称中的空格:您必须写offsetof(type,member)而不是offsetof(type, member)

    您可以在窗口sYmbol.List.MACRO

    中查看您的宏

    如果您的编译器在使用选项/ MACRO Data.LOAD.Elf * /MACRO加载ELF时支持此编码(GCC使用选项-g3),您也可以从源代码中获取宏。但同样:TRACE32将无法理解GCC特定的扩展或内部宏,如' __ builtin_offsetof()'。

    您还可以使用

    声明 container_of()预处理器宏
    sYmbol.NEW.MACRO container_of(ptr,type,member) ((type *)((char *)(ptr)-offsetof(type,member)))
    

    使用它,例如如下:

    Var.View container_of(modules->next,struct module,list)
    

答案 1 :(得分:0)

在Var.CHAIN和VAR.FixedCHAIN命令之间,我猜Var.CHAIN显示了更详细的链表信息。

对于linux内核系统,以下命令允许完整的链表列表。

v.chain %m %l %tree.open %hex init_task.tasks init_task.tasks.next

  0x0 (0)|  [D:0xC1612588] (
         |    [D:0xC1612588] next = 0xEE058220,
         |    [D:0xC161258C] prev = 0xE5C0B3A0),
  0x1 (1)|  [D:0xEE058220] (
         |    [D:0xEE058220] next = 0xEE0587A0,
         |    [D:0xEE058224] prev = 0xC1612588),
  0x2 (2)|  [D:0xEE0587A0] (
         |    [D:0xEE0587A0] next = 0xEE058D20,
         |    [D:0xEE0587A4] prev = 0xEE058220),
  0x3 (3)|  [D:0xEE058D20] (
         |    [D:0xEE058D20] next = 0xEE0592A0,
         |    [D:0xEE058D24] prev = 0xEE0587A0),
  0x4 (4)|  [D:0xEE0592A0] (
         |    [D:0xEE0592A0] next = 0xEE059820,
         |    [D:0xEE0592A4] prev = 0xEE058D20),
  0x5 (5)|  [D:0xEE059820] (
         |    [D:0xEE059820] next = 0xEE059DA0,
         |    [D:0xEE059824] prev = 0xEE0592A0),
  0x6 (6)|  [D:0xEE059DA0] (
         |    [D:0xEE059DA0] next = 0xEE05A320,
         |    [D:0xEE059DA4] prev = 0xEE059820),
  0x7 (7)|  [D:0xEE05A320] (
         |    [D:0xEE05A320] next = 0xEE05A8A0,
         |    [D:0xEE05A324] prev = 0xEE059DA0),
  0x8 (8)|  [D:0xEE05A8A0] (
         |    [D:0xEE05A8A0] next = 0xEE05AE20,
         |    [D:0xEE05A8A4] prev = 0xEE05A320),
  0x9 (9)|  [D:0xEE05AE20] (
         |    [D:0xEE05AE20] next = 0xEE05B3A0,
         |    [D:0xEE05AE24] prev = 0xEE05A8A0),
0x0A (10)|  [D:0xEE05B3A0] (
         |    [D:0xEE05B3A0] next = 0xEE05B920,
         |    [D:0xEE05B3A4] prev = 0xEE05AE20),
0x0B (11)|  [D:0xEE05B920] (
         |    [D:0xEE05B920] next = 0xEE05BEA0,
         |    [D:0xEE05B924] prev = 0xEE05B3A0),
0x0C (12)|  [D:0xEE05BEA0] (
         |    [D:0xEE05BEA0] next = 0xEE05C420,
         |    [D:0xEE05BEA4] prev = 0xEE05B920),
0x0D (13)|  [D:0xEE05C420] (
         |    [D:0xEE05C420] next = 0xEE05DA20,
         |    [D:0xEE05C424] prev = 0xEE05BEA0),
0x0E (14)|  [D:0xEE05DA20] (
         |    [D:0xEE05DA20] next = 0xEE05DFA0,
         |    [D:0xEE05DA24] prev = 0xEE05C420),
0x0F (15)|  [D:0xEE05DFA0] (
         |    [D:0xEE05DFA0] next = 0xEE05E520,
         |    [D:0xEE05DFA4] prev = 0xEE05DA20),