Debug in Linux
Tool list
performance profiling: perf trace, ftrace, strace, lstrace
Two main classes of debugging tool today:
- checker (static and dynamic) - did my code do bad thing x, y, z? - Examples: Address Sanitizer, Valgrind, Converity 
- Debuggers - what exactly did my code do? - Examples: GDG, LLDB, rr, UndoDB, Live Recorder 
GDB:
-ggdb3 is better than -g
| 1 | 编译debug info | 
GDB TUI(Test User Interface) top tips
| 1 | quick shortcut | 
| 1 | gdb program | 
using python in gdb
gdb invoke python interpret, but library need be installed in target system. gdb need to find it.
| 1 | the gdb python module gives most access to gdb | 
In-built pretty printers for STL
| 1 | this relies on Python pretty printers installed on the target system | 
.gdbinit
Hint: have a project gdbinit with lots of stuff in it, and source that
| 1 | set history save on | 
gdb is built atop ptrace and signals
when a program being traced receives a signal, it is suspends and the tracer gets notified(via waitpid).
So when the inferior receives a signal, it stop and gdb gets control.
Usually gdb return to the prompt, but what it will do depends on the signal and how it is configured.
Two signals are special:
- SIGINT is generated when you hit ^C 
- SIGTRAP is generated when the inferior hits a breakpoint or is single stepped. - Actually, not so special, - these signals are treated no differently to any others. 
| 1 | set pagination on | 
Breakpoints and watchpoints
| 1 | stop when foo is modified | 
thread apply
| 1 | info threads | 
Dynamic Printf
use dprintf to put printf’s  in your code without recompiling, e.g.
| 1 | dprintf mutex_lock, "m is %p m->magic is %u\n", m, m->magic | 
control how the printfs hapen:
| 1 | set dprintf-style gdb|call|agent | 
calling
call foo() will call foo in your inferior
| 1 | call strcpy(buffer, "hello, world!\n") | 
| 1 | but beware, `print` may well do too, e.g. | 
Catchpoints
Catchpoints are like breakpoints but catch certain events, such as c++ exceptions.
| 1 | catch catch # to stop when c++ exceptions are caught | 
Remote Debugging
| 1 | Debug over serial/sockets to a remote server | 
Multiprocess Debugging
| 1 | set follow-fork-mode child|parent | 
Yet More Python
hook certain kinds of events
| 1 | def stop_handler(ev): | 
[reverse execution](Recording Inferior’s Execution and Replaying It)
| 1 | > start | 
GDB inbuilt reversible debugging: Work well, but is very slow
GDB in-build record btrace: Uses Intel branch trace.
 Not really reversible, no data
 Quite slow
rr: Very good at what it does, though somewhat limited features/platform support
Other cool things…
| 1 | 
 | 
Valgrind
memcheck is default and the most used/known.
Also there is: cachegrind, callgrind, helgrind, drd, massif, lackey, none
| 1 | > valgrind ./program | 
Sanitizers
AddressSanitizer, MemorySanitizer, ThreadSanitizer, LeakSanitizer
| 1 | faster and more powerful | 
ftrace
“function tracer” - a fast way to trace various kernel functions.
- Lots of pre-defined events(i.e. trace-points)
- Controlled through /sys/kernel/debug/tracing
- Or, use the trace-cmd utility
strace
Trace all the system calls of a process.
| 1 | strace cmd # Print all system calls issued by cmd | 
ltrace
Trace all the dynamic library calls of a process.
| 1 | ltrace cmd # Print all library calls issued by cmd | 
perf trace
Like strace but better(and worse).
| 1 | perf trace # Trace everything - every syscall by every process | 
 Better than strace: Much faster; more flexible.
 Worse than strace: Needs privileges, doesn’t do as much decoding(e.g. strings look like pointers)
Fortify(加固)
 Compile with -D_FORTIFY_SOURCE=1
 memcpy, strcpy, et al do bounds checking where they can.
 Very low(typically impossible to measure), performance overhead.
nm
| 1 | You can find out all functions defined (but not necessarily called) in an application with the nm command, e.g. |