Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to "jump"/"skip" in GDB debugger?

Tags:

c

debugging

gdb

Is it possible to jump to some location/address in the code/executable while debugging in GDB ?

Let say I have something similar to the following

int main()
{
  caller_f1() {  

   f1();  // breakpoint  
   f2() } // want to skip f2() and jump 

  caller_f2() { // jump to this this location ??       
   f1();  
   f2(); }  
}
like image 306
newprint Avatar asked Nov 07 '10 05:11

newprint


People also ask

Can you skip a line in gdb?

So just type skip in gdb to skip a line.

How do I skip an instruction in gdb?

The command is jump .

What does jump do in gdb?

Description. This command jumps the program counter to the specified location. The debugger resumes program execution at that point unless it encounters a breakpoint there.

Is gdb a good debugger?

GDB stands for GNU Project Debugger and is a powerful debugging tool for C(along with other languages like C++). It helps you to poke around inside your C programs while they are executing and also allows you to see what exactly happens when your program crashes.


2 Answers

To resume execution at a new address, use jump (short form: j):

jump LINENUM
jump *ADDRESS

The GDB manual suggests using tbreak (temporary breakpoint) before jumping.

The linenum can be any linespec expression, like +1 for the next line.

See @gospes's answer on a related question for a handy skip macro that does exactly that.


Using jump is only "safe" in un-optimized code (-O0), and even then only within the current function. It only modifies the program counter; it doesn't change any other registers or memory.

Only gcc -O0 compiles each source statement (or line?) into an independent block of instructions that loads variable values from memory and stores results. This lets you modify variable values with a debugger at any breakpoint, and makes jumping between lines in the machine code work like jumping between lines in the C source.

This is part of why -O0 makes such slow code: not only does the compiler not spend time optimizing, it is required to make slow code that spills/reloads everything after every statement to support asynchronous modification of variables and even program-counter. (Store/reload latency is about 5 cycles on a typical x86, so a 1 cycle add takes 6 cycles in -O0 builds).

gcc's manual suggests using -Og for the usual edit-compile-debug cycle, but even that light level of optimization will break jump and async modification of variables. If you don't want to do that while debugging, it's a good choice, especially for projects where -O0 runs so slowly that it's a problem.


To set program-counter / instruction-pointer to a new address without resuming, you can also use this:

set $pc = 0x4005a5

Copy/paste addresses from the disassembly window (layout asm / layout reg).

This is equivalent to tbreak + jump, but you can't use line numbers, only instruction addresses. (And you don't get a warning + confirmation-request for jumping outside the current function).

Then you can stepi from there. $pc is a generic gdb name for whatever the register is really called in the target architecture. e.g. RIP in x86-64. (See also the bottom of the x86 tag wiki for asm debugging tips for gdb.)

like image 170
Peter Cordes Avatar answered Sep 20 '22 14:09

Peter Cordes


There seems to be a jump command which is exactly what you are looking for:

http://idlebox.net/2010/apidocs/gdb-7.0.zip/gdb_18.html#SEC163

Updated link: http://web.archive.org/web/20140101193811/http://idlebox.net/2010/apidocs/gdb-7.0.zip/gdb_18.html#SEC163

like image 32
hojusaram Avatar answered Sep 19 '22 14:09

hojusaram