Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Kevin Pouget <kevin.pouget@gmail.com>
To: gdb@sourceware.org
Subject: Re: [RFC] Python Finish Breakpoints
Date: Fri, 13 May 2011 09:04:00 -0000	[thread overview]
Message-ID: <BANLkTi=UpgogckTD5MZsW+PC5d2F8X-+jA@mail.gmail.com> (raw)
In-Reply-To: <BANLkTikt2hEUcXkGVH44NaUcwiF1SGdMaw@mail.gmail.com>

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)


  parent reply	other threads:[~2011-05-13  9:04 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-09 14:11 Kevin Pouget
2011-05-09 14:31 ` Kevin Pouget
     [not found]   ` <BANLkTikVdqbMqjguTV8ct0TWiBDhHGYtLg@mail.gmail.com>
2011-05-11  7:44     ` Kevin Pouget
2011-05-11 10:31       ` Phil Muldoon
2011-05-11 11:29         ` Kevin Pouget
2011-05-12 10:50         ` Phil Muldoon
2011-05-12 11:29           ` Kevin Pouget
2011-05-12 19:00 ` Doug Evans
2011-05-13  7:51   ` Phil Muldoon
     [not found]   ` <BANLkTikt2hEUcXkGVH44NaUcwiF1SGdMaw@mail.gmail.com>
2011-05-13  9:04     ` Kevin Pouget [this message]
2011-05-16 11:24       ` Kevin Pouget
2011-05-18  8:58         ` Kevin Pouget
2011-05-18 10:16           ` Phil Muldoon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='BANLkTi=UpgogckTD5MZsW+PC5d2F8X-+jA@mail.gmail.com' \
    --to=kevin.pouget@gmail.com \
    --cc=gdb@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox