* Modify address of a gdb.Value
@ 2009-06-15 6:22 Niko Sams
2009-06-15 16:43 ` Tom Tromey
0 siblings, 1 reply; 8+ messages in thread
From: Niko Sams @ 2009-06-15 6:22 UTC (permalink / raw)
To: gdb
Hi,
I'm trying to write a pretty-printer for Qt QMap using python.
QMap uses the following code:
static inline Node *concrete(QMapData::Node *node) {
return reinterpret_cast<Node *>(reinterpret_cast<char *>(node) - payload());
}
How can I do such an operation with gdb.Value?
thanks,
Niko
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Modify address of a gdb.Value
2009-06-15 6:22 Modify address of a gdb.Value Niko Sams
@ 2009-06-15 16:43 ` Tom Tromey
2009-06-15 17:05 ` Vladimir Prus
2009-06-17 5:51 ` Niko Sams
0 siblings, 2 replies; 8+ messages in thread
From: Tom Tromey @ 2009-06-15 16:43 UTC (permalink / raw)
To: Niko Sams; +Cc: gdb
>>>>> "Niko" == Niko Sams <niko.sams@gmail.com> writes:
Niko> I'm trying to write a pretty-printer for Qt QMap using python.
Niko> QMap uses the following code:
Niko> static inline Node *concrete(QMapData::Node *node) {
Niko> return reinterpret_cast<Node *>(reinterpret_cast<char *>(node) - payload());
Niko> }
Niko> How can I do such an operation with gdb.Value?
Nobody has implemented inferior function calls using Value yet.
So the payload() part is not implementable.
If you know what it returns, or you can compute it in Python, then
this is no big deal. You can use Value.cast to cast to some other
type, then do pointer math.
newval = (val.cast(Type('char').pointer()) - payload).cast(val.type)
libstdc++ uses a similar implementation trick in some places, those
printers already do this kind of thing.
Tom
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Modify address of a gdb.Value
2009-06-15 16:43 ` Tom Tromey
@ 2009-06-15 17:05 ` Vladimir Prus
2009-06-15 17:33 ` Paul Pluzhnikov
2009-06-15 19:27 ` Tom Tromey
2009-06-17 5:51 ` Niko Sams
1 sibling, 2 replies; 8+ messages in thread
From: Vladimir Prus @ 2009-06-15 17:05 UTC (permalink / raw)
To: gdb
Tom Tromey wrote:
>>>>>> "Niko" == Niko Sams <niko.sams@gmail.com> writes:
>
> Niko> I'm trying to write a pretty-printer for Qt QMap using python.
>
> Niko> QMap uses the following code:
> Niko> static inline Node *concrete(QMapData::Node *node) {
> Niko> return reinterpret_cast<Node *>(reinterpret_cast<char *>(node) - payload());
> Niko> }
>
> Niko> How can I do such an operation with gdb.Value?
>
> Nobody has implemented inferior function calls using Value yet.
Boo. Is this something hard, or is expected soon?
- Volodya
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Modify address of a gdb.Value
2009-06-15 17:05 ` Vladimir Prus
@ 2009-06-15 17:33 ` Paul Pluzhnikov
2009-06-15 19:27 ` Tom Tromey
1 sibling, 0 replies; 8+ messages in thread
From: Paul Pluzhnikov @ 2009-06-15 17:33 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb
On Mon, Jun 15, 2009 at 10:05 AM, Vladimir
Prus<vladimir@codesourcery.com> wrote:
> Tom Tromey wrote:
>> Nobody has implemented inferior function calls using Value yet.
But (I believe) an equivalent could be achieved by constructing a string
representation, and then calling gdb.parse_and_eval() on it [1].
However, I've been burned by doing so: in multi-threaded program
parse_and_eval (and I think inferior function call) resumes inferior,
and that causes no end of grief (including possible recursive entry back
into python, which triggers GDB assertions :-(
Tom, you may want to mention this gotcha when you expand parse_and_eval
documentation.
[1] parse_and_eval is not yet in mainline; the current patch for it is here:
http://sourceware.org/ml/gdb-patches/2009-06/msg00326.html
Cheers,
--
Paul Pluzhnikov
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Modify address of a gdb.Value
2009-06-15 17:05 ` Vladimir Prus
2009-06-15 17:33 ` Paul Pluzhnikov
@ 2009-06-15 19:27 ` Tom Tromey
1 sibling, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2009-06-15 19:27 UTC (permalink / raw)
To: Vladimir Prus; +Cc: gdb
>>>>> "Vladimir" == Vladimir Prus <vladimir@codesourcery.com> writes:
Tom> Nobody has implemented inferior function calls using Value yet.
Vladimir> Boo. Is this something hard, or is expected soon?
I don't know. As far as I know nobody has looked into it.
Tom
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Modify address of a gdb.Value
2009-06-15 16:43 ` Tom Tromey
2009-06-15 17:05 ` Vladimir Prus
@ 2009-06-17 5:51 ` Niko Sams
2009-06-17 15:52 ` Niko Sams
2009-06-17 16:21 ` Tom Tromey
1 sibling, 2 replies; 8+ messages in thread
From: Niko Sams @ 2009-06-17 5:51 UTC (permalink / raw)
To: gdb
> newval = (val.cast(Type('char').pointer()) - payload).cast(val.type)
that is working, thanks.
> Nobody has implemented inferior function calls using Value yet.
> So the payload() part is not implementable.
>
> If you know what it returns, or you can compute it in Python, then
> this is no big deal. You can use Value.cast to cast to some other
> type, then do pointer math.
I tried to implement this payload method in python, the c++ code is
the following:
template <class Key, class T>
struct QMapPayloadNode
{
Key key;
T value;
QMapData::Node *backward;
};
static inline int payload() {
return sizeof(PayloadNode) - sizeof(QMapData::Node *);
}
the obvious solution would be gdb.lookup_type('QMapPayloadNode<%s,
%s>' % (self.ktype, self.vtype)).sizeof
but that doesn't work, i get this error:
RuntimeError: No type named QMapPayloadNode<int, QString *>
This is because that QMapPayloadNode is not instanciated, it's only
used for this sizeof.
So any idea how i can compute the payload?
Niko
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Modify address of a gdb.Value
2009-06-17 5:51 ` Niko Sams
@ 2009-06-17 15:52 ` Niko Sams
2009-06-17 16:21 ` Tom Tromey
1 sibling, 0 replies; 8+ messages in thread
From: Niko Sams @ 2009-06-17 15:52 UTC (permalink / raw)
To: gdb
On Wed, Jun 17, 2009 at 07:51, Niko Sams<niko.sams@gmail.com> wrote:
>> newval = (val.cast(Type('char').pointer()) - payload).cast(val.type)
> that is working, thanks.
>
>
>> Nobody has implemented inferior function calls using Value yet.
>> So the payload() part is not implementable.
>>
>> If you know what it returns, or you can compute it in Python, then
>> this is no big deal. You can use Value.cast to cast to some other
>> type, then do pointer math.
>
> I tried to implement this payload method in python, the c++ code is
> the following:
> template <class Key, class T>
> struct QMapPayloadNode
> {
> Key key;
> T value;
> QMapData::Node *backward;
> };
> static inline int payload() {
> return sizeof(PayloadNode) - sizeof(QMapData::Node *);
> }
>
> the obvious solution would be gdb.lookup_type('QMapPayloadNode<%s,
> %s>' % (self.ktype, self.vtype)).sizeof
> but that doesn't work, i get this error:
> RuntimeError: No type named QMapPayloadNode<int, QString *>
> This is because that QMapPayloadNode is not instanciated, it's only
> used for this sizeof.
>
> So any idea how i can compute the payload?
Ok, here comes my hacky workaround. Tested on amd64 only.
def payload (self):
#we can't use QMapPayloadNode as it's never instanciated and so gcc
#doesn't include it in debug information.
#as a workaround take the sum of sizeof(members)
ret = self.ktype.sizeof
ret += self.vtype.sizeof
ret += gdb.lookup_type('void').pointer().sizeof
#but because of data alignment the value can be higher
#so guess it's aliged by sizeof(void*)
#TODO: find a real solution for this problem
ret += ret % gdb.lookup_type('void').pointer().sizeof
ret -= gdb.lookup_type('void').pointer().sizeof
return ret
Any better idea?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Modify address of a gdb.Value
2009-06-17 5:51 ` Niko Sams
2009-06-17 15:52 ` Niko Sams
@ 2009-06-17 16:21 ` Tom Tromey
1 sibling, 0 replies; 8+ messages in thread
From: Tom Tromey @ 2009-06-17 16:21 UTC (permalink / raw)
To: Niko Sams; +Cc: gdb
>>>>> "Niko" == Niko Sams <niko.sams@gmail.com> writes:
Niko> I tried to implement this payload method in python
[...]
Niko> the obvious solution would be gdb.lookup_type('QMapPayloadNode<%s,
Niko> %s>' % (self.ktype, self.vtype)).sizeof
Niko> but that doesn't work, i get this error:
Niko> RuntimeError: No type named QMapPayloadNode<int, QString *>
Niko> This is because that QMapPayloadNode is not instanciated, it's only
Niko> used for this sizeof.
Niko> So any idea how i can compute the payload?
There's no easy way. gdb only knows what the compiler tells it, and
in this case, the information is omitted.
You could try recreating the ABI struct layout rules in Python.
This is a pain but not insanely hard.
Tom
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-06-17 16:21 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-15 6:22 Modify address of a gdb.Value Niko Sams
2009-06-15 16:43 ` Tom Tromey
2009-06-15 17:05 ` Vladimir Prus
2009-06-15 17:33 ` Paul Pluzhnikov
2009-06-15 19:27 ` Tom Tromey
2009-06-17 5:51 ` Niko Sams
2009-06-17 15:52 ` Niko Sams
2009-06-17 16:21 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox