Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > gdb vs C standard

Reply
Thread Tools

gdb vs C standard

 
 
Chris Peters
Guest
Posts: n/a
 
      08-25-2008
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.


 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      08-25-2008
Chris Peters <(E-Mail Removed)> 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.
 
Reply With Quote
 
 
 
 
Richard
Guest
Posts: n/a
 
      08-25-2008
Chris Peters <(E-Mail Removed)> 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).


 
Reply With Quote
 
vippstar@gmail.com
Guest
Posts: n/a
 
      08-26-2008
On Aug 25, 11:36 pm, Chris Peters <(E-Mail Removed)> 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];


 
Reply With Quote
 
Richard
Guest
Posts: n/a
 
      08-26-2008
http://www.velocityreviews.com/forums/(E-Mail Removed) writes:

> On Aug 25, 11:36 pm, Chris Peters <(E-Mail Removed)> 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?
 
Reply With Quote
 
fjblurt@yahoo.com
Guest
Posts: n/a
 
      08-26-2008
On Aug 25, 1:36 pm, Chris Peters <(E-Mail Removed)> 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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Debugging with gdb: pystack macro for gdb to show python stack trace Timothy Madden Python 1 09-17-2009 11:47 AM
GDB - no debugging symbols found (GDB Vs GCC?) seba C++ 1 03-22-2007 02:02 PM
Capturing gdb output in pyhton script using gdb -batch -x arguments Surendra Python 0 03-23-2006 02:47 PM
add pexpect to the standard library, standard "install" mechanism. funkyj Python 5 01-20-2006 08:35 PM
How standard is the standard library? steve.leach Python 1 04-18-2005 04:07 PM



Advertisments