First version of the slides, with examples.

This commit is contained in:
Sergio Durigan Junior 2019-06-03 10:36:07 -04:00
commit 4b3bbbe2c4
16 changed files with 955 additions and 0 deletions

28
examples/corefile/1.c Normal file
View file

@ -0,0 +1,28 @@
static void foo_segv (void);
static void
bar (void)
{
foo_segv ();
}
static void
foo_segv (void)
{
int *x = 0;
*x = 5;
}
static void
baz (void)
{
bar ();
}
int
main (int argc, char *argv[])
{
baz ();
return 0;
}

10
examples/points/Makefile Normal file
View file

@ -0,0 +1,10 @@
CC = gcc
CFLAGS = -g3 -O0
all: breakwatch catch hello
%.o: %.c
$(CC) -o $@ -c $< $(CFLAGS)
clean:
rm -f breakwatch catch hello

View file

@ -0,0 +1,40 @@
/* points.c -- Break and watch examples. */
#include <stdio.h>
struct sttest
{
int index;
char name[15];
int value;
};
int
test_func (int n)
{
int r;
r = n + 10;
r += 20;
return r;
}
int
main (int argc, char **argv)
{
int a, b, i;
struct sttest example_struct[10];
a = 5;
b = test_func (a) / 10;
for (i = 0; i < 10; i++)
{
example_struct[i].index = i;
sprintf (example_struct[i].name, "element %d", i);
example_struct[i].value = test_func (i);
}
return 0;
}

31
examples/points/catch.c Normal file
View file

@ -0,0 +1,31 @@
/* catch.c -- Example for 'catch fork' and 'catch syscall'. */
#include <stdio.h>
#include <unistd.h>
void
test (void)
{
if (fork () == 0)
printf ("Child\n");
fork ();
}
void
another_test (const char *p)
{
chdir (p);
}
int
main (int argc, char **argv)
{
int a;
test ();
another_test (".");
return 0;
}

28
examples/points/hello.c Normal file
View file

@ -0,0 +1,28 @@
/* hello.c -- Segfault example. */
#include <stdio.h>
#include <string.h>
int
print (char *msg)
{
printf ("%s\n", msg);
return 0;
}
int
hello (char *param)
{
strcpy (param, "Hello World!");
print (param);
}
int
main (int argc, char **argv)
{
char *str = "Hi!";
hello (str);
return 0;
}

View file

@ -0,0 +1,9 @@
#include <string>
int
main ()
{
std::string x = "Hello Upstream";
return 0;
}

View file

@ -0,0 +1,29 @@
import gdb.printing
import re
class StdStringPrinter:
def __init__ (self, val):
self.val = val
def to_string (self):
return self.val['_M_dataplus']['_M_p']
def display_hint (self):
return 'string'
def str_lookup_function(val):
bbb = {}
try:
bbb = val.type.fields ()
except:
pass
found = 0
for x in bbb:
if x.name == '_M_dataplus':
found = 1
if found == 1:
return StdStringPrinter(val)
return None
gdb.printing.register_pretty_printer (gdb, str_lookup_function)

23
examples/reverse/1.c Normal file
View file

@ -0,0 +1,23 @@
#include "2.h"
void
foo (int v)
{
int a = 0;
a = 10 + 20;
a += v;
bar (&a);
bar (0);
a = 0;
}
int
main (int argc, char *argv[])
{
initialize ();
return 0;
}

1
examples/reverse/1.h Normal file
View file

@ -0,0 +1 @@
void foo (int v);

17
examples/reverse/2.c Normal file
View file

@ -0,0 +1,17 @@
#include "1.h"
void
initialize (void)
{
int n = 0;
n = 12314314 % 453;
foo (n);
}
void
bar (int *v)
{
if (v != 0)
*v += 12314314 % 453;
}

3
examples/reverse/2.h Normal file
View file

@ -0,0 +1,3 @@
void initialize (void);
void bar (int *v);

41
examples/stap-probe/1.c Normal file
View file

@ -0,0 +1,41 @@
#include <sys/sdt.h>
struct baz
{
int a;
char b;
union
{
int c;
char d;
} u;
};
static void
foo (int a, const char *b)
{
STAP_PROBE2 (test, probefoo, a, b);
}
static void
bar (const struct baz *a)
{
STAP_PROBE1 (test, probebar, a);
}
int
main (int argc, char *argv[])
{
int i1 = 1;
const char *s = "String test";
struct baz b;
b.a = 49;
b.b = 'y';
b.u.d = 'a';
foo (i1, s);
bar (&b);
return 0;
}

View file

@ -0,0 +1,2 @@
Compiling with -Ox (x > 0) changes the layout of the symbols in the memory.
If you want to access a structure field, refer to it explicitly in the probe argument.

12
examples/stap-probe/baz.c Normal file
View file

@ -0,0 +1,12 @@
struct baz
{
int a;
char b;
union
{
int c;
char d;
} u;
};
struct baz blabla;

270
gdb-intro-kwlug.org Normal file
View file

@ -0,0 +1,270 @@
#+OPTIONS: toc:nil date:nil
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.9)
#+TITLE: GDB Intro
#+AUTHOR: Sergio Durigan Junior @@latex:\\@@ sergiodj@{sergiodj.net,redhat.com,debian.org}
#+LANGUAGE: en
#+LATEX_HEADER: \usepackage{listings}
#+LATEX_HEADER: \lstdefinestyle{customc}{belowcaptionskip=1\baselineskip,breaklines=true,frame=L,xleftmargin=\parindent,language=C,showstringspaces=false,basicstyle=\footnotesize\ttfamily,keywordstyle=\bfseries\color{green!40!black},commentstyle=\itshape\color{purple!40!black},identifierstyle=\color{blue},stringstyle=\color{orange},}
* License
- License: *Creative Commons Attribution 4.0 International License (CC-BY-4.0)*
- https://creativecommons.org/licenses/by/4.0/
* Agenda
- Blabla
* Introduction
- =GDB=: =GNU= project's Debugger @@latex:\pause@@ (it is *not* a
/database/...). Supports several programming languages.
- Started around 1986 by Richard Stallman (after *GNU Emacs*, but
likely before *GCC*).
* Compiling your program for GDB
- Your program needs to contain *debug information* (also called
=DWARF=) for GDB to consume.
#+BEAMER: \pause
- The GCC flag to include debug information is =-g=. We also use
=-g3=, which includes information about macros (=#define=).
#+BEAMER: \pause
- It's common to *disable optimizations* when building the binary, by
using the flag =-O0= (it's /dash-oh-zero/).
#+BEAMER: \pause
- =# gcc -O0 -g program.c -o program=, /or/
- ~# CFLAGS='-O0 -g' ./configure && make~
* Running your program using GDB
- In GDB's parlance, the program being debugged is called the
*inferior*.
#+BEAMER: \pause
- Some ways to start the debugger:
#+BEAMER: \pause
- =# gdb ./program=
#+BEAMER: \pause
- =# gdb --args ./program arg1 arg2=
#+BEAMER: \pause
- =# gdb= @@latex: \\@@
=(gdb) file ./program= @@latex: \\@@
=(gdb) run arg1 arg2=
* {Break,Catch,Watch}points
- A *breakpoint* is related to /source code/ (location, function). A
*watchpoint* is related to /data/ (read/write of a variable). A
*catchpoint* is related to an /event/ (enter/exit a syscall, fork,
receive a signal).
#+BEAMER: \pause
- Breakpoints (/code/)
- =break=
- =tbreak= (temporary)
#+BEAMER: \pause
- Watchpoints (/data/)
- =watch= (write), =rwatch= (read), =awatch= (access)
- Conditional watchpoints are supported.
#+BEAMER: \pause
- Catchpoints (/events/)
- =catch fork=
- =catch syscall=
* Resuming the execution
- After GDB has stopped the inferior (because a =*point= has been hit,
for example), you will probably want to resume its execution.
#+BEAMER: \pause
- You may just want to continue the program:
- =continue=
#+BEAMER: \pause
- Or maybe go to the next statement/instruction:
- =next= (/statement/), or =nexti= (/instruction/)
#+BEAMER: \pause
- Or step into a function:
- =step= (/statement/), or =stepi= (/instruction/)
#+BEAMER: \pause
- Or finish executing the current function, but stop at the end:
- =finish=
* Examining data
- The inferior has stopped... Now what?
#+BEAMER: \pause
- You may want to print the value of some variable:
- =print VAR=
#+BEAMER: \pause
- Or examine a memory location:
- =x ADDRESS=
#+BEAMER: \pause
- The type of a variable? Easy:
- =whatis VARIABLE=
#+BEAMER: \pause
- Hint: you may want to enable pretty-printing:
- =set print pretty on=
* Examining the code
- Yes, we have =ncurses=! The @@latex:\textbf{T}@@ext
@@latex:\textbf{U}@@user @@latex:\textbf{I}@@nterface!
- =C-x a= (that's =CTRL x a=).
#+BEAMER: \pause
- If you want to list the current region, or if you don't want/can't
to use TUI:
- =list=
#+BEAMER: \pause
- You can also disassemble code:
- =disassemble=
#+BEAMER: \pause
- If GDB can't find the source code, you can specify its location
using the =dir= command.
* Examining the call stack
- If you want to see the call stack (A.K.A. stack trace) that lead to
the current function:
- =bt=
#+BEAMER: \pause
- And you can move through it:
- =up= and =down=
- You can also go to a specific frame: =frame NUMBER=
* Corefiles
- *Corefiles* are frozen images of the inferior. You can inspect
everything that was happening when the process was running (but you
can't resurrect it).
#+BEAMER: \pause
- You can generate them /outside/ GDB, when a program crashes. Make
sure you:
- =ulimit -c unlimited=
- Check if =systemd= is handling them
(=/proc/sys/kernel/core_pattern=).
#+BEAMER: \pause
- You can also generate them /inside/ GDB, at any moment:
- =generate-core-file=
#+BEAMER: \pause
- You can open a corefile using GDB:
- =# gdb program -c corefile.PID=
* Other interesting information
- =info breakpoints=
- =info locals=
- =info registers=
- Many others!
* Who you gonna call?
- Our online documentation (=info=) is very good!
- Every command has a =help=.
- You can also use =apropos= when searching for a term.
- =TAB=-completion is also useful.
* Other advanced features
- Python support.
- Reverse debugging.
- Support for /SystemTap SDT probes/.
* End
#+ATTR_LATEX: :options style=customc
#+begin_src c -n
int main ()
{
const char *c = NULL;
return 0;
}
#+end_src

411
gdb-intro-kwlug.tex Normal file
View file

@ -0,0 +1,411 @@
% Created 2019-06-02 Sun 21:20
% Intended LaTeX compiler: pdflatex
\documentclass[presentation]{beamer}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{grffile}
\usepackage{longtable}
\usepackage{wrapfig}
\usepackage{rotating}
\usepackage[normalem]{ulem}
\usepackage{amsmath}
\usepackage{textcomp}
\usepackage{amssymb}
\usepackage{capt-of}
\usepackage{hyperref}
\usepackage{color}
\usepackage{listings}
\usepackage{listings}
\lstdefinestyle{customc}{belowcaptionskip=1\baselineskip,breaklines=true,frame=L,xleftmargin=\parindent,language=C,showstringspaces=false,basicstyle=\footnotesize\ttfamily,keywordstyle=\bfseries\color{green!40!black},commentstyle=\itshape\color{purple!40!black},identifierstyle=\color{blue},stringstyle=\color{orange},}
\usetheme{default}
\author{Sergio Durigan Junior \\ sergiodj@\{sergiodj.net,redhat.com,debian.org\}}
\date{}
\title{GDB Intro}
\hypersetup{
pdfauthor={Sergio Durigan Junior \\ sergiodj@\{sergiodj.net,redhat.com,debian.org\}},
pdftitle={GDB Intro},
pdfkeywords={},
pdfsubject={},
pdfcreator={Emacs 26.1 (Org mode 9.1.9)},
pdflang={English}}
\begin{document}
\maketitle
\begin{frame}[label={sec:orga1f4768}]{License}
\begin{itemize}
\item License: \alert{Creative Commons Attribution 4.0 International License (CC-BY-4.0)}
\item \url{https://creativecommons.org/licenses/by/4.0/}
\end{itemize}
\end{frame}
\begin{frame}[label={sec:org13db7cc}]{Agenda}
\begin{itemize}
\item Blabla
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:orgcb90a6c}]{Introduction}
\begin{itemize}
\item \texttt{GDB}: \texttt{GNU} project's Debugger \pause (it is \alert{not} a
\emph{database}\ldots{}). Supports several programming languages.
\item Started around 1986 by Richard Stallman (after \alert{GNU Emacs}, but
likely before \alert{GCC}).
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:orgb03390f}]{Compiling your program for GDB}
\begin{itemize}
\item Your program needs to contain \alert{debug information} (also called
\texttt{DWARF}) for GDB to consume.
\end{itemize}
\pause
\begin{itemize}
\item The GCC flag to include debug information is \texttt{-g}. We also use
\texttt{-g3}, which includes information about macros (\texttt{\#define}).
\end{itemize}
\pause
\begin{itemize}
\item It's common to \alert{disable optimizations} when building the binary, by
using the flag \texttt{-O0} (it's \emph{dash-oh-zero}).
\pause
\begin{itemize}
\item \texttt{\# gcc -O0 -g program.c -o program}, \emph{or}
\item \texttt{\# CFLAGS='-O0 -g' ./configure \&\& make}
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:org71ced54}]{Running your program using GDB}
\begin{itemize}
\item In GDB's parlance, the program being debugged is called the
\alert{inferior}.
\end{itemize}
\pause
\begin{itemize}
\item Some ways to start the debugger:
\pause
\begin{itemize}
\item \texttt{\# gdb ./program}
\end{itemize}
\pause
\begin{itemize}
\item \texttt{\# gdb -{}-args ./program arg1 arg2}
\end{itemize}
\pause
\begin{itemize}
\item \texttt{\# gdb} \\
\texttt{(gdb) file ./program} \\
\texttt{(gdb) run arg1 arg2}
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:org361654c}]{\{Break,Catch,Watch\}points}
\begin{itemize}
\item A \alert{breakpoint} is related to \emph{source code} (location, function). A
\alert{watchpoint} is related to \emph{data} (read/write of a variable). A
\alert{catchpoint} is related to an \emph{event} (enter/exit a syscall, fork,
receive a signal).
\end{itemize}
\pause
\begin{itemize}
\item Breakpoints (\emph{code})
\begin{itemize}
\item \texttt{break}
\item \texttt{tbreak} (temporary)
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item Watchpoints (\emph{data})
\begin{itemize}
\item \texttt{watch} (write), \texttt{rwatch} (read), \texttt{awatch} (access)
\item Conditional watchpoints are supported.
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item Catchpoints (\emph{events})
\begin{itemize}
\item \texttt{catch fork}
\item \texttt{catch syscall}
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:org62a7e28}]{Resuming the execution}
\begin{itemize}
\item After GDB has stopped the inferior (because a \texttt{*point} has been hit,
for example), you will probably want to resume its execution.
\end{itemize}
\pause
\begin{itemize}
\item You may just want to continue the program:
\begin{itemize}
\item \texttt{continue}
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item Or maybe go to the next statement/instruction:
\begin{itemize}
\item \texttt{next} (\emph{statement}), or \texttt{nexti} (\emph{instruction})
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item Or step into a function:
\begin{itemize}
\item \texttt{step} (\emph{statement}), or \texttt{stepi} (\emph{instruction})
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item Or finish executing the current function, but stop at the end:
\begin{itemize}
\item \texttt{finish}
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:org717537c}]{Examining data}
\begin{itemize}
\item The inferior has stopped\ldots{} Now what?
\end{itemize}
\pause
\begin{itemize}
\item You may want to print the value of some variable:
\begin{itemize}
\item \texttt{print VAR}
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item Or examine a memory location:
\begin{itemize}
\item \texttt{x ADDRESS}
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item The type of a variable? Easy:
\begin{itemize}
\item \texttt{whatis VARIABLE}
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item Hint: you may want to enable pretty-printing:
\begin{itemize}
\item \texttt{set print pretty on}
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:org71b8f2a}]{Examining the code}
\begin{itemize}
\item Yes, we have \texttt{ncurses}! The \textbf{T}ext
\textbf{U}user \textbf{I}nterface!
\begin{itemize}
\item \texttt{C-x a} (that's \texttt{CTRL x a}).
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item If you want to list the current region, or if you don't want/can't
to use TUI:
\begin{itemize}
\item \texttt{list}
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item You can also disassemble code:
\begin{itemize}
\item \texttt{disassemble}
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item If GDB can't find the source code, you can specify its location
using the \texttt{dir} command.
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:org1b45b5a}]{Examining the call stack}
\begin{itemize}
\item If you want to see the call stack (A.K.A. stack trace) that lead to
the current function:
\begin{itemize}
\item \texttt{bt}
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item And you can move through it:
\begin{itemize}
\item \texttt{up} and \texttt{down}
\item You can also go to a specific frame: \texttt{frame NUMBER}
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:org22c386a}]{Corefiles}
\begin{itemize}
\item \alert{Corefiles} are frozen images of the inferior. You can inspect
everything that was happening when the process was running (but you
can't resurrect it).
\end{itemize}
\pause
\begin{itemize}
\item You can generate them \emph{outside} GDB, when a program crashes. Make
sure you:
\begin{itemize}
\item \texttt{ulimit -c unlimited}
\item Check if \texttt{systemd} is handling them
(\texttt{/proc/sys/kernel/core\_pattern}).
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item You can also generate them \emph{inside} GDB, at any moment:
\begin{itemize}
\item \texttt{generate-core-file}
\end{itemize}
\end{itemize}
\pause
\begin{itemize}
\item You can open a corefile using GDB:
\begin{itemize}
\item \texttt{\# gdb program -c corefile.PID}
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:org7b2681d}]{Other interesting information}
\begin{itemize}
\item \texttt{info breakpoints}
\item \texttt{info locals}
\item \texttt{info registers}
\item Many others!
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:org73ead26}]{Who you gonna call?}
\begin{itemize}
\item Our online documentation (\texttt{info}) is very good!
\item Every command has a \texttt{help}.
\item You can also use \texttt{apropos} when searching for a term.
\item \texttt{TAB}-completion is also useful.
\end{itemize}
\end{frame}
\begin{frame}[label={sec:orgf6ce0ab}]{Other advanced features}
\begin{itemize}
\item Python support.
\item Reverse debugging.
\item Support for \emph{SystemTap SDT probes}.
\end{itemize}
\end{frame}
\begin{frame}[fragile,label={sec:org0d39b0e}]{End}
\lstset{language=C,label= ,caption= ,captionpos=b,firstnumber=1,numbers=left,style=customc}
\begin{lstlisting}
int main ()
{
const char *c = NULL;
return 0;
}
\end{lstlisting}
\end{frame}
\end{document}