what compiler flag is used to generate a debug build?

Today we're going to talk virtually how we build applications for best use inside GDB.

-chiliad and -O

Let's talk almost what the options -g and -O do. The first matter you need to know is that they are completely orthogonal things.

The first choice,-g, compiles your program with the information to tell GDB what your program is doing. All the debug data goes in its ain section in the executable or the object file and, importantly, it does non affect the lawmaking that is generated at all. On the other hand-O does touch on the generated code, just does not do anything with debug information.

If you are worried that adding -g will slow down your program, then don't worry. This option will make your binary a bit larger on deejay, but that'south information technology. Your program will run equally normal and when you're running the application, the operating organization won't even page in the additional debugging information into retentivity.

Nevertheless, when you compile with optimizations - with -O - information technology can and frequently adversely touch your debug experience.

Optimized out?

Permit'due south await at an case using this tiny trivial program:

#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
  int foo = rand();
  printf("foo is %d\due north", foo++);
  return foo;
}

Compile information technology and run information technology inside GDB:

gcc -O3 -g optimized.c
gdb a.out

Now if you start so impress the value of foo, y'all'll see:

(gdb) impress foo
$1 = <optimized out>

Seen that before? You probably have.

Information technology'due south somewhat annoying - partly because the bulletin is somewhat misleading as it suggests the compiler has been super-clever and the value of foo doesn't exist at all in your programme; peradventure information technology's been optimized away? This isn't really the instance.

What this can hateful is that the variable foo is not yet live at this point, even though notionally it's in scope. In this example, nosotros're at the beginning of the line where this is alleged, simply space hasn't yet been allocated for information technology.

So, if I type adjacent and so look at foo ... voilĂ , at that place is information technology:

(gdb) print foo
$ii = 1804289384

UDB Time Travel Debugger
Find and prepare bugs in minutes  - even C/C++ concurrency issues
Learn more »

Inspecting with readelf

Let'south look at what'south going on here and how the debugger does what it does.

When we compile with -yard, nosotros're really generating dwarf information. (DWARF is a pun on ELF, which stands for Executable and Linking Format. DWARF goes with ELF.)

Bated from the sense of humor, what you need to know is that it's a bunch of information generated by the compile that the debugger uses to understand what your program is doing. At its simplest, this debug data might be telling you what line you lot're on.

We can look at this using the readelf utility.

readelf --debug-dump a.out | less

readelf1

This shows a dump version of the DWARF info which the compiler stored in a.out along with your program.

In this dump, I can search for my variable foo and see that the DWARF information is basically a tree. From this screenshot, you tin can see that foo is alleged in file number i (the DW_AT_decl_file line underneath the DW_AT_name : foo line):

readelf2

Post-obit on from that, at that place is information about its line, column, type and location. The location tells us where the variable is alive.

You tin use the readelf utility to show the locations as so:

readelf --debug-dump=loc a.out | less

What this shows me is a list of places where this variable is alive; and from that I meet that the programme counter commencement (highlighted below) is alive in the register rax. It doesn't exist in memory, at that place's no accost to look at, just we can meet it's in the register.

readelf3.2

And what follows is seeing the variable menstruation through the program.

If you return to GDB, become adjacent and and so print the plan counter with print $pc, y'all volition see the 074 in the location. (Watch the video to a higher place to see this in action.)

In short, <optimized out> doesn't mean the variable isn't there. Sometimes you lot can step next a few times. If you accept reversible capabilities, you can back up to where information technology's live.

-grand is not the merely option

It's worth knowing that -g is not the only option that you tin pass to gcc or clang about how it'due south going to optimize data.

For example, while the default is -g2, if I laissez passer -g3 which is the highest that will generate more than debug information. This volition make the binary larger, only it won't of course touch the program itself.

This turns on basically everything and is likely to requite y'all a better debugging experience.

Different versions of DWARF

They are different versions of the DWARF format. The default for mod versions of gcc (with -g2) is to generate DWARF 4.

Nonetheless, if you have to build on older systems to guarantee that the resulting application will run on older systems, then the compile will probable do a less good job at generating DWARF. This is considering there'southward a whole bunch of stuff information technology just can't capture and y'all'll see more than "optimized out" annoyances when yous're debugging.

But if you do have a modern compiler, -g3 will generate more than DWARF 4 including things like macros.

For case, if you compile the following with gcc -1000:

#define VAL 42

int
main(void)
{
  return VAL;
}

...then run gdb a.out, open in GDB, runstart so exercise:

(gdb) print VAL

You lot'll see that you lot're told VAL doesn't exist. This is becauseVAL is a macro, then the compiler has never fifty-fifty seen information technology.

Nonetheless, if you compile with -g3 and load into GDB, the same print line will show:

$1 = 42

Horrah! You lot tin can debug your macros.

Option -Og

As a concluding point, here'southward how to call back about balancing optimization with debugging experience.

You can specify -Og will give you a good debug experience and remaining pretty fast.

Combined, the -g3 -Og options give y'all prissy balance of performance merely is still nicely debuggable.

(The only reason not to apply -g3 is if yous're really sensitive to the size of your binaries on disk or compile time of your code.)


And there you get! Hopefully that's given you some proficient tips and a deeper understanding of how you build your program for debugging with GDB.

Endeavor Fourth dimension Travel Debugging for free
Notice and test failures in minutes with UDB - pace backwards in time to view registers and retention
Learn more »

Don't miss my side by side GDB tutorial: sign up to my gdbWatchPoint mailing listing below.

romanfaber1960.blogspot.com

Source: https://undo.io/resources/gdb-watchpoint/build-for-debug-in-gdb/

0 Response to "what compiler flag is used to generate a debug build?"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel