2

When I set a breakpoint in GDB and attach a command-list to it, if I execute a "next" in this command-list, the following commands are ignored, which is normal (See https://sourceware.org/gdb/current/onlinedocs/gdb/Break-Commands.html#Break-Commands).

However, it could be very useful for me to override this limitation... So, is it possible to execute a "next" in the commands block and also the following commands ?

e.g. :

break 8
  commands
    next
    set i = i+1
    continue
  end
3
  • If you just do "next" unconditionally after the breakpoint hit, you could just as well set the breakpoint on line 9, right? Could you show a use case that better demonstrate your constraints? Commented Feb 16, 2015 at 15:11
  • Yes, i thought about that but in some cases, it does not work. For example : if(i > 0) { i++; } else { i--; } In this case, if I want to break just after the i++ instruction, and I set the breakpoint at this line, the "real" breakpoint will be put at the "i-- line" (which is in the else block). Then, if the condition is satisfied, the "i-- line" will never be reached and so my breakpoint will never be hit. Commented Feb 17, 2015 at 9:19
  • possible duplicate of How to execute finish and then another command from inside commands? Commented Jul 18, 2015 at 10:52

2 Answers 2

1

You can't next or cont from breakpoint command lists, but you can write a "stop event handler" in Python then resume inferior execution from there. See the self-contained example below:

buggy.c

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i;
    i = atoi(getenv("i"));

    if (i > 0) {
        i++;
    } else {
        i--;
    }
    printf("i: %d\n", i);
    return 0;
}

next-after-break-on-conditional.gdb

set confirm 0
set python print-stack full

python import gdb

file buggy

break 8
python
conditional_bpnum = int(gdb.parse_and_eval('$bpnum'))
def stop_handler(event):
    if not isinstance(event, gdb.BreakpointEvent):
        return
    if conditional_bpnum not in set(x.number for x in event.breakpoints):
        return
    gdb.write('i: %d\n' % (gdb.parse_and_eval('i'),))
    gdb.execute('next')
    gdb.write('GDB: incrementing "i" from debugger\n')
    gdb.execute('set variable i = i+1')
    gdb.execute('continue')

gdb.events.stop.connect(stop_handler)
end

run
quit

Sample Session

$ gcc -Os -g3 buggy.c -o buggy
$ i=0 gdb -q -x next-after-break-on-conditional.gdb
Breakpoint 1 at 0x4004e3: file buggy.c, line 8.

Breakpoint 1, main () at buggy.c:9
9           i++;
i: 0
11          i--;
GDB: incrementing "i" from debugger
i: 1
[Inferior 1 (process 7405) exited normally]

Implementation Notes

stop_handler() will be called whenever GDB stops so you MUST test that GDB stopped for the specific breakpoint before issuing commands.

If I compile with -O3, I'd get the dreaded "value has been optimized out" error for i and set variable i = i+1 would fail. So watch out for this as usual. (gcc-4.9.2, gdb-7.8.2 on Fedora 21, x86-64)

References

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot ! It works ! Actually, for my specific problem, I created a new command in python and I execute gdb.execute("next") inside this command, but it's your answer that made me think of that.
0

So, is it possible to execute a "next" in the commands block and also the following commands ?

Not with GDB, no.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.