* container_of equivalent in gdb-python script @ 2009-06-10 16:56 Jan Kiszka 2009-06-10 18:57 ` Tom Tromey 0 siblings, 1 reply; 11+ messages in thread From: Jan Kiszka @ 2009-06-10 16:56 UTC (permalink / raw) To: gdb Hi, I'm currently getting my feet wet with gdb's great python extension. My first exercise is to walk a linked list of objects in a C inferior (namely 'modules' of the Linux kernel) and evaluate the elements. I'm at the point where I would apply a standard container_of() macro in C: convert the list entry into a gdb.Value that describes the containing object. Of course, I can implement container_of as a gdb expression, print the result and drag it in via gdb.history(). Done that already, basically works. But it is fairly ugly as the print output will flood the screen. I'm probably overseeing some obvious path in the python extension, any pointers welcome! Thanks, Jan -- Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: container_of equivalent in gdb-python script 2009-06-10 16:56 container_of equivalent in gdb-python script Jan Kiszka @ 2009-06-10 18:57 ` Tom Tromey 2009-06-10 20:10 ` Jan Kiszka 0 siblings, 1 reply; 11+ messages in thread From: Tom Tromey @ 2009-06-10 18:57 UTC (permalink / raw) To: Jan Kiszka; +Cc: gdb >>>>> "Jan" == Jan Kiszka <jan.kiszka@siemens.com> writes: Jan> I'm at the point where I would apply a standard container_of() Jan> macro in C: convert the list entry into a gdb.Value that Jan> describes the containing object. Jan> Of course, I can implement container_of as a gdb expression, print the Jan> result and drag it in via gdb.history(). Done that already, basically Jan> works. But it is fairly ugly as the print output will flood the screen. I would say that the usual approach would be to reimplement the macro in Python. The Python Value API is reasonably robust and can usually be used for this. If you post the macro definition maybe I could help with that. More details wouldn't hurt, either... are you writing a pretty-printer? A new command? A convenience function? Tom ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: container_of equivalent in gdb-python script 2009-06-10 18:57 ` Tom Tromey @ 2009-06-10 20:10 ` Jan Kiszka 2009-06-10 20:37 ` Tom Tromey 2009-06-10 20:42 ` Daniel Jacobowitz 0 siblings, 2 replies; 11+ messages in thread From: Jan Kiszka @ 2009-06-10 20:10 UTC (permalink / raw) To: tromey; +Cc: gdb [-- Attachment #1: Type: text/plain, Size: 2104 bytes --] Tom Tromey wrote: >>>>>> "Jan" == Jan Kiszka <jan.kiszka@siemens.com> writes: > > Jan> I'm at the point where I would apply a standard container_of() > Jan> macro in C: convert the list entry into a gdb.Value that > Jan> describes the containing object. > > Jan> Of course, I can implement container_of as a gdb expression, print the > Jan> result and drag it in via gdb.history(). Done that already, basically > Jan> works. But it is fairly ugly as the print output will flood the screen. > > I would say that the usual approach would be to reimplement the macro > in Python. The Python Value API is reasonably robust and can usually > be used for this. If you post the macro definition maybe I could help > with that. More details wouldn't hurt, either... are you writing a > pretty-printer? A new command? A convenience function? I want to automate 'add-symbol-file linux_module.ko 0xff...' that you have to run for loading the symbols of dynamically loaded kernel modules. Before that you also have to look up the module base address, typically by cat'ing /proc/modules on the target. With a proper python script, this will be trivial to do automatically. You just have to walk the module list of the kernel you are attached to, extract names and base addresses, search for the corresponding module binaries (also easy with python) and issue the proper add-symbol-file commands. But now back to the core problems, starting with the exercise to implement offset_of(type, field): def offset_of(type, field): container_type = gdb.lookup_type(type) dummy_obj = gdb.selected_frame().read_var('modules') container_obj = dummy_obj.cast(container_type) field_obj = container_obj[field] return int(str(field_obj.address), 16) - \ int(str(container_obj.address), 16) I meanwhile discovered (reading testcases and python-*.c) gdb.lookup_type() and Value.cast() to make this real. But you see, I still need an ugly synthetic Value object which must have a non-'None' address to do this calculation. Is there a cleaner, more generic way? Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 257 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: container_of equivalent in gdb-python script 2009-06-10 20:10 ` Jan Kiszka @ 2009-06-10 20:37 ` Tom Tromey 2009-06-10 21:06 ` Jan Kiszka 2009-06-10 20:42 ` Daniel Jacobowitz 1 sibling, 1 reply; 11+ messages in thread From: Tom Tromey @ 2009-06-10 20:37 UTC (permalink / raw) To: Jan Kiszka; +Cc: gdb >>>>> "Jan" == Jan Kiszka <jan.kiszka@web.de> writes: Jan> I meanwhile discovered (reading testcases and python-*.c) Jan> gdb.lookup_type() and Value.cast() to make this real. But you see, I Jan> still need an ugly synthetic Value object which must have a non-'None' Jan> address to do this calculation. Is there a cleaner, more generic way? Yeah, I think the missing piece is "gdb.parse_and_eval", which is on the archer python branch, but which we haven't pushed upstream into gdb CVS yet. This takes an expression (a string), parses it, evaluates it, and returns a Value. It is very convenient when implementing your own gdb commands. I don't think there's any particular problem with submitting this, just somebody finding the time. Tom ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: container_of equivalent in gdb-python script 2009-06-10 20:37 ` Tom Tromey @ 2009-06-10 21:06 ` Jan Kiszka 0 siblings, 0 replies; 11+ messages in thread From: Jan Kiszka @ 2009-06-10 21:06 UTC (permalink / raw) To: tromey; +Cc: gdb [-- Attachment #1: Type: text/plain, Size: 994 bytes --] Tom Tromey wrote: >>>>>> "Jan" == Jan Kiszka <jan.kiszka@web.de> writes: > > Jan> I meanwhile discovered (reading testcases and python-*.c) > Jan> gdb.lookup_type() and Value.cast() to make this real. But you see, I > Jan> still need an ugly synthetic Value object which must have a non-'None' > Jan> address to do this calculation. Is there a cleaner, more generic way? > > Yeah, I think the missing piece is "gdb.parse_and_eval", which is on > the archer python branch, but which we haven't pushed upstream into > gdb CVS yet. This takes an expression (a string), parses it, > evaluates it, and returns a Value. It is very convenient when > implementing your own gdb commands. Perfect, that solves the problem! Just checked out and tried successfully. > > I don't think there's any particular problem with submitting this, > just somebody finding the time. > Hopefully before the next release. I would try to help, but I don't have an FSF assignment. Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 257 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: container_of equivalent in gdb-python script 2009-06-10 20:10 ` Jan Kiszka 2009-06-10 20:37 ` Tom Tromey @ 2009-06-10 20:42 ` Daniel Jacobowitz 2009-06-10 21:33 ` Jan Kiszka 1 sibling, 1 reply; 11+ messages in thread From: Daniel Jacobowitz @ 2009-06-10 20:42 UTC (permalink / raw) To: Jan Kiszka; +Cc: tromey, gdb On Wed, Jun 10, 2009 at 10:10:39PM +0200, Jan Kiszka wrote: > I want to automate 'add-symbol-file linux_module.ko 0xff...' that you > have to run for loading the symbols of dynamically loaded kernel > modules. Before that you also have to look up the module base address, > typically by cat'ing /proc/modules on the target. With a proper python > script, this will be trivial to do automatically. You just have to walk > the module list of the kernel you are attached to, extract names and > base addresses, search for the corresponding module binaries (also easy > with python) and issue the proper add-symbol-file commands. FYI, I am hoping to work on this soon (in the next month). The right representation is not a set of add-symbol-file commands, which doesn't play nicely with repeated unload/reload, but instead a synthetic list of shared libraries. That calls for some extensions to the current set of Python hooks and shared library infrastructure, though! And it will require basically everything you're doing now :-) > But now back to the core problems, starting with the exercise to > implement offset_of(type, field): > > def offset_of(type, field): > container_type = gdb.lookup_type(type) > dummy_obj = gdb.selected_frame().read_var('modules') > container_obj = dummy_obj.cast(container_type) > field_obj = container_obj[field] > return int(str(field_obj.address), 16) - \ > int(str(container_obj.address), 16) > > I meanwhile discovered (reading testcases and python-*.c) > gdb.lookup_type() and Value.cast() to make this real. But you see, I > still need an ugly synthetic Value object which must have a non-'None' > address to do this calculation. Is there a cleaner, more generic way? It's typical to do this the same way folks do in C: Create a null pointer of the right type. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: container_of equivalent in gdb-python script 2009-06-10 20:42 ` Daniel Jacobowitz @ 2009-06-10 21:33 ` Jan Kiszka 2009-06-10 21:42 ` Tom Tromey 0 siblings, 1 reply; 11+ messages in thread From: Jan Kiszka @ 2009-06-10 21:33 UTC (permalink / raw) To: tromey; +Cc: gdb [-- Attachment #1: Type: text/plain, Size: 2482 bytes --] Daniel Jacobowitz wrote: > On Wed, Jun 10, 2009 at 10:10:39PM +0200, Jan Kiszka wrote: >> I want to automate 'add-symbol-file linux_module.ko 0xff...' that you >> have to run for loading the symbols of dynamically loaded kernel >> modules. Before that you also have to look up the module base address, >> typically by cat'ing /proc/modules on the target. With a proper python >> script, this will be trivial to do automatically. You just have to walk >> the module list of the kernel you are attached to, extract names and >> base addresses, search for the corresponding module binaries (also easy >> with python) and issue the proper add-symbol-file commands. > > FYI, I am hoping to work on this soon (in the next month). The right > representation is not a set of add-symbol-file commands, which doesn't > play nicely with repeated unload/reload, but instead a synthetic list Currently, I does. I simply reload the whole set of symbols (vmlinux + modules) when requested by the user. Of course, one could additionally register a triggering breakpoint on return of load_module(), but having a simple helper that can be called on demand will already be a great improvement. > of shared libraries. That calls for some extensions to the current > set of Python hooks and shared library infrastructure, though! And it > will require basically everything you're doing now :-) Looking forward nevertheless. What ever makes kernel debugging more handy is welcome. Once finished, I will post my script here. > >> But now back to the core problems, starting with the exercise to >> implement offset_of(type, field): >> >> def offset_of(type, field): >> container_type = gdb.lookup_type(type) >> dummy_obj = gdb.selected_frame().read_var('modules') >> container_obj = dummy_obj.cast(container_type) >> field_obj = container_obj[field] >> return int(str(field_obj.address), 16) - \ >> int(str(container_obj.address), 16) >> >> I meanwhile discovered (reading testcases and python-*.c) >> gdb.lookup_type() and Value.cast() to make this real. But you see, I >> still need an ugly synthetic Value object which must have a non-'None' >> address to do this calculation. Is there a cleaner, more generic way? > > It's typical to do this the same way folks do in C: Create a null > pointer of the right type. You can't do that with the current upstream python interface, but the parse_and_eval solves this nicely. Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 257 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: container_of equivalent in gdb-python script 2009-06-10 21:33 ` Jan Kiszka @ 2009-06-10 21:42 ` Tom Tromey 2009-06-10 22:13 ` Jan Kiszka 0 siblings, 1 reply; 11+ messages in thread From: Tom Tromey @ 2009-06-10 21:42 UTC (permalink / raw) To: Jan Kiszka; +Cc: gdb >>>>> "Jan" == Jan Kiszka <jan.kiszka@web.de> writes: Daniel> It's typical to do this the same way folks do in C: Create a null Daniel> pointer of the right type. Jan> You can't do that with the current upstream python interface, but the Jan> parse_and_eval solves this nicely. Actually, for constants you can: (gdb) python print gdb.Value(0) 0 (gdb) python print type(gdb.Value(0)) <type 'gdb.Value'> (gdb) python print gdb.Value(0).cast(gdb.lookup_type('char').pointer()) 0x0 Whoops, this seems to be undocumented. Tom ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: container_of equivalent in gdb-python script 2009-06-10 21:42 ` Tom Tromey @ 2009-06-10 22:13 ` Jan Kiszka 2009-06-10 22:17 ` Tom Tromey 0 siblings, 1 reply; 11+ messages in thread From: Jan Kiszka @ 2009-06-10 22:13 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb [-- Attachment #1: Type: text/plain, Size: 776 bytes --] Tom Tromey wrote: >>>>>> "Jan" == Jan Kiszka <jan.kiszka@web.de> writes: > > Daniel> It's typical to do this the same way folks do in C: Create a null > Daniel> pointer of the right type. > > Jan> You can't do that with the current upstream python interface, but the > Jan> parse_and_eval solves this nicely. > > Actually, for constants you can: > > (gdb) python print gdb.Value(0) > 0 > (gdb) python print type(gdb.Value(0)) > <type 'gdb.Value'> > (gdb) python print gdb.Value(0).cast(gdb.lookup_type('char').pointer()) > 0x0 Yeah, seen this (in the testsuite). But such objects neither have addresses, nor do they help with non-constant objects I'm interested in. > > Whoops, this seems to be undocumented. Not the only piece... :) Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 257 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: container_of equivalent in gdb-python script 2009-06-10 22:13 ` Jan Kiszka @ 2009-06-10 22:17 ` Tom Tromey 2009-06-11 9:51 ` Jan Kiszka 0 siblings, 1 reply; 11+ messages in thread From: Tom Tromey @ 2009-06-10 22:17 UTC (permalink / raw) To: Jan Kiszka; +Cc: gdb >>>>> "Jan" == Jan Kiszka <jan.kiszka@web.de> writes: Jan> Yeah, seen this (in the testsuite). But such objects neither have Jan> addresses, nor do they help with non-constant objects I'm interested in. Yeah. You can use this for "offsetof" but it sounds like you wanted more. Tom> Whoops, this seems to be undocumented. Jan> Not the only piece... :) Please report anything you think is missing. We try very hard to document the entirety of the Python API; anything missing is due to an oversight. I will write doc patches for anything you "don't" find ;) Tom ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: container_of equivalent in gdb-python script 2009-06-10 22:17 ` Tom Tromey @ 2009-06-11 9:51 ` Jan Kiszka 0 siblings, 0 replies; 11+ messages in thread From: Jan Kiszka @ 2009-06-11 9:51 UTC (permalink / raw) To: tromey; +Cc: gdb [-- Attachment #1: Type: text/plain, Size: 902 bytes --] Tom Tromey wrote: >>>>>> "Jan" == Jan Kiszka <jan.kiszka@web.de> writes: > > Jan> Yeah, seen this (in the testsuite). But such objects neither have > Jan> addresses, nor do they help with non-constant objects I'm interested in. > > Yeah. You can use this for "offsetof" but it sounds like you wanted > more. Yep, essentially instantiate a gdb.Value object of arbitrary type at an arbitrary address. > > Tom> Whoops, this seems to be undocumented. > > Jan> Not the only piece... :) > > Please report anything you think is missing. We try very hard to > document the entirety of the Python API; anything missing is due to an > oversight. I will write doc patches for anything you "don't" find ;) > I have to correct myself: Actually looking at the right documentation, I find all the latest features described (I was probably still starring at 6.8 docs...). Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 257 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2009-06-11 9:51 UTC | newest] Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2009-06-10 16:56 container_of equivalent in gdb-python script Jan Kiszka 2009-06-10 18:57 ` Tom Tromey 2009-06-10 20:10 ` Jan Kiszka 2009-06-10 20:37 ` Tom Tromey 2009-06-10 21:06 ` Jan Kiszka 2009-06-10 20:42 ` Daniel Jacobowitz 2009-06-10 21:33 ` Jan Kiszka 2009-06-10 21:42 ` Tom Tromey 2009-06-10 22:13 ` Jan Kiszka 2009-06-10 22:17 ` Tom Tromey 2009-06-11 9:51 ` Jan Kiszka
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox