gdb vs C standard

C

Chris Peters

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.
 
B

Ben Bacarisse

Chris Peters said:
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.
 
R

Richard

Chris Peters said:
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).
 
V

vippstar

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];
 
R

Richard

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?
 
F

fjblurt

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top