gdb vs C standard

Discussion in 'C Programming' started by Chris Peters, Aug 25, 2008.

  1. Chris Peters

    Chris Peters Guest

    Hello

    I am debugging some code with gdb and want to watch a 64-bit long int
    value x. But gdb can only set 32-bit width watches.

    My solution is to watch these two things
    *((int *) &x)
    *((int *) &x + 1)

    But I understood from this group that this kind of "type punning" or
    pointer conversion is u/b according to the C standard.

    Does that mean the two watches above might not work? What is the
    "standard" solution?

    Thanks.
    Chris Peters, Aug 25, 2008
    #1
    1. Advertising

  2. Chris Peters <> writes:

    > I am debugging some code with gdb and want to watch a 64-bit long int
    > value x. But gdb can only set 32-bit width watches.


    My gdb is happy with 64 bit values in watch expressions.

    > My solution is to watch these two things
    > *((int *) &x)
    > *((int *) &x + 1)
    >
    > But I understood from this group that this kind of "type punning" or
    > pointer conversion is u/b according to the C standard.


    If it works, use it.

    > Does that mean the two watches above might not work? What is the
    > "standard" solution?


    The standard does not say much about it but the best solution is to
    find a debugger that "speaks" the language you write so you don't need
    to do this sort of thing.

    --
    Ben.
    Ben Bacarisse, Aug 25, 2008
    #2
    1. Advertising

  3. Chris Peters

    Richard Guest

    Chris Peters <> writes:

    > Hello
    >
    > I am debugging some code with gdb and want to watch a 64-bit long int
    > value x. But gdb can only set 32-bit width watches.
    >
    > My solution is to watch these two things
    > *((int *) &x)
    > *((int *) &x + 1)
    >
    > But I understood from this group that this kind of "type punning" or
    > pointer conversion is u/b according to the C standard.
    >
    > Does that mean the two watches above might not work? What is the
    > "standard" solution?
    >
    > Thanks.


    FYI

    "watch l" works for me on a 32 bit gdb/linux combo.

    where l is a long long int and compiler is gcc and gdb shows it as a 64
    bit value (I always 'set radix 16' btw).
    Richard, Aug 25, 2008
    #3
  4. Chris Peters

    Guest

    On Aug 25, 11:36 pm, Chris Peters <> wrote:
    > Hello
    >
    > I am debugging some code with gdb and want to watch a 64-bit long int
    > value x. But gdb can only set 32-bit width watches.
    >
    > My solution is to watch these two things
    > *((int *) &x)
    > *((int *) &x + 1)
    >
    > But I understood from this group that this kind of "type punning" or
    > pointer conversion is u/b according to the C standard.
    >
    > Does that mean the two watches above might not work? What is the
    > "standard" solution?


    There's just one standard solution. The representation of long int is
    not known.
    You have to keep a unsigned int [ULONG_MAX / UINT_MAX + 1] large
    array.
    In each element, you'd initialize as:

    size_t i = 0;
    long l = somevalue;
    unsigned int array[ULONG_MAX / UINT_MAX + 1];

    while(l > UINT_MAX) l -= UINT_MAX, array[i++] = UINT_MAX;

    Then you'd observe the values of array[0] to array[i-1], as:

    int x = array[y] > INT_MAX ? -(int)(array[y] - INT_MAX) : array[y];
    , Aug 26, 2008
    #4
  5. Chris Peters

    Richard Guest

    writes:

    > On Aug 25, 11:36 pm, Chris Peters <> wrote:
    >> Hello
    >>
    >> I am debugging some code with gdb and want to watch a 64-bit long int
    >> value x. But gdb can only set 32-bit width watches.
    >>
    >> My solution is to watch these two things
    >> *((int *) &x)
    >> *((int *) &x + 1)
    >>
    >> But I understood from this group that this kind of "type punning" or
    >> pointer conversion is u/b according to the C standard.
    >>
    >> Does that mean the two watches above might not work? What is the
    >> "standard" solution?

    >
    > There's just one standard solution. The representation of long int is
    > not known.
    > You have to keep a unsigned int [ULONG_MAX / UINT_MAX + 1] large
    > array.
    > In each element, you'd initialize as:
    >
    > size_t i = 0;
    > long l = somevalue;
    > unsigned int array[ULONG_MAX / UINT_MAX + 1];
    >
    > while(l > UINT_MAX) l -= UINT_MAX, array[i++] = UINT_MAX;
    >
    > Then you'd observe the values of array[0] to array[i-1], as:
    >
    > int x = array[y] > INT_MAX ? -(int)(array[y] - INT_MAX) : array[y];


    So how come it works fine on my 32 bit system watching a long long int?
    Richard, Aug 26, 2008
    #5
  6. Chris Peters

    Guest

    On Aug 25, 1:36 pm, Chris Peters <> wrote:
    > Hello
    >
    > I am debugging some code with gdb and want to watch a 64-bit long int
    > value x. But gdb can only set 32-bit width watches.
    >
    > My solution is to watch these two things
    > *((int *) &x)
    > *((int *) &x + 1)
    >
    > But I understood from this group that this kind of "type punning" or
    > pointer conversion is u/b according to the C standard.
    >
    > Does that mean the two watches above might not work? What is the
    > "standard" solution?


    This is off-topic on comp.lang.c. I'll put followups to
    comp.unix.programmer. It really should go to a system-specific
    newsgroup but you didn't say what your system is.

    Meanwhile...

    Of course this is nothing to do with the C language. gdb's syntax,
    while C-like, does not hold you to all the same constraints. I think
    you can rely on gdb commands doing what they appear to say.

    However, what you propose may still have a problem, depending on the
    system you are using.

    gdb has two kinds of watches: hardware and software. A software watch
    inspects the value of the watchpoint target after each instruction is
    executed to see if it has changed. Although slow, this should allow
    you to watch any expression you want, so I would guess this is not
    what you're doing.

    A hardware watch uses a feature of the CPU which causes it to trap
    when the relevant address is written. Usually the address and size of
    the target must exactly match the instruction that writes it. If you
    are on a 64-bit platform, a 64-bit long int is likely written as a
    single instruction, which would trigger a watchpoint at &x but not at
    (int *)&x +1 , which is 4 bytes higher. So in that case the second
    watchpoint is unnecessary. On the other hand, in this case you ought
    to have the ability to set a 64-bit watch.

    If on the other hand you are on a 32-bit platform (where 64-bit types
    are usually called 'long long int'), a 64-bit integer would be written
    with two instructions, so you might in principle need two
    watchpoints. However, it would be rare for code to write one half and
    not the other. They will normally happen within one or two
    instructions of each other, so it is probably sufficient to watch one
    of them. If this is on x86, which is little-endian, the lower address
    contains the least-significant half, which is more likely to have to
    change on any given write, so that seems the safer alternative.
    , Aug 26, 2008
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. steve.leach

    How standard is the standard library?

    steve.leach, Apr 18, 2005, in forum: Python
    Replies:
    1
    Views:
    388
    Christos TZOTZIOY Georgiou
    Apr 18, 2005
  2. funkyj
    Replies:
    5
    Views:
    1,122
    funkyj
    Jan 20, 2006
  3. Surendra
    Replies:
    0
    Views:
    508
    Surendra
    Mar 23, 2006
  4. seba
    Replies:
    1
    Views:
    1,443
    mlimber
    Mar 22, 2007
  5. Timothy Madden
    Replies:
    1
    Views:
    1,616
    Timothy Madden
    Sep 17, 2009
Loading...

Share This Page