* 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