Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does GDB evaluate C++ expressions at runtime

When debugging, I recently noticed that GDB has the ability to evaluate "complex" expressions while debugging a program, and I am wondering how it does this. For example, with the following code:

int main() {
    std::vector<int> v = {1, 2, 3};
    int k = 0;
    std::cin >> k;
    v.push_back(k);
    return v.at(0);
}

I am able to compile the program g++ -g myprogram.cpp and debug it in GDB which allows me to type things like print v.at(4); (which prints the correct value after k is dynamically entered) and print v.at(2) == 3 which evaluates to true.

I am wondering how GDB does this. This SO question hints that it is something "compiled in memory" but does not elaborate further, so I am wondering does it use some sort of JIT to make this all work or something else? Are they compiling the code inline as I type it and running it? Do they have a framework to evaluate C++ on the fly in the debugging context? In essence, I want to reproduce this in a debugger I am writing to evaluate expressions at breakpoints which is why I am curious how GDB does it.

like image 297
llk Avatar asked May 31 '17 13:05

llk


People also ask

What does GDB do in C?

Gdb is a debugger for C (and C++). It allows you to do things like run the program up to a certain point then stop and print out the values of certain variables at that point, or step through the program one line at a time and print out the values of each variable after executing each line.

At which point does GDB stop a running program?

gdb will stop your program at whatever line it has just executed. From here you can examine variables and move through your program.

Is GDB only for C?

The GNU Debugger (GDB) is a portable debugger that runs on many Unix-like systems and works for many programming languages, including Ada, C, C++, Objective-C, Free Pascal, Fortran, Go, and partially others.


1 Answers

Short Answer: It does not compile code.

Long Answer:

  1. You call print command and the procedure occurs in printcmd.c
  2. It calls evaluate_expression, defined in eval.c, which evaluates an expression by reading target memory and calculating it inside gdb for standard operators, otherwise use call_function_by_hand.
  3. call_function_by_hand is defined in infcall.c. When called, the procedure halts target execution (sometimes doesn't, so it is possible to crash a multithreaded program with this feature).
  4. Inject code into the program being debug.
  5. Retrieve the result by reading memory and unpause it if necessary.

You may focus on the code of call_function_by_hand for better understanding.

Note: compile is a different thing from print/call.

like image 61
Keyu Gan Avatar answered Sep 20 '22 22:09

Keyu Gan