* [RFC] Target Layer Python Interface
@ 2016-01-29 12:33 Kieran Bingham
2016-01-31 15:21 ` Phil Muldoon
0 siblings, 1 reply; 8+ messages in thread
From: Kieran Bingham @ 2016-01-29 12:33 UTC (permalink / raw)
To: gdb; +Cc: Yao Qi, Peter Griffin
While investigating how to get Python to define the threads presented by
the application layer (in my instance the linux kernel) I found that I
could create threads with a call from Python, (by writing a hook through
the inferior object)
However, whilst these threads were added, they were immediately removed
by the next call to (target).to_update_thread_list()
This has led me to believe I should create a Python Target layer
interface, which I have started, and have been able to register a
target, and provide Python bindings so that (currently _to_thread_name)
calls into the python layer object, and returns a new name.
My intention is that this can be extended to provide the whole set of
target operations allowing me to implement much of the Linux Kernel
Debugger interface in Python.
Through this layer, we can even tackle some of the issues with memory
address spaces, by adding appropriate hooks to adjust MMU context, or
interpret page tables through the relevant target_ops hooks.
Some of the interface can even hopefully be autogenerated by a
make-target-delegate equivalent
This layer interface, will mean that I can provide a Linux Thread
Awareness layer to implement a thread_stratum layer, and can even go
further to provide extra layers for other functionality later.
With a example implementation looking like the start of this:
======================================================================
class LxAwarenessTarget(gdb.Target):
""" Provide a Linux Awareness Target Layer
This will provide hooks for our Thread implementation, and later
extra architecture specific target layers to handle memory """
def __init__(self):
self.shortname = "LxThreads"
self.longname = "Linux Thread Integration Layer"
super(LxAwarenessTarget, self).__init__(gdb.Stratums.thread)
def to_thread_name(self, gdbthread):
return "A thread"
...
(gdb) maintenance print target-stack
The current target stack is:
- LxThreads (Linux Thread Integration Layer)
- remote (Remote serial target in gdb-specific protocol)
- exec (Local exec file)
- None (None)
(gdb) info threads
Id Target Id Frame
2 Thread 2 "A thread" (CPU#1 [halted ]) default_idle ()
at /home/linaro/sources/linux/arch/x86/kernel/process.c:305
* 1 Thread 1 "A thread" (CPU#0 [halted ]) default_idle ()
at /home/linaro/sources/linux/arch/x86/kernel/process.c:305
======================================================================
By implementing this as a layer, it will also allow other
implementations from OS's or targets to define their specific
implementation detail in their source trees
Before I head too much further, I wanted to ask the opinions of the
community as to whether this is an acceptable interface to implement, or
if it opens up too much of the GDB internals, to external dependencies.
Whilst the target layer may be defined as 'fairly' stable - It has
undergone changes, and this may cause issues if exposed to an external
interface.
We could of course tackle this by providing a versioned API which would
allow adaptation in the Python objects, but I thought it was a big
enough question that it should be posed to a wider audience (wider than
just me!)
Regards
--
Kieran
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [RFC] Target Layer Python Interface 2016-01-29 12:33 [RFC] Target Layer Python Interface Kieran Bingham @ 2016-01-31 15:21 ` Phil Muldoon 2016-02-01 18:19 ` Kieran Bingham 0 siblings, 1 reply; 8+ messages in thread From: Phil Muldoon @ 2016-01-31 15:21 UTC (permalink / raw) To: Kieran Bingham, gdb; +Cc: Yao Qi, Peter Griffin On 29/01/16 12:33, Kieran Bingham wrote: > While investigating how to get Python to define the threads presented by > the application layer (in my instance the linux kernel) I found that I > could create threads with a call from Python, (by writing a hook through > the inferior object) A snippet would be cool to see what you are doing here, if possible. > However, whilst these threads were added, they were immediately removed > by the next call to (target).to_update_thread_list() I presume you mean GDB's accounting of them, not the actual threads? > This has led me to believe I should create a Python Target layer > interface, which I have started, and have been able to register a > target, and provide Python bindings so that (currently _to_thread_name) > calls into the python layer object, and returns a new name. > > My intention is that this can be extended to provide the whole set of > target operations allowing me to implement much of the Linux Kernel > Debugger interface in Python. At this point, there's just not enough information to form an opinion of this being a good thing or a bad thing. Do you have an interface in mind? An API? > > Through this layer, we can even tackle some of the issues with memory > address spaces, by adding appropriate hooks to adjust MMU context, or > interpret page tables through the relevant target_ops hooks. Interesting! > Some of the interface can even hopefully be autogenerated by a > make-target-delegate equivalent Presume you mean the Python C code/interface? > Before I head too much further, I wanted to ask the opinions of the > community as to whether this is an acceptable interface to implement, or > if it opens up too much of the GDB internals, to external dependencies. This is something that is always a balancing act with Python GDB. There are, as you allude too, some parts of GDB that are not suitable to be extended to the Python layer, and some parts that while theoretically OK, need a little work to make safe and accessible in a Pythonic way. I can't comment without more details though. My initial reaction though is yeah, this sounds useful and exciting. > We could of course tackle this by providing a versioned API which would > allow adaptation in the Python objects, but I thought it was a big > enough question that it should be posed to a wider audience (wider than > just me!) The versioned API would also need some documenting first. I ask a few questions here that might provide you with some additional work! Sorry ;) But I find this an interesting proposal. Cheers Phil ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Target Layer Python Interface 2016-01-31 15:21 ` Phil Muldoon @ 2016-02-01 18:19 ` Kieran Bingham 2016-02-04 22:16 ` Ales Novak 0 siblings, 1 reply; 8+ messages in thread From: Kieran Bingham @ 2016-02-01 18:19 UTC (permalink / raw) To: Phil Muldoon, gdb Cc: Yao Qi, Peter Griffin, Jan Kiszka, Lee Jones, Jeff Mahoney, Ales Novak Hi Phil, On 31/01/16 15:21, Phil Muldoon wrote: > On 29/01/16 12:33, Kieran Bingham wrote: >> While investigating how to get Python to define the threads presented by > the application layer (in my instance the linux kernel) I found that I > could create threads with a call from Python, (by writing a hook through > the inferior object) > > A snippet would be cool to see what you are doing here, if possible. My initial test was simply a method to generate PID's and add them to test what would happen. Commit viewable @ : https://git.linaro.org/people/kieran.bingham/binutils-gdb.git/commitdiff/0e2692cdc6d195810ed61ac96ada91a715f94990 In testing this, I quickly discovered that the thread list was updated as soon as I then called "info threads" which cleared down the list. Thus, I then went to look at creating a gdb.Target object to mirror ST's implementations, and provide the ability to call into the kernels python iterators to generate the list instead. So far I have created a gdb.Target python object representation which has a call to register the layer from a python subclass (following the implementation style of gdb.Command, where calling super.__init__ performs the registration) An early version of (work in progress) gdb.Target is available here: https://git.linaro.org/people/kieran.bingham/binutils-gdb.git/commitdiff/77ca621b2d2fcdc9376221833c9dbae557881090 And of course usual caveats of this branch will be rebased very soon :) > >> However, whilst these threads were added, they were immediately removed > by the next call to (target).to_update_thread_list() > > I presume you mean GDB's accounting of them, not the actual threads? Aha, of course :) - Only GDB's 'view' of the threads are removed. Not actual Kernel threads. This brings me on to needing to implement .to_update_thread_list() et al. I believe if we can expose this functionality through to Python, the implementation will live in the kernel - and be common to the targets, and maintain kernel specific versions in the correct place. The kernel. > >> This has led me to believe I should create a Python Target layer > interface, which I have started, and have been able to register a > target, and provide Python bindings so that (currently _to_thread_name) > calls into the python layer object, and returns a new name. > > My intention is that this can be extended to provide the whole set of > target operations allowing me to implement much of the Linux Kernel > Debugger interface in Python. > > At this point, there's just not enough information to form an opinion > of this being a good thing or a bad thing. Do you have an interface in > mind? An API? The API, I would expect to match that of the Target API operations. I would expect a one-to-one mapping of (required) operation names to perform functions. For instance, to support thread listings, I would expect something along the lines of: .to_update_thread_list .to_pid_to_str .to_extra_thread_info .to_thread_alive .to_fetch_registers ... And having seen Jeff's work today, we could utilise Jeff's py-regcache object quite effectively > >>> Through this layer, we can even tackle some of the issues with memory > address spaces, by adding appropriate hooks to adjust MMU context, or > interpret page tables through the relevant target_ops hooks. > > Interesting! > It appears, that the guys at SUSE are already looking at SLAB table walks, and I wonder if we could introduce this into our layers and provide a common architecture for both kdump/core files, and live targets. The STLinuxLKD implementation for interacting with Userspace is to manipulate the MMU, which Jan has noted has issues as it changes the state of the target you are debugging. However if we can identify the data locations to read by walking tables, then this could be a route to providing a much more enriched data retrieval >> Some of the interface can even hopefully be autogenerated by a > make-target-delegate equivalent > > Presume you mean the Python C code/interface? Yes, I suspect some of the functionality to implement will be very repeatable throughout each of the operation call implementations. However, the more I look into it - the more I see each function is likely to need very specific bindings, as it is not simple passing from c function to c function. Perhaps we can factor out commonality as we go - and try to keep as DRY as possible, but I suspect it will be an iterative implementation process. >> Before I head too much further, I wanted to ask the opinions of the > community as to whether this is an acceptable interface to implement, or > if it opens up too much of the GDB internals, to external dependencies. > > This is something that is always a balancing act with Python > GDB. There are, as you allude too, some parts of GDB that are not > suitable to be extended to the Python layer, and some parts that while > theoretically OK, need a little work to make safe and accessible in a > Pythonic way. I was discussing this with Jan this yesterday morning. We don't want a fragile plugin implementation causing undesirable effects in the rest of the GDB program space. The layers would have to be able to gracefully handle failures in the python functions, without catastrophic crashing of gdb. The layer would also need to be able to enable/disable which is perhaps as simple as poping it off the target stack..., or perhaps more likely having an enable flag in the gdb.Target object, which would effectively make the entire layer delegate to beneath. > I can't comment without more details though. My initial reaction > though is yeah, this sounds useful and exciting. Perfect :) > >> We could of course tackle this by providing a versioned API which would > allow adaptation in the Python objects, but I thought it was a big > enough question that it should be posed to a wider audience (wider than > just me!) > > The versioned API would also need some documenting first. Of course. > I ask a few questions here that might provide you with some > additional work! Sorry ;) But I find this an interesting proposal. Ask away! I'm keen to have engagement. I'm considering putting submitting a proposal for a presentation on the topic at ELC to follow on from Peter's presentation in Dublin, and hopefully find out what use cases people would *actually* expect from this. I think we already can see that we will need to make this layer work with a large group of users. I hope that it will be common across remote(jtag/serial) targets, including QEmu/KVM stubs, and with the work from the guys at SUSE we should be able to cater this for kdump cores too. I think the importance is to make sure everything works well together. > > Cheers > > Phil > > Regards Kieran ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Target Layer Python Interface 2016-02-01 18:19 ` Kieran Bingham @ 2016-02-04 22:16 ` Ales Novak 2016-02-05 16:36 ` Kieran Bingham 0 siblings, 1 reply; 8+ messages in thread From: Ales Novak @ 2016-02-04 22:16 UTC (permalink / raw) To: Kieran Bingham Cc: Phil Muldoon, gdb, Yao Qi, Peter Griffin, Jan Kiszka, Lee Jones, Jeff Mahoney, ptesarik Hello, On 2016-2-1 19:19, Kieran Bingham wrote: > [...] > The API, I would expect to match that of the Target API operations. I > would expect a one-to-one mapping of (required) operation names to > perform functions. > > For instance, to support thread listings, I would expect something along > the lines of: > > .to_update_thread_list > .to_pid_to_str > .to_extra_thread_info > .to_thread_alive > .to_fetch_registers > ... FTR I've slightly tweaked your gdb.Target to process "to_xfer_partial", the respective commit is: https://github.com/alesax/gdb-kdump/commit/efba160691273ef3c1547112554584088b5dba75 (and the respective branch is "gdb-target") Then the target code which is accessing virtual (!) memory of the kernel dump on the disk (using libkdumpfile library) is as small as: === from gdb import Target from _kdumpfile import kdumpfile class MyTarget(Target): def __init__(self, fil): self.kdump = kdumpfile(fil) self.kdump.symbol_func = \ lambda nam: long(gdb.lookup_minimal_symbol(nam).value()) self.kdump.vtop_init() super(MyTarget, self).__init__() def to_xfer_partial(self, obj, annex, readbuf, writebuf, offset, ln): if obj == self.TARGET_OBJECT_MEMORY: r = self.kdump.read (self.kdump.KDUMP_KVADDR, offset, ln) readbuf[:] = r return ln MyTarget(file("/tmp/vmcore")) === which is really nice, I'd say. Now it would be interesting > And having seen Jeff's work today, we could utilise Jeff's py-regcache > object quite effectively > > [...] > > Yes, I suspect some of the functionality to implement will be very > repeatable throughout each of the operation call implementations. > > > However, the more I look into it - the more I see each function is > likely to need very specific bindings, as it is not simple passing from > c function to c function. Yes, the mentioned to_xfer_partial being a good example (of not simple passing). > Perhaps we can factor out commonality as we go - and try to keep as DRY > as possible, but I suspect it will be an iterative implementation process. > > >> I can't comment without more details though. My initial reaction >> though is yeah, this sounds useful and exciting. > > Perfect :) Yes, this definitely is worth pursuing. -- Ales Novak SUSE L3 Team ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Target Layer Python Interface 2016-02-04 22:16 ` Ales Novak @ 2016-02-05 16:36 ` Kieran Bingham 2016-02-05 16:38 ` Jeff Mahoney 0 siblings, 1 reply; 8+ messages in thread From: Kieran Bingham @ 2016-02-05 16:36 UTC (permalink / raw) To: Ales Novak, Kieran Bingham Cc: Phil Muldoon, gdb, Yao Qi, Peter Griffin, Jan Kiszka, Lee Jones, Jeff Mahoney, ptesarik On 04/02/16 22:16, Ales Novak wrote: > Hello, > > On 2016-2-1 19:19, Kieran Bingham wrote: >> [...] >> The API, I would expect to match that of the Target API operations. I >> would expect a one-to-one mapping of (required) operation names to >> perform functions. >> >> For instance, to support thread listings, I would expect something along >> the lines of: >> >> .to_update_thread_list >> .to_pid_to_str >> .to_extra_thread_info >> .to_thread_alive >> .to_fetch_registers >> ... > > FTR I've slightly tweaked your gdb.Target to process "to_xfer_partial", > the respective commit is: > > https://github.com/alesax/gdb-kdump/commit/efba160691273ef3c1547112554584088b5dba75 > > > (and the respective branch is "gdb-target") > > Then the target code which is accessing virtual (!) memory of the kernel > dump on the disk (using libkdumpfile library) is as small as: > > === > from gdb import Target > from _kdumpfile import kdumpfile > > class MyTarget(Target): > def __init__(self, fil): > self.kdump = kdumpfile(fil) > self.kdump.symbol_func = \ > lambda nam: long(gdb.lookup_minimal_symbol(nam).value()) > self.kdump.vtop_init() > super(MyTarget, self).__init__() > def to_xfer_partial(self, obj, annex, readbuf, writebuf, offset, ln): > if obj == self.TARGET_OBJECT_MEMORY: > r = self.kdump.read (self.kdump.KDUMP_KVADDR, offset, ln) > readbuf[:] = r > return ln > > MyTarget(file("/tmp/vmcore")) > === > > which is really nice, I'd say. Now it would be interesting Were you going to say something else here? ... looks like it got chopped! Pulling the const's through is pretty neat, and that does make an effective way to implement the read overrides to a file! By the way, I'd started to add thread support - but I'm on holiday now. Adding an add_thread(pid,lwp,tid) method to the inferior allows def to_update_thread_list(self): gdb.write("LX.to_update_thread_list\n") inferior = gdb.selected_inferior() threads = inferior.threads() for task in tasks.task_lists(): # Build ptid_t ... class object better here still ptid = (inferior.pid, 0, task['pid']) # (pid, lwp, tid) if ptid not in threads: gdb.write("- New Task [{} {}]\n" .format(task['pid'], task['comm'].string())) inferior.add_thread(ptid) The 'if ptid not in tasks' is not working yet. That was going to be next on my list. I think the comparison function is in the wrong place, it should be implementing __contains__ instead of compare I think. Then it's just a matter of wiring up Jeff's Regcache ... If you're interested: My latest patches are at: http://git.linaro.org/people/kieran.bingham/binutils-gdb.git lkd-python And the Kernel Awareness object is at http://git.linaro.org/people/kieran.bingham/linux.git lkd-python Feel free to have a go at wiring up while I'm away if it's useful to you. > > >> And having seen Jeff's work today, we could utilise Jeff's py-regcache >> object quite effectively >> >> [...] >> >> Yes, I suspect some of the functionality to implement will be very >> repeatable throughout each of the operation call implementations. >> >> >> However, the more I look into it - the more I see each function is >> likely to need very specific bindings, as it is not simple passing from >> c function to c function. > > Yes, the mentioned to_xfer_partial being a good example (of not simple > passing). Indeed - but probably not too many hooks to implement to get thread integration through python. > >> Perhaps we can factor out commonality as we go - and try to keep as DRY >> as possible, but I suspect it will be an iterative implementation >> process. >> >> >>> I can't comment without more details though. My initial reaction >>> though is yeah, this sounds useful and exciting. >> >> Perfect :) > > Yes, this definitely is worth pursuing. > I'm glad you like the concept. I think it can work well with the recent code Jeff has written. Although I may be slightly diverted for a bit when I get back from holiday - so if it can go somewhere for you guys ... do have a go until I return. (And let me know how it goes!) Regards Kieran ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Target Layer Python Interface 2016-02-05 16:36 ` Kieran Bingham @ 2016-02-05 16:38 ` Jeff Mahoney 2016-02-05 16:47 ` Kieran Bingham 0 siblings, 1 reply; 8+ messages in thread From: Jeff Mahoney @ 2016-02-05 16:38 UTC (permalink / raw) To: Kieran Bingham, Ales Novak, Kieran Bingham Cc: Phil Muldoon, gdb, Yao Qi, Peter Griffin, Jan Kiszka, Lee Jones, ptesarik -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 2/5/16 11:36 AM, Kieran Bingham wrote: > On 04/02/16 22:16, Ales Novak wrote: >> Hello, >> >> On 2016-2-1 19:19, Kieran Bingham wrote: >>> [...] The API, I would expect to match that of the Target API >>> operations. I would expect a one-to-one mapping of (required) >>> operation names to perform functions. >>> >>> For instance, to support thread listings, I would expect >>> something along the lines of: >>> >>> .to_update_thread_list .to_pid_to_str .to_extra_thread_info >>> .to_thread_alive .to_fetch_registers ... >> >> FTR I've slightly tweaked your gdb.Target to process >> "to_xfer_partial", the respective commit is: >> >> https://github.com/alesax/gdb-kdump/commit/efba160691273ef3c154711255 4584088b5dba75 >> >> >> >> (and the respective branch is "gdb-target") >> >> Then the target code which is accessing virtual (!) memory of the >> kernel dump on the disk (using libkdumpfile library) is as small >> as: >> >> === from gdb import Target from _kdumpfile import kdumpfile >> >> class MyTarget(Target): def __init__(self, fil): self.kdump = >> kdumpfile(fil) self.kdump.symbol_func = \ lambda nam: >> long(gdb.lookup_minimal_symbol(nam).value()) >> self.kdump.vtop_init() super(MyTarget, self).__init__() def >> to_xfer_partial(self, obj, annex, readbuf, writebuf, offset, >> ln): if obj == self.TARGET_OBJECT_MEMORY: r = self.kdump.read >> (self.kdump.KDUMP_KVADDR, offset, ln) readbuf[:] = r return ln >> >> MyTarget(file("/tmp/vmcore")) === >> >> which is really nice, I'd say. Now it would be interesting > > Were you going to say something else here? ... looks like it got > chopped! > > > Pulling the const's through is pretty neat, and that does make an > effective way to implement the read overrides to a file! > > > By the way, I'd started to add thread support - but I'm on holiday > now. > > Adding an add_thread(pid,lwp,tid) method to the inferior allows Ok, I have code doing that too. There's a big messy commit at the top of my repo last night that I'm going to refactor but I got most of this working. - -Jeff > def to_update_thread_list(self): > gdb.write("LX.to_update_thread_list\n") inferior = > gdb.selected_inferior() threads = inferior.threads() for task in > tasks.task_lists(): # Build ptid_t ... class object better here > still ptid = (inferior.pid, 0, task['pid']) # (pid, lwp, tid) if > ptid not in threads: gdb.write("- New Task [{} {}]\n" > .format(task['pid'], task['comm'].string())) > inferior.add_thread(ptid) > > > The 'if ptid not in tasks' is not working yet. That was going to be > next on my list. > > I think the comparison function is in the wrong place, it should > be implementing __contains__ instead of compare I think. > > Then it's just a matter of wiring up Jeff's Regcache ... > > If you're interested: My latest patches are at: > > http://git.linaro.org/people/kieran.bingham/binutils-gdb.git > lkd-python > > And the Kernel Awareness object is at > http://git.linaro.org/people/kieran.bingham/linux.git lkd-python > > Feel free to have a go at wiring up while I'm away if it's useful > to you. > > >> >> >>> And having seen Jeff's work today, we could utilise Jeff's >>> py-regcache object quite effectively >>> >>> [...] >>> >>> Yes, I suspect some of the functionality to implement will be >>> very repeatable throughout each of the operation call >>> implementations. >>> >>> >>> However, the more I look into it - the more I see each function >>> is likely to need very specific bindings, as it is not simple >>> passing from c function to c function. >> >> Yes, the mentioned to_xfer_partial being a good example (of not >> simple passing). > > Indeed - but probably not too many hooks to implement to get > thread integration through python. > >> >>> Perhaps we can factor out commonality as we go - and try to >>> keep as DRY as possible, but I suspect it will be an iterative >>> implementation process. >>> >>> >>>> I can't comment without more details though. My initial >>>> reaction though is yeah, this sounds useful and exciting. >>> >>> Perfect :) >> >> Yes, this definitely is worth pursuing. >> > > I'm glad you like the concept. I think it can work well with the > recent code Jeff has written. > > Although I may be slightly diverted for a bit when I get back from > holiday - so if it can go somewhere for you guys ... do have a go > until I return. (And let me know how it goes!) > > Regards > > Kieran > - -- Jeff Mahoney SUSE Labs -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.19 (Darwin) Comment: GPGTools - http://gpgtools.org iQIcBAEBAgAGBQJWtNAKAAoJEB57S2MheeWySjwP/RyE9xWolrCjFXo7f8yVFW8C aF/AP/zYa7A56fc9PtkdpDjqRzCnhoHK/9iBi62yN+F+gBdHOE13EytRLsdlimwi M+QNRqJf658oEho4s11G+WznCw5E8TLSBmx426nnOnfHDJ3umSo++az05WY3GX9e PH+UdUJRfEBLz7i0+Y2ZAv9b5oYUpLGwzXJJVwEHKYE6x30BWUUA/0NDUnaSRJpo +2b2xWLHUWGKis9po0H20zRyO5srAHPlwlNyA+p087GD1oRHttDExrSuYrHeikx1 6wfp7GVjFDl6D/iMa1f9Gf9QzoqI7zkwaGxX5C6ex7AmdNofRSVk/WaaZdzWuEgm 4xV9EDsy5BebU7rzDBE1dByW1Jo/3h8EQARS+RvuYA7xml8quqosKevH+iXDWFyZ aJG4bhhkTpV1+50AHQluJh7N8GxoUTBQTZtlgpbpSw2+0B/NyYlImZiLdQDesmkR TptueFkScOt7l5NZ3EkjglRaNURD1OyG+KP/t3Faf5EiyQrnAk/wkhtKX71R44Mk /F8PnlJRYDbPM9+VE326gH9VmXCLDDxqj2UMcAG0dNEYWlCeaYBZB90gLcQuxAvL ch28FAdI8qAJ85pMfXKEPrG9aEa55swTdLjmeIxcOsQMF8t0jfBigXfQ47TIhb/R Lt58vNw8Yu25Eh+/GujZ =UeOP -----END PGP SIGNATURE----- ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Target Layer Python Interface 2016-02-05 16:38 ` Jeff Mahoney @ 2016-02-05 16:47 ` Kieran Bingham 2016-02-05 17:06 ` Kieran Bingham 0 siblings, 1 reply; 8+ messages in thread From: Kieran Bingham @ 2016-02-05 16:47 UTC (permalink / raw) To: Jeff Mahoney, Kieran Bingham, Ales Novak Cc: Phil Muldoon, gdb, Yao Qi, Peter Griffin, Jan Kiszka, Lee Jones, ptesarik On 05/02/16 16:38, Jeff Mahoney wrote: > On 2/5/16 11:36 AM, Kieran Bingham wrote: >> On 04/02/16 22:16, Ales Novak wrote: >>> Hello, >>> >>> On 2016-2-1 19:19, Kieran Bingham wrote: >>>> [...] The API, I would expect to match that of the Target API >>>> operations. I would expect a one-to-one mapping of (required) >>>> operation names to perform functions. >>>> >>>> For instance, to support thread listings, I would expect >>>> something along the lines of: >>>> >>>> .to_update_thread_list .to_pid_to_str .to_extra_thread_info >>>> .to_thread_alive .to_fetch_registers ... >>> >>> FTR I've slightly tweaked your gdb.Target to process >>> "to_xfer_partial", the respective commit is: >>> >>> https://github.com/alesax/gdb-kdump/commit/efba160691273ef3c154711255 > 4584088b5dba75 >>> >>> >>> >>> > (and the respective branch is "gdb-target") >>> >>> Then the target code which is accessing virtual (!) memory of the >>> kernel dump on the disk (using libkdumpfile library) is as small >>> as: >>> >>> === from gdb import Target from _kdumpfile import kdumpfile >>> >>> class MyTarget(Target): def __init__(self, fil): self.kdump = >>> kdumpfile(fil) self.kdump.symbol_func = \ lambda nam: >>> long(gdb.lookup_minimal_symbol(nam).value()) >>> self.kdump.vtop_init() super(MyTarget, self).__init__() def >>> to_xfer_partial(self, obj, annex, readbuf, writebuf, offset, >>> ln): if obj == self.TARGET_OBJECT_MEMORY: r = self.kdump.read >>> (self.kdump.KDUMP_KVADDR, offset, ln) readbuf[:] = r return ln >>> >>> MyTarget(file("/tmp/vmcore")) === >>> >>> which is really nice, I'd say. Now it would be interesting > >> Were you going to say something else here? ... looks like it got >> chopped! > > >> Pulling the const's through is pretty neat, and that does make an >> effective way to implement the read overrides to a file! > > >> By the way, I'd started to add thread support - but I'm on holiday >> now. > >> Adding an add_thread(pid,lwp,tid) method to the inferior allows > > Ok, I have code doing that too. There's a big messy commit at the top > of my repo last night that I'm going to refactor but I got most of > this working. Fantastic, you've probably spent more time on it than me so I'll bet your version works before I'm back from holiday! I'll go have a quick look now. :D I felt a bit like we need a bit better encapsulation on the ptid_t object. Might need a small object to wrap it up for passing around instead of just throwing Tuples everywhere. -- Kieran > > -Jeff > >> def to_update_thread_list(self): >> gdb.write("LX.to_update_thread_list\n") inferior = >> gdb.selected_inferior() threads = inferior.threads() for task in >> tasks.task_lists(): # Build ptid_t ... class object better here >> still ptid = (inferior.pid, 0, task['pid']) # (pid, lwp, tid) if >> ptid not in threads: gdb.write("- New Task [{} {}]\n" >> .format(task['pid'], task['comm'].string())) >> inferior.add_thread(ptid) > > >> The 'if ptid not in tasks' is not working yet. That was going to be >> next on my list. > >> I think the comparison function is in the wrong place, it should >> be implementing __contains__ instead of compare I think. > >> Then it's just a matter of wiring up Jeff's Regcache ... > >> If you're interested: My latest patches are at: > >> http://git.linaro.org/people/kieran.bingham/binutils-gdb.git >> lkd-python > >> And the Kernel Awareness object is at >> http://git.linaro.org/people/kieran.bingham/linux.git lkd-python > >> Feel free to have a go at wiring up while I'm away if it's useful >> to you. > > >>> >>> >>>> And having seen Jeff's work today, we could utilise Jeff's >>>> py-regcache object quite effectively >>>> >>>> [...] >>>> >>>> Yes, I suspect some of the functionality to implement will be >>>> very repeatable throughout each of the operation call >>>> implementations. >>>> >>>> >>>> However, the more I look into it - the more I see each function >>>> is likely to need very specific bindings, as it is not simple >>>> passing from c function to c function. >>> >>> Yes, the mentioned to_xfer_partial being a good example (of not >>> simple passing). > >> Indeed - but probably not too many hooks to implement to get >> thread integration through python. > >>> >>>> Perhaps we can factor out commonality as we go - and try to >>>> keep as DRY as possible, but I suspect it will be an iterative >>>> implementation process. >>>> >>>> >>>>> I can't comment without more details though. My initial >>>>> reaction though is yeah, this sounds useful and exciting. >>>> >>>> Perfect :) >>> >>> Yes, this definitely is worth pursuing. >>> > >> I'm glad you like the concept. I think it can work well with the >> recent code Jeff has written. > >> Although I may be slightly diverted for a bit when I get back from >> holiday - so if it can go somewhere for you guys ... do have a go >> until I return. (And let me know how it goes!) > >> Regards > >> Kieran > > > > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [RFC] Target Layer Python Interface 2016-02-05 16:47 ` Kieran Bingham @ 2016-02-05 17:06 ` Kieran Bingham 0 siblings, 0 replies; 8+ messages in thread From: Kieran Bingham @ 2016-02-05 17:06 UTC (permalink / raw) To: Jeff Mahoney, Kieran Bingham, Ales Novak Cc: Phil Muldoon, gdb, Yao Qi, Peter Griffin, Jan Kiszka, Lee Jones, ptesarik On 05/02/16 16:47, Kieran Bingham wrote: > > > On 05/02/16 16:38, Jeff Mahoney wrote: >> On 2/5/16 11:36 AM, Kieran Bingham wrote: >>> On 04/02/16 22:16, Ales Novak wrote: >>>> Hello, >>>> >>>> On 2016-2-1 19:19, Kieran Bingham wrote: >>>>> [...] The API, I would expect to match that of the Target API >>>>> operations. I would expect a one-to-one mapping of (required) >>>>> operation names to perform functions. >>>>> >>>>> For instance, to support thread listings, I would expect >>>>> something along the lines of: >>>>> >>>>> .to_update_thread_list .to_pid_to_str .to_extra_thread_info >>>>> .to_thread_alive .to_fetch_registers ... >>>> >>>> FTR I've slightly tweaked your gdb.Target to process >>>> "to_xfer_partial", the respective commit is: >>>> >>>> https://github.com/alesax/gdb-kdump/commit/efba160691273ef3c154711255 >> 4584088b5dba75 >>>> >>>> >>>> >>>> >> (and the respective branch is "gdb-target") >>>> >>>> Then the target code which is accessing virtual (!) memory of the >>>> kernel dump on the disk (using libkdumpfile library) is as small >>>> as: >>>> >>>> === from gdb import Target from _kdumpfile import kdumpfile >>>> >>>> class MyTarget(Target): def __init__(self, fil): self.kdump = >>>> kdumpfile(fil) self.kdump.symbol_func = \ lambda nam: >>>> long(gdb.lookup_minimal_symbol(nam).value()) >>>> self.kdump.vtop_init() super(MyTarget, self).__init__() def >>>> to_xfer_partial(self, obj, annex, readbuf, writebuf, offset, >>>> ln): if obj == self.TARGET_OBJECT_MEMORY: r = self.kdump.read >>>> (self.kdump.KDUMP_KVADDR, offset, ln) readbuf[:] = r return ln >>>> >>>> MyTarget(file("/tmp/vmcore")) === >>>> >>>> which is really nice, I'd say. Now it would be interesting >> >>> Were you going to say something else here? ... looks like it got >>> chopped! >> >> >>> Pulling the const's through is pretty neat, and that does make an >>> effective way to implement the read overrides to a file! >> >> >>> By the way, I'd started to add thread support - but I'm on holiday >>> now. >> >>> Adding an add_thread(pid,lwp,tid) method to the inferior allows >> >> Ok, I have code doing that too. There's a big messy commit at the top >> of my repo last night that I'm going to refactor but I got most of >> this working. > > Fantastic, you've probably spent more time on it than me so I'll bet > your version works before I'm back from holiday! > > I'll go have a quick look now. :D > > I felt a bit like we need a bit better encapsulation on the ptid_t > object. Might need a small object to wrap it up for passing around > instead of just throwing Tuples everywhere. + if (!result) + error("Callback failed.\n"); + + ret = python_string_to_host_string (result); do_cleanups(cleanup); + return ret; } Watch out for the memory leak here ... It's one of the annoyances of this layer. No way to free the pointers when we pass them back up to the caller: In my implementation of pid_to_str, I have a scratch buffer to copy the string into and then free the object. It's probably worth putting one scratch buffer in the layer to share across all functions that need it. We should be can_async_p = 0 anyway I think. https://git.linaro.org/people/kieran.bingham/binutils-gdb.git/commitdiff/ecd824755584f5c3f2083f7d9ee4b5e25eb357f3 Ha - I say that - and then I see I didn't free the char array from python_string_to_host_string (result); in my version! That'll have to be a fixup later :) -- Kieran > > -- > Kieran > >> >> -Jeff >> >>> def to_update_thread_list(self): >>> gdb.write("LX.to_update_thread_list\n") inferior = >>> gdb.selected_inferior() threads = inferior.threads() for task in >>> tasks.task_lists(): # Build ptid_t ... class object better here >>> still ptid = (inferior.pid, 0, task['pid']) # (pid, lwp, tid) if >>> ptid not in threads: gdb.write("- New Task [{} {}]\n" >>> .format(task['pid'], task['comm'].string())) >>> inferior.add_thread(ptid) >> >> >>> The 'if ptid not in tasks' is not working yet. That was going to be >>> next on my list. >> >>> I think the comparison function is in the wrong place, it should >>> be implementing __contains__ instead of compare I think. >> >>> Then it's just a matter of wiring up Jeff's Regcache ... >> >>> If you're interested: My latest patches are at: >> >>> http://git.linaro.org/people/kieran.bingham/binutils-gdb.git >>> lkd-python >> >>> And the Kernel Awareness object is at >>> http://git.linaro.org/people/kieran.bingham/linux.git lkd-python >> >>> Feel free to have a go at wiring up while I'm away if it's useful >>> to you. >> >> >>>> >>>> >>>>> And having seen Jeff's work today, we could utilise Jeff's >>>>> py-regcache object quite effectively >>>>> >>>>> [...] >>>>> >>>>> Yes, I suspect some of the functionality to implement will be >>>>> very repeatable throughout each of the operation call >>>>> implementations. >>>>> >>>>> >>>>> However, the more I look into it - the more I see each function >>>>> is likely to need very specific bindings, as it is not simple >>>>> passing from c function to c function. >>>> >>>> Yes, the mentioned to_xfer_partial being a good example (of not >>>> simple passing). >> >>> Indeed - but probably not too many hooks to implement to get >>> thread integration through python. >> >>>> >>>>> Perhaps we can factor out commonality as we go - and try to >>>>> keep as DRY as possible, but I suspect it will be an iterative >>>>> implementation process. >>>>> >>>>> >>>>>> I can't comment without more details though. My initial >>>>>> reaction though is yeah, this sounds useful and exciting. >>>>> >>>>> Perfect :) >>>> >>>> Yes, this definitely is worth pursuing. >>>> >> >>> I'm glad you like the concept. I think it can work well with the >>> recent code Jeff has written. >> >>> Although I may be slightly diverted for a bit when I get back from >>> holiday - so if it can go somewhere for you guys ... do have a go >>> until I return. (And let me know how it goes!) >> >>> Regards >> >>> Kieran >> >> >> >> ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2016-02-05 17:06 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-01-29 12:33 [RFC] Target Layer Python Interface Kieran Bingham 2016-01-31 15:21 ` Phil Muldoon 2016-02-01 18:19 ` Kieran Bingham 2016-02-04 22:16 ` Ales Novak 2016-02-05 16:36 ` Kieran Bingham 2016-02-05 16:38 ` Jeff Mahoney 2016-02-05 16:47 ` Kieran Bingham 2016-02-05 17:06 ` Kieran Bingham
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox