3

I'm trying to setup a set of functions to be skipped by gdb from stepping in by commands like:

skip myfunction

. But if I place them in ~/.gdbinit instead of just saying in the terminal gdb prompt, I get the error:

No function found named myfunction.

Ignore function pending future shared library load? (y or [n]) [answered N; input not from terminal]

So I need GDB to get Y answer. I've tried what was suggested for breakpoints as well as set confirm off suggested in a comment to this question. But these don't help with skip command.

How can I set skip in a .gdbinit script, answering Y about future library load?

Community
  • 1
  • 1
Ruslan
  • 18,162
  • 8
  • 67
  • 136

2 Answers2

1

This feature has been proposed here:

https://sourceware.org/ml/gdb-prs/2015-q2/msg00417.html https://sourceware.org/bugzilla/show_bug.cgi?id=18531

So far, there's been no activity on that issue for 6 months though. As of writing this, the feature is not included in GDB 7.10.

thejoshwolfe
  • 5,328
  • 3
  • 29
  • 21
  • From my limited experience, patches even in bug reports for GDB are ignored unless sent to gdb-patches mailing list. So it looks like if the patch works, it'll have to be applied manually by the user... – Ruslan Jan 09 '16 at 08:29
  • Hmm, in fact that's not even a patch there — just a source file without any hints on where it should reside and how to include it in GDB build system. – Ruslan Jan 09 '16 at 08:30
  • is this the mailing list you're talking about? https://sourceware.org/ml/gdb-prs/2015-q2/msg00417.html – thejoshwolfe Jan 09 '16 at 15:18
  • No, I mean _gdb-patches_, as I said above. This: https://sourceware.org/ml/gdb-patches/ . – Ruslan Jan 09 '16 at 15:35
1

you can use Python to wait for the execution to start, which is equivalent to pending on:

import gdb

to_skip = []

def try_pending_skips(evt=None):
    for skip in list(to_skip): # make a copy for safe remove
        try:
            # test if the function (aka symbol is defined)
            symb, _ = gdb.lookup_symbol(skip)
            if not symb:
                continue
        except gdb.error:
            # no frame ?
            continue
        # yes, we can skip it
        gdb.execute("skip {}".format(skip))
        to_skip.remove(skip)

    if not to_skip:
        # no more functions to skip
        try:
            gdb.events.new_objfile.disconnect(try_pending_skips) # event fired when the binary is loaded
        except ValueError:
            pass # was not connected

class cmd_pending_skip(gdb.Command):
    self = None

    def __init__ (self):
        gdb.Command.__init__(self, "pending_skip", gdb.COMMAND_OBSCURE)

    def invoke (self, args, from_tty):
        global to_skip

        if not args:
            if not to_skip:
                print("No pending skip.")
            else:
                print("Pending skips:")
                for skip in to_skip:
                    print("\t{}".format(skip))
            return

        new_skips = args.split()
        to_skip += new_skips

        for skip in new_skips:
            print("Pending skip for function '{}' registered.".format(skip))

        try:
            gdb.events.new_objfile.disconnect(try_pending_skips) 
        except ValueError: pass # was not connected

        # new_objfile event fired when the binary and libraries are loaded in memory
        gdb.events.new_objfile.connect(try_pending_skips)

        # try right away, just in case
        try_pending_skips()

cmd_pending_skip()

Save this code into a Python file pending_skip.py (or surrounded with python ... end in your .gdbinit), then:

source pending_skip.py
pending_skip fct1
pending_skip fct2 fct3
pending_skip # to list pending skips

Documentation references:

Kevin
  • 4,618
  • 3
  • 38
  • 61