1

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
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
patatarte
  • 43
  • 4
  • 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? – scottt Feb 16 '15 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. – patatarte Feb 17 '15 at 09:19
  • possible duplicate of [How to execute finish and then another command from inside commands?](http://stackoverflow.com/questions/10501121/how-to-execute-finish-and-then-another-command-from-inside-commands) – Ciro Santilli OurBigBook.com Jul 18 '15 at 10:52

2 Answers2

0

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

Not with GDB, no.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
0

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

scottt
  • 7,008
  • 27
  • 37
  • 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. – patatarte Feb 18 '15 at 11:35