在GDB中打印结构数组的变量值

den*_*tre 7 c arrays debugging gdb data-structures

这是C中结构的定义:

typedef struct projection {
    angle_t angle;
    int size;
    element_t *element;
} projection_t;

projection_t *projections;
projections = (projection_t *)malloc(sizeof(projection_t)*m);
Run Code Online (Sandbox Code Playgroud)

定义了这个结构的数组,并为每个投影的变量赋值.使用GDB,我试图显示每个投影的大小的值.逐个打印值是一个繁重的过程.

我知道数组的内容可以显示print *projections@len但我不知道是否可以使用@操作数轻松访问投影大小的值.

Ser*_*kov 12

您可以注册python pretty prointer:https://sourceware.org/gdb/onlinedocs/gdb/Writing-a-Pretty_002dPrinter.html 并使用它来获得如下内容:

(gdb) p *projections@10
$1 = {10, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
(gdb)
Run Code Online (Sandbox Code Playgroud)

这是一个python漂亮的打印机的例子:

>cat my_printer.py
class projection_printer:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return str(self.val['size'])


import gdb.printing

def build_pretty_printer():
    pp = gdb.printing.RegexpCollectionPrettyPrinter("")
    pp.add_printer('projection', '^projection$', projection_printer)
    return pp
gdb.printing.register_pretty_printer( gdb.current_objfile(),  build_pretty_printer())
Run Code Online (Sandbox Code Playgroud)

这是一个测试程序:

>cat main.cpp
#include <stdlib.h>

typedef struct angle
{
  int a;
} angle_t;


typedef struct projection {
    angle_t angle;
    int size;
} projection_t;


int main()
{
  projection_t *projections;
  projections = (projection_t *)malloc(sizeof(projection_t)*10);
  projections[0].size = 10;
  projections[0].angle.a = 20;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是一个gdb会话:

>gdb -q -x my_printer.py a.out
Reading symbols from /home/a.out...done.
(gdb) start
Temporary breakpoint 1 at 0x4005ac: file main.cpp, line 18.
Starting program: /home/a.out

Temporary breakpoint 1, main () at main.cpp:18
18        projections = (projection_t *)malloc(sizeof(projection_t)*10);
(gdb) n
19        projections[0].size = 10;
(gdb)
20        projections[0].angle.a = 20;
(gdb)
22        return 0;
(gdb) p *projections@10
$1 = {10, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
(gdb)
Run Code Online (Sandbox Code Playgroud)


nik*_*el7 11

虽然不使用@操作数,但您可以尝试以下方法来实现目标:

(gdb)set $i=0
(gdb) set $end=m
(gdb) while ($i < $end)
 >p projections[$i++].size
 >end
Run Code Online (Sandbox Code Playgroud)

或使用

p projections[index].size
Run Code Online (Sandbox Code Playgroud)

打印给定索引的大小.


den*_*tre 1

我不想每次启动 GDB 时都编写一个循环,而且漂亮的打印机依赖于 Python,这不适合我。在 GDB 中,从非连续内存空间打印变量的值似乎不太可行。

我最终找到了一种似乎是最简单的替代方法。我在代码中编写了一个C函数来打印我需要获取的值:

void print(projection_t *projections, int size)
{
    int i;
    for(i=0; i<size; i++)
        printf("proj_%d: size=%d\n", i, projections[i].size);
}
Run Code Online (Sandbox Code Playgroud)

当我想打印每个投影的大小时,可以从 GDB 调用该函数:

(gdb) call print(projections, len)
proj_0: size=1027
proj_1: size=1024
proj_2: size=1027
proj_3: size=1030
Run Code Online (Sandbox Code Playgroud)