public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
* [Bug python/27000] New: gdb.block_for_pc should accept a gdb.Value argument
@ 2020-12-02 21:03 jwakely.gcc at gmail dot com
  2020-12-02 21:18 ` [Bug python/27000] " jwakely.gcc at gmail dot com
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: jwakely.gcc at gmail dot com @ 2020-12-02 21:03 UTC (permalink / raw)
  To: gdb-prs

https://sourceware.org/bugzilla/show_bug.cgi?id=27000

            Bug ID: 27000
           Summary: gdb.block_for_pc should accept a gdb.Value argument
           Product: gdb
           Version: 10.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: python
          Assignee: unassigned at sourceware dot org
          Reporter: jwakely.gcc at gmail dot com
  Target Milestone: ---

I've come up with this wrapper for gdb.block_for_pc:

def block_for_function_pointer(f):
    "Find the gdb.Block corresponding to a function pointer in a gdb.Value"

    # Turn the function pointer into an actual address.
    # This is needed to unpack ppc64 function descriptors.
    f = f.dereference().address

    if sys.version_info[0] == 2:
        # Need to use long for Python 2, because int on 64-bit big-endian
        # values raises gdb.error saying "Cannot convert value to int."
        f = long(f)
    else:
        f = int(f)

    try:
        # The GDB manual says this returns None if it fails, but it can raise
        # RuntimeError saying "Cannot locate object file for block."
        return gdb.block_for_pc(f)
    except:
        return None


This is horrible, and IMHO none of it should be necessary.

For powerpc64 a C pointer to function cannot be converted directly to an
integer (it's a "function descriptor") so I use f.dereference().address to do
that.

Then converting to an int has to be done differently for Python 2 (for RHEL 7)
and Python 3. Using int(f) fails for some values with Python 2, raising an
exception, so you have to use long(f). But long doesn't exist in Python 3.

In Python 2 the built-in int() function is supposed to automatically return a
long if the value doesn't fit in int. It would be useful if that happened when
calling it with a gdb.Value argument. That would allow int(f) to work for Py2
and Py3.

Finally, I need to handle exceptions from gdb.block_for_pc even though the
manual suggests it will return None if it fails.

Life would be much easier if a gdb.Value could be passed directly to 
gdb.block_for_pc. The value's gdb.Type should be checked to ensure it's a
suitable type (maybe just function pointers, but maybe void* should be allowed
too). That could presumably do the adjustment from function descriptor to
function address, if needed by the target ABI.

So to summarise:

- Calling int with gdb.Value should not raise an exception if long(v) would
work instead, just do that.

- gdb.block_for_pc should not raise exceptions for invalid values, or the docs
should be fixed.

- gdb.block_for_pc should just accept a gdb.Value of suitable type, and Do The
Right Thing.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-07-08 20:29 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-02 21:03 [Bug python/27000] New: gdb.block_for_pc should accept a gdb.Value argument jwakely.gcc at gmail dot com
2020-12-02 21:18 ` [Bug python/27000] " jwakely.gcc at gmail dot com
2020-12-02 21:24 ` tromey at sourceware dot org
2022-06-04 16:59 ` tromey at sourceware dot org
2022-06-05 13:42 ` tromey at sourceware dot org
2022-07-08 20:28 ` cvs-commit at gcc dot gnu.org
2022-07-08 20:29 ` tromey at sourceware dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).