gdb cheatsheet

#1 tip:
gdb –tui # starts an upper screen showing a moving marker against the current line. If you started gdb without “–tui”, you can still use Ctrl-X Ctrl-A.

#2 tip:
After hitting a breakpoint, you can use q(n) i.e. q(next) and just Enter to repeat previous q(n).

#3 tip:
p or q(print)
I found it easier to use q(break filename:lineno) # Filename doesn’t need full path J

Other essential commands
· info break # or info b to list all breakpoints
· bt # or backtrace
· frame 0
· list
· p for print
· info variables
· info locals
· info args
· n # for step-over
· s # for step-in
· fin # for step-out


cvs rollback #basics

cvs -q update -D “2017-07-29” # will remove any file that’s “not in the universe” at that moment in history

Here’s the more precise form:

cvs -q up -D ‘2017/09/15 19:54:25 GMT’ # GMT make a difference. Default is … surprise.

cvs log # is confusing and shows commits after the snapshot!

cvs stat path/to/file # shows the sticky tag


cvs update/checkout a file or dir

–retrieve an old version without sticky

cvs up -p -r1.17 CTFXdpIntgPlugin.C> CTFXdpIntgPlugin.C.1.17

–cvs update a dir or file:

cvs update –dA package/aida/common/script Bring working dir specified up to date with the repository (merge changes made to the repository into the local files).
cvs update –A package/aida/common/script/MakefileAida.sun4
Bring just the named file up-to-date with the repository

–cvs checkout a dir or file:

cvs checkout edu Checks out everything under edu, placing an edu directory, plus all subordinate subdirectories, in the working dir.
cvs checkout app/alh Checks out everything under app/alh placing an app directory in your working directory, but only the alh subdirectory of app.
cvs co package/aida/common/script/MakefileAida.sun4
Checks out only the single file MakefileAida.sun4, creating package/aida/common/script/MakefileAida.sun4 in the working directory, containing that one file.

q(g++ -g -O) together has a section specifically on debugging. It says

GCC allows you to use -g with -O

I think -g adds additional debug info into the binary to help debuggers; -O turns on complier optimization.

By default, our binaries are compiled with “-g3 -O2”. When I debug these binaries, I can see variables but lines are rearranged in source code, causing minor problems. See my blog posts on gdb.

gdb q(next) over if/else +function calls #optimized

I used an optimized binary. Based on limited testing, un-optimized doesn’t suffer from these complexities.

Conventional wisdom: q(next) differs from q(step) and should not go into a function

Rule (simple case): When you are on a line of if-statement in a source code, q(next) would evaluate this condition. If the condition doesn’t involve any function call, then debugger would evaluate it and move to the “presumed next line”, hopefully another simple statement.

Rule 1: suppose your “presumed next line” involves a function call, debugger would often show the first line in the function as the actual “pending”. This may look like step-into!

Eg: In the example below. Previous pending is showing L432 (See Rule 2b to interpret it). The presumed line is L434, but L434 involves a function call, so debugger actually shows L69 as the “pending” i.e. the first line in the function

Rule 2 (more tricky): suppose presumed line is an if-statement involving a function call. Debugger would show first line in the function as the pending.

Eg: In the example below, Previous pending was showing L424. Presumed line is L432, but we hit Rule 2, so actual pending is L176, i.e. first line in the function.

Rule 2b: when debugger shows such an if-statement as the “pending”, then probably the function call completed and debugger is going to evaluate the if-condition.

424 if (isSendingLevel1){
425 //……
426 //……….
427 //……..
428 //……….
429 } // end of if
430 } // end of an outer block
432 if (record->generateTopOfBook()
433 && depthDb->isTopOfTheBook(depthDataRecord)) {
434 record->addTopOfBookMarker(outMsg);
435 }

#1 challenge if u rely@gdb to figure things out: optimizer

Background: explains why “figure things out quickly” is such a make-or-break factor.

In my recent experience, I feel compiler optimization is the #1 challenge. It can mess up GDB step-through. For a big project using automated build, it is often tricky to disable every optimization flag like “-O2”.

More fundamentally, it’s often impossible to tell if the compiled binary in front of you was compiled as optimized or not. Rarely the binary shows it.

Still, compared to other challenges in figuring things out, this one is tractable.

gdb stop@simple assignments #compiler optimize

Toggle between -O2 and -O0, which is the default non-optimized compilation.

In my definition, A “simple assignment” is one without using functions. It can get value from another variable or a literal. Simple assignments are optimized away under -O2, so gdb cannot stop on these lines. This applies to break point or step-through.

In particular, if you breakpoint on a simple assignment then “info breakpoint” will show a growing hit count on this breakpoint, but under -O2 gdb would never stop there. -O0 works as expected.

As another illustration, if an if-block contains nothing but simple assignment, then gdb has nowhere to stop inside it and will only stop after the if-block. You won’t know whether you entered it. -O0 works as expected.