This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] Python Finish Breakpoints


Hello,


(sorry for the double post)

On Thu, May 12, 2011 at 3:00 PM, Doug Evans <dje@google.com> wrote:
>
> Hi. ?re:
>
> On Mon, May 9, 2011 at 7:10 AM, Kevin Pouget <kevin.pouget@gmail.com> wrote:
> > Hello,
> >
> > I would like to discuss with you guys a new Python interface for
> > breakpoint handling. Based on the `finish' command, I prepared a
> > Python class which allows to catch the return of a given frame.
> > Basically, the motivation behind this class is to allow Python script
> > to wrap inferior function calls:
> >
> > with a code like
> > int do_something(int *a)
> > {
> > ? *a += 5;
> > ? sleep(a);
> > ? return 10;
> > }
> > which may take a few seconds to execute, there was no way to know the
> > updated value of `a' and the return value (`gdb.execute("finish")'
> > could do that, but a Ctrl^C during the `sleep' would have screwed up
> > your results).
>
> Plus
>
> >But globally, my thoughts when I prepared this interface were that it
> >shouldn't be much different from a classic breakpoint. I'm not really
> >familiar with C++ mechanisms, but I can't see (right now, but I'll
> >investigate it) how it differs from setting a BP on the frame above,
> >checking for recursion upon BP hit and checking for the scope every
> >once in a while.
>
> This *may* be a reasonable approach in the end, and I am sensitive to
> the time invested (that's why I'm replying ... I'd hate for too much
> time being spent hacking down a path that ultimately gets abandoned),
> but I wonder if another approach would be better. ?I honestly don't
> know if it is, but it feels like it should at least be discussed.
>
> To me, there's a difference between providing robust handling a
> hand-called function finishing and a general "finish" handler. ?The
> semantics are sufficiently different, e.g. w.r.t.
> longjmp/c++-exception.
>
> So first let me ask a clarifying question: Is the main purpose for the
> patch to provide robust handling of the different ways an inferior
> function call can "exit"?
> And if so, maybe (or maybe not, dunno) it would be better to focus on
> making that work as desired, as opposed to a general purpose
> finish-frame breakpoint handler.
> The latter may be sufficiently useful as well of course. ?At this
> point I'd just like to understand the main use-case.

thanks for your support,
you're right, it appears that I need to explicit what I exactly want
to do, which certainly fits in your second proposition, a 'general
"finish" handler'.

I mainly want to catch normal termination of functions calls, the 'out
of scope' notification being almost just a convenient asynchronous /
'best effort' notification.

To make it clearer, here is an example of the functionality I want to
build up upon FinishBreakpoints:

> #include <stdio.h>
> #include <dlfcn.h>
> int
> main (int argc, char ** argv) {
> -->void * handle = dlopen ("/lib64/libm.so.6", RTLD_LAZY); <--
> ??? if (!handle) {
> ??? ??? perror("dlopen: ");
> ??? ??? return 1;
> ??? }
> -->double (* cosinus) (double) = dlsym (handle, "cos"); <--
> ??? printf ("%f\n", (* cosinus)(2.0));
> ??? return 0;
> }

> (gdb) run
> Starting program: /home/kevin/travail/arm/perso/root/sample/gdb-finish/fork
> --> DlOpen(0x400768 "/lib64/libm.so.6") = 0x601030 <--
> --> DlSym("cos", "/lib64/libm.so.6") = 0x3cbd41d580 <--
> -0.416147
> [Inferior 1 (process 8263) exited normally]


I want to be able to exploit the interactions between the inferior and
a given library (here lib. 'dl'). So in this example, the script (at
the bottom of the mail) followed the `dlopen' to catch it's return
value

> DlOpen(0x400768 "/lib64/libm.so.6") = 0x601030

Then it catched the `dlsym' call and worked out the library name
matching the handler, and printed the function pointer associated with
'cos'.
> DlSym("cos", "/lib64/libm.so.6") = 0x3cbd41d580


Let me know if this vision of the feature still looks interesting to
you, I'll prepare some tests about the cases Phil mentioned


Cordially,

Kevin

--

import re

global dlopen_name
global dlopen_handler

dlopen_name = None
dlopen_handler = None
class DlOpenBreakpoint(gdb.Breakpoint):
??? def __init__(self):
??????? gdb.Breakpoint.__init__(self, spec="dlopen", internal=1)
??????? self.silent = True

??? def stop(self):
??????? DlOpenFinishBreakpoint(gdb.newest_frame(),
gdb.parse_and_eval("(char*) $rdi"))
??????? return False
DlOpenBreakpoint()

class DlOpenFinishBreakpoint(gdb.FinishBreakpoint):
??? def __init__(self, frame, name):
??????? gdb.FinishBreakpoint.__init__(self, frame, internal=1)
??????? self.name = name
??????? self.silent = True

??? def stop(self):
??????? global dlopen_name
??????? global dlopen_handler

??????? dlopen_name = self.name
??????? dlopen_handler = gdb.parse_and_eval("$rax")

??????? print "DlOpen(%s) = 0x%x" % (dlopen_name, dlopen_handler)

??? def out_of_scope(self):
??????? print "dlopen didn't finish ..."

class DlSymBreakpoint(gdb.Breakpoint):
??? def __init__(self):
??????? gdb.Breakpoint.__init__(self, spec="dlsym", internal=1)
??????? self.silent = True

??? def stop(self):
??????? global dlopen_name
??????? global dlopen_handler

??????? fct = gdb.parse_and_eval("(char *) $rsi")
??????? handler = gdb.parse_and_eval("$rdi")

??????? if (dlopen_handler == handler):
??????????? DlSymFinishBreakpoint(gdb.newest_frame(), fct, dlopen_name)
??????? else:
??????????? print "Unknown handler"
??????? return False
DlSymBreakpoint()

class DlSymFinishBreakpoint(gdb.FinishBreakpoint):
??? def __init__(self, frame, fct, lib):
??????? gdb.FinishBreakpoint.__init__(self, frame, internal=1)
??????? self.fct = fct
??????? self.lib = lib
??????? self.silent = True

??? def stop(self):
??????? fct_addr = gdb.parse_and_eval("$rax")

??????? print "DlSym(%s, %s) = 0x%x" % (self.fct, self.lib, fct_addr)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]