10

Here is the definition of structure in 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);

An array of this structure is defined and values are assigned to each projection's variables. Using GDB, I am trying to display the value of the size of each projection. Printing the values one by one is a heavy process.

I know that the content of arrays can be displayed with print *projections@len but I do not know if it is possible to access easily the values of projection's size with the @ operand.

2
  • 1
    -1 You rejected two very good answers that suggested using python or a few instructions in gdb as not being convenient, and then modified your C code instead? You should have clarified your definition of "easily" so readers wouldn't waste their time trying to help you. Commented Jan 21, 2014 at 12:02
  • 1
    These answers bring great information to solve the problem, as I highlight in my comments. It is definitely neither a waste of time nor should it be considered as rejected as I am sure it can help other users that know Python. Yes, I consider adding few instructions in the C code and using the 'call' function a good alternative as it might be helpful for everyone. Commented Jan 21, 2014 at 12:12

5 Answers 5

16

While not using the @ operand you can try the following to achieve your goal:

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

or use

p projections[index].size

to print the size for the given index.

Sign up to request clarification or add additional context in comments.

3 Comments

The documentation suggests something similar, without the loop.
Yes, but without the loop no boundary check is provided. Meaning that if someone goes on pressing <RET> then he might end up inspecting memory out of the specified size of the projections array.
Thanks for the reply. Yes, both work but are not convenient in my opinion. The first one requires to write a loop and associated variables, and the second one is what I meant by "one by one" in my post.
15

You can register python pretty prointer: https://sourceware.org/gdb/onlinedocs/gdb/Writing-a-Pretty_002dPrinter.html and use it to get something like this:

(gdb) p *projections@10
$1 = {10, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
(gdb)

This is example of a python pretty printer:

>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())

This is a test program:

>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;
}

And this is a gdb session:

>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)

1 Comment

Thanks for the reply :) I voted up as it works and is it supported by GDB's documentation. However, this solution relies on Python which is not a simple solution in my case.
1

I did not want to write a loop each time I launch GDB, and pretty-printers rely on Python which does not fit me. Printing the value of variables from non contiguous memory spaces seems not to be easily feasible in GDB.

I end up finding an alternative way which seems to be the easiest one. I wrote a C function in the code to print the values I need to get:

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);
}

It is possible to call the function from GDB when I want to print the size of each projections:

(gdb) call print(projections, len)
proj_0: size=1027
proj_1: size=1024
proj_2: size=1027
proj_3: size=1030

Comments

1

Define a function that prints out each element in a loop. You only need to define the function once. Set $m equal to number of projections you allocated. Then, you can print out everything with one command line input.

(gdb) set $m=4 

(gdb) define f
>set $i=0
>while ($i<$m)
> p projections[$i++].size
> end
>end

(gdb) f

1 Comment

f - is short for "frame <#N>" command. Pick up another name.
0
(gdb) p *(projection_t (*)[10])projections

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.